//////////////////////////////////////////////////////////////////////////// // // Crytek Engine Source File. // Copyright (C), Crytek Studios, 2002. // ------------------------------------------------------------------------- // File name: CommandManager.cpp // Version: v1.00 // Created: 4/7/2002 by Timur. // Compilers: Visual Studio.NET // Description: // ------------------------------------------------------------------------- // History: // //////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "CommandManager.h" ////////////////////////////////////////////////////////////////////////// // Functor command. ////////////////////////////////////////////////////////////////////////// class CFunctorCommand : public CCommand { public: explicit CFunctorCommand( const char *sName,Functor0 func ) : CCommand( sName,0 ) { m_func = func; } virtual void Execute() { if (m_func) m_func(); } private: Functor0 m_func; }; /////////////////////////////////////////////////////////////////////////////// // // CCommandManager. // /////////////////////////////////////////////////////////////////////////////// CCommandManager::CCommandManager() { // Make big enough hash table for faster searches. // m_commands.resize( 1024 ); } CCommandManager::~CCommandManager() { } ////////////////////////////////////////////////////////////////////////// void CCommandManager::RegisterCommand( const CString &sCommand,CommandCallback callback ) { assert( callback != 0 ); if (FindCommand( sCommand ) != 0) { CString err; err.Format( "Error: Command %s already registered",(const char*)sCommand ); CLogFile::WriteLine( err ); AfxMessageBox( err ); } CFunctorCommand *cmd = new CFunctorCommand(sCommand,callback); m_commands.insert( Commands::value_type( sCommand,cmd ) ); } ////////////////////////////////////////////////////////////////////////// void CCommandManager::UnregisterCommand( const CString &sCommand ) { CCommand *pCmd = FindCommand( sCommand ); if (pCmd) UnregisterCommand( pCmd ); } ////////////////////////////////////////////////////////////////////////// void CCommandManager::RegisterCommand( CCommand *cmd ) { assert( cmd != 0 ); if (FindCommand( cmd->GetName() ) != 0) { CString err; err.Format( "Error: Command %s already registered",cmd->GetName() ); CLogFile::WriteLine( err ); AfxMessageBox( err ); } m_commands.insert( Commands::value_type( cmd->GetName(),cmd ) ); } void CCommandManager::UnregisterCommand( CCommand *cmd ) { for (Commands::iterator it = m_commands.begin(); it != m_commands.end(); ++it) { if (it->second == cmd) { m_commands.erase( it ); break; } } //error( "Cannot unregister command %s",cmd->name() ); } CCommand* CCommandManager::FindCommand( const CString &sCommand ) const { Commands::const_iterator it = m_commands.find( sCommand ); if (it != m_commands.end()) { return it->second; } return 0; } void CCommandManager::Execute( const char *command ) { CCommand *cmd = FindCommand( command ); if (cmd) { for (CmdHandlers::iterator it = m_cmdHandlers.begin(); it != m_cmdHandlers.end(); ++it) { // if OnCommand handler return false ignore this commmand. if (!(*it)->OnCommand( cmd )) return; } cmd->Execute(); } else { CString err; err.Format( "Error: Trying to execute unknown Command: %s",command ); CLogFile::WriteLine( err ); } } ////////////////////////////////////////////////////////////////////////// void CCommandManager::ExecuteId( int commandId ) { CCommand *cmd = 0; for (Commands::iterator it = m_commands.begin(); it != m_commands.end(); it++) { CCommand *c = it->second; if (c->GetId() == commandId) { cmd = c; break; } } if (cmd) { for (CmdHandlers::iterator it = m_cmdHandlers.begin(); it != m_cmdHandlers.end(); ++it) { // if OnCommand handler return false ignore this commmand. if (!(*it)->OnCommand( cmd )) return; } cmd->Execute(); } /* else { CString err; err.Format( "Error: Tring to execute unknown Command: %s",command ); CLogFile::WriteLine( err ); } */ } ////////////////////////////////////////////////////////////////////////// void CCommandManager::AddCommandHandler( ICommandHandler *handler ) { m_cmdHandlers.push_back( handler ); } void CCommandManager::RemoveCommandHandler( ICommandHandler *handler ) { CmdHandlers::iterator it = std::find( m_cmdHandlers.begin(),m_cmdHandlers.end(),handler ); if (it != m_cmdHandlers.end()) { m_cmdHandlers.erase( it ); } } ////////////////////////////////////////////////////////////////////////// void CCommandManager::GetSortedCmdList( std::vector &cmds ) { cmds.clear(); cmds.reserve( m_commands.size() ); for (Commands::iterator it = m_commands.begin(); it != m_commands.end(); it++) { if (!cmds.empty()) { // Ignore duplicate strings. if (stricmp(cmds.back(),it->first) == 0) continue; } cmds.push_back( it->first ); } std::sort( cmds.begin(),cmds.end() ); } ////////////////////////////////////////////////////////////////////////// CString CCommandManager::AutoComplete( const char* substr ) { std::vector cmds; GetSortedCmdList( cmds ); int substrLen = strlen(substr); // If substring is empty return first command. if (substrLen==0 && cmds.size()>0) return cmds[0]; for (int i = 0; i < cmds.size(); i++) { int cmdlen = strlen(cmds[i]); if (cmdlen >= substrLen && memicmp(cmds[i],substr,substrLen) == 0) { if (substrLen == cmdlen) { i++; if (i < cmds.size()) return cmds[i]; return cmds[i-1]; } return cmds[i]; } } // Not found. return ""; } ////////////////////////////////////////////////////////////////////////// CString CCommandManager::AutoCompletePrev( const char* substr ) { std::vector cmds; GetSortedCmdList( cmds ); // If substring is empty return last command. if (strlen(substr)==0 && cmds.size()>0) return cmds[cmds.size()-1]; for (int i = 0; i < cmds.size(); i++) { if (stricmp(substr,cmds[i])==0) { if (i > 0) return cmds[i-1]; else return cmds[0]; } } return AutoComplete( substr ); }