...
typedef void (*ConCommandFn)(vector<string>);
class Console
{
public:
Console();
~Console() {};
void msg2(string sMsg);
void msg(string sMsg);
void debug(int nLevel, string sMsg);
void warning(string sMsg);
ConVar *getVariable(string sName);
bool variableExists(string sName);
ConVar *createVariable(string sName, string sDefaultValue, bool bMin=false, float flMin=0.0, bool bMax=false, float flMax=0.0);
void createCommand(string sCommand, ConCommandFn fnCallback);
bool commandExists(string sName);
void addCommand(string sCommand);
void insertCommand(string sCommand);
void forceCommand(string sCommand);
void processQueue();
private:
map<string,ConVar> m_variables;
map<string,ConCommandFn> m_commands;
vector<string> m_cmdQueue;
};
...
...
//-----------------------------------------------------------------------------
// Name: createCommand()
// Desc: Adds a command to the command map.
//-----------------------------------------------------------------------------
void Console::createCommand(string sCommand, ConCommandFn fnCallback)
{
if(commandExists(sCommand))
{
debug(1, "Cannot createCommand(): command already exists.\n");
return;
}
m_commands[sCommand] = fnCallback;
}
//-----------------------------------------------------------------------------
// Name: commandExists()
// Desc: Returns true or false depending on whether the command is in the
// command map.
//-----------------------------------------------------------------------------
bool Console::commandExists(string sName)
{
// Is the variable map empty?
if(m_commands.empty())
return false;
return m_commands.find(sName) != m_commands.end();
}
//-----------------------------------------------------------------------------
// Name: processQueue()
// Desc: Called every frame. Process all commands in the command buffer.
//-----------------------------------------------------------------------------
void Console::processQueue()
{
// Run forceCommand() on all the items in the queue
for (vector<string>::iterator i = m_cmdQueue.begin(); i != m_cmdQueue.end(); ++i)
forceCommand(*i);
// Clear the command queue
m_cmdQueue.clear();
}
//-----------------------------------------------------------------------------
// Name: addCommand()
// Desc: Adds a command to the command queue. Processed the next frame.
//-----------------------------------------------------------------------------
void Console::addCommand(string sCommand)
{
// Ensure that the item won't get discarded by the vector (overflow
// protection)
if (m_cmdQueue.size()+1 >= m_cmdQueue.max_size())
{
debug(1, "Command queue overflow imminent. Processing queue now...\n");
processQueue();
}
// Put to the end of the queue
m_cmdQueue.push_back(sCommand);
}
//-----------------------------------------------------------------------------
// Name: insertCommand()
// Desc: Adds a command to the start of the command queue. Processes first the
// next frame.
//-----------------------------------------------------------------------------
void Console::insertCommand(string sCommand)
{
// Ensure that the item won't get discarded by the vector (overflow
// protection)
if (m_cmdQueue.size()+1 >= m_cmdQueue.max_size())
{
debug(1, "Command queue overflow imminent. Processing queue now...\n");
processQueue();
}
// Insert at the start of the queue
m_cmdQueue.insert(m_cmdQueue.begin(), sCommand);
}
//-----------------------------------------------------------------------------
// Name: forceCommand()
// Desc: Doesn't add the command to the command queue, but process the command
// immediately.
//-----------------------------------------------------------------------------
void Console::forceCommand(string sCommand)
{
vector<string> vTokens;
// Ensure the string is not empty
if (sCommand == "\n")
return;
if (sCommand == "")
return;
// Initialize the seperator and tokenizer
escaped_list_separator<char> sep('\\', ' ', '\"');
tokenizer<escaped_list_separator<char>> tok(sCommand, sep);
// Put all the tokens in a vector
for(tokenizer<escaped_list_separator<char>>::iterator i = tok.begin(); i != tok.end(); ++i)
vTokens.push_back(*i);
// No tokens?
if(vTokens.size() == 0)
return;
// Get the command name
string sName = vTokens[0];
// Is a variable
if (variableExists(sName))
{
if(vTokens.size() != 2)
{
// Print out the value of the variable
msg("Value of ");
msg2(sName);
msg(" is ");
msg2(getVariable(sName)->GetString());
msg("\n");
return;
}
// Set the value of the variable
getVariable(sName)->SetValue(vTokens[1]);
// TODO: Add event code
return;
}
// Is a command
if (commandExists(sCommand))
{
// Call command
m_commands[sCommand](vTokens);
return;
}
// Show "Unknown command".
msg("Unknown command: ");
msg2(sName);
msg("\n");
}
...
Console g_console;
...
void Con_echo_f(vector<string> arg)
{
if (arg.size() <= 1)
{
g_console.msg("Syntax: echo <message>");
return;
}
for (vector<string>::iterator i = arg.begin()+1; i != arg.end(); ++i)
g_console.msg(i->append(" "));
g_console.msg("\n");
}
...
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR lpCmdLine, INT )
{
...
g_console.createCommand("echo", Con_echo_f);
g_console.addCommand("echo hey there!");
...
}