dimanche 1 novembre 2020

Using Command pattern for console input

I'm trying to write a console for a game engine which will allow me to type in commands to perform tasks, such as change the map, spawn an enemy etc.

I've been trying to do this with the Command pattern (following the example from gameprogrammingpatterns.com). See below for the outline of my current code structure.

parseCommand processes the string from the user, extracting the command name and arguments (currently using just whitespace separation). The next step is where I'm stuck. I need to create a Command* somehow to call execute on but I only have the string name of the command.

I could have a giant bunch of if statements in my parseCommand function, such as if (cmdName == "spawn") return new SpawnEnemyCommand(). Alternatively I could store a pointer to each command in myConsole class, e.g. Command *spawnNewEnemy = new SpawnNewEnemy(); and then in parseCommand do if (cmdName == "spawn") spawnNewEnemy->execute();. This second option seems to be how the gameprogrammingpatterns book does it.

Neither of these options seems very practical if I end up with hundreds of console commands. I've studied all the articles and posts I can find on this pattern but it isn't helping clarify the situation for me.

How can I cleanly instantiate the correct Command object from within parseCommand?

Command interface base class:

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

Example interface implementation:

class SpawnEnemyCommand : public Command {
public:
    void execute() {
        // method calls to perform command go here
    }
};

Console class header:

class Console {
public:
    Command* parseCommand(std::string);
    bool validateCommand(std::string, std::vector<std::string>);
};

Aucun commentaire:

Enregistrer un commentaire