Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Design a Parser for multiple command list from Json file

Would love some opinions on this problem I’m trying to workout. I’m trying to improve my OO experience and fully leverage C++’s polymorphic capabilities. I’m trying to write some code for a basic command parser. The commands comes from a Json multiple lines file.

As shown here:

{"command_name":"vkGetDeviceQueue","call_index":8,"threadId":3,"return_value":"void","parameters":{"device":"0x0000000000000005","queueFamilyIndex":0,"queueIndex":0,"pQueue":"0x0000000000000006"}}
{"command_name":"vkCreateFence","call_index":9,"threadId":3,"return_value":"VK_SUCCESS","parameters":{"device":"0x0000000000000005","pCreateInfo":{"sType":"VK_STRUCTURE_TYPE_FENCE_CREATE_INFO","flags":"0x00000001","pNext":null},"pAllocator":null,"pFence":"0x0000000000000010"}}

sample file of the JSON
here command_name can be lots of commands
What I’m doing now

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

     if (commandName == "vkCreateShaderModule")
                {
                    Parser<VulkanShaderModule> shaderModule;
                    shaderModule.dataStruct.captureID = captureID;
                    // shaderModule.pData = &dataZip;
                    shaderModule.Parse(data);
                }
                else if (commandName == "vkCreateGraphicsPipelines")
                {
                    Parser<VulkanGraphicsPipeline> pipelineStruct;
                    pipelineStruct.dataStruct.captureID = captureID;
                    pipelineStruct.Parse(data);
                }
           

As you know the API can have lots of API Calls. I would like to proceed on an OOP way.. probablly a factory pattern would help ? that’s my guess.. but don’t know how to proceed with a good design. I would like to avoid multiple if statements for each command in the full VULKAN API.

>Solution :

Ultimately you can’t really avoid if statements, but you can move this logic to e.g. a parser or a Factory if you prefer. Expanding a bit on john’s comment, you can have a Command class that looks more or less like this:

class Command
{
public:
  virtual ~Command() = default;
  void execute() = 0;
};

and some entity that allows you to create the superclass objects, like:

// or make it a factory class, if you feel it will be better
std::unique_ptr<Command> parseCommand(const SomeJson& j) {  // here come your if/else logic
  if (j["command_name"] == "command1")
  {
    // do some logic to create concrete command and return it; class can be defined in this translation unit, or somewhere else, up to you
    return std::make_unique<CommandOne>(j["command_payload"]);
    // return createCommand1(j["command_payload"]);  // or move it to separate function, it can also be defined in this translation unit, or somewhere else, hidden from the user
  }
  // etc etc ...
}

where concrete CommandXxx classes can be hidden from your public interfaces. Then in your code you can have:

for (auto line : yourInputSplitInLines)
{
  collection.push_back(parseCommand(SomeJson(line)));
}
// and later
for (auto& cmd : collection)
{
  cmd->execute();
}

where collection is a container of your choice. It can also be std::unordered_map<std::string, std::unique_ptr<Command>> if you want to have the possibility to look up commands by name.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading