Skip to main content
gamedev.net
🔒 Locked

Input/Command Design

Started by unferth Aug 28, 2003 at 4:19 PM 1 replies 800+ views
Original Post
unferth
unferth
Ok, here is the situation. In the core of my engine, I have wrapper for some type of input system. Then, at a higher higher leve (the level I want my logic code to interact with) I have what I am calling a CommandManager (which is a working name, really). The question is: how should the CommandManager find out which keys are bound to which "commands" previously registered by the logic code? Another class, ConfigManager handles loading config files and settings. I am not worried right now about performance drawbacks (although I want the design to be well thought out enough to make modifications later). So far, I have considered three designs, but not too deeply. 1. Create a structure inside CommandManager to map keys->commands. This means the CommandManager is responsible for maintaining the list. 2. Have the responsibility to map keys->commands within ConfigManager. When the CommandManager wants to update the command states, it asks ConfigManager what keys are bound to which commands, and then asks the input wrapper if those keys are down. ConfigManager is responsible for keeping the list of keys. 3. Create another structure, outside both CommandManager and ConfigManager whose responsibility is to keep track of the bindings. Since the responsibility of changing the key bound to a funtion should logically rest with the ConfigManager, how does this information get propogated to the CommandManager? In #2, it would be easy, although the process of updating command states would be lengthy. I suppose in #1 the CommandManager could have a ChangeCommandBinding() function. Actually, I''m not sure exactly how #3 would work, anyway. Ok, the process of writing my thoughts out here helped clarify things a little, and I think #1 is the way I will implement it. I''ll still post this because I would definitely be interested in feedback. I have zero experience in any kind of design at all.
Cornutopia
Cornutopia
In my game I''ve done something more like 2. It seems to make sense to have the config resposible for key mapping in case the user wants to have a selection of key mappings to choose from. Either way should be equally efficient though, it''s a question of choice.

Mark
Zidane
Zidane
Hi

I dont really know if this helps but in my rpg engine i am devolping i have a CommandManager singleton class which is responsible for handling commands and the keys that generate them - Now this is how it works, i have a structure declared as:

struct SCommandKeyBind{
ICommand* pCommand;
int Key;
IGameObject pDest;
}

ICommand is an abstract base class that allows diferent commands to be derived (for example ShootCommand and MoveCommand). pDest is the destination for the command if null all objects in the game will recieve notification of the command

during the initailastion of the engine it calls the command managers RegisterCommand method with a structure of the above
which states which command is bound to which key.

For example if a players Shoot command was bound to space it could be added as so:

SCommandKeyBind new_command;

new_command.pCommand = new CFireCommand(); //derived from ICommand
new_command.Key = KEY_SPACE;
new_command.pDest = CEdenEngine::GetInstance()->GetPlayer();
CCommandManager::GetInstance()->RegisterCommand(&new_command);

Now during the game when the lower level input system fires an event to my main engine class - the engine class first looks at the input values and if it isnt any predefined system ones (for example in my engine X means shutdown) if not it shoves it off to the command manager to foreword to whovever neeeds it, for example he is some hypothetical code:

void CEdenEngine::OnKeyboardInterupt(int InputValue)
{
if(!CheckIfSystemCode(InputValue))
{
CCommandManager::GetInstance()->HandleInput(InputValue);
}
else
{
HandleSystemCode(InputValue);
}
}


now the command managers code may look something like this:



CCommandManager::HandleInput(InputValue)
{

// get the command from the list based on the key pressed
SCommandKeyBind* pCommandBind = FetchCommand(InputValue);

//to avoid coupling the command to the receiver we
//pass the object the command should do something with
//as a param to command this means command can be
// made more flexible

// if there are NULL receivers we broadcast it to everyone
if(pCommandBind->pDest==NULL)
{
BroadCastCommandToAll(pCommandBind->pCommand);
}
else
{
pCommandBind->pCommand->Execute(pCommandBind->pDest);
}


}




So in short the commmand manager, well manages the commands and knows how to pass them on but doesnt have a clue what the command actually does, it only knows the destination (one object or all objects tbh you could improve this to allow object filters etc) and how to execute it.

The main engine traps any commands that are important system commands first and them allows the command manager to handle any.





Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.