00001 #include "MercuryObjectFactory.h" 00002 #include "MercuryLog.h" 00003 #include "MercuryUtil.h" 00004 00005 MercuryObjectFactory& MercuryObjectFactory::GetInstance() 00006 { 00007 static MercuryObjectFactory* instance = NULL; 00008 if (!instance) 00009 instance = new MercuryObjectFactory; 00010 return *instance; 00011 } 00012 00013 PSElement ObjectCallFail( MercuryCommandHandler * pThs, const PStack & pParameters ) 00014 { 00015 return PSElement(); 00016 } 00017 00018 bool MercuryObjectFactory::RegisterObjectClass( const MString & sClassName, MakeObjectCommand pCmd ) 00019 { 00020 m_mClasses[sClassName] = pCmd; 00021 return true; 00022 } 00023 00024 MercuryObject * MercuryObjectFactory::GenerateObject( const MString & sClass, const MString & sName ) 00025 { 00026 if ( !m_mClasses.get( sClass ) ) 00027 return NULL; 00028 return m_mClasses[sClass]( sName ); 00029 } 00030 00031 void MercuryObjectFactory::FinalizeCallbacks() 00032 { 00033 MVector< MString > vClasses; 00034 m_mClasses.VectorIndicies( vClasses ); 00035 for( unsigned i = 0; i < vClasses.size(); i++ ) 00036 { 00037 MString sName = vClasses[i]; 00038 MVector< MString > vTypes; 00039 MercuryCommandHandler * pObject = m_mClasses[sName]( "Dummy" + sName ); 00040 pObject->GetAllTypes( vTypes ); 00041 00042 //vTypes is now a list, with the topmost inherited item on top, and the base on the bottom 00043 //for this reason we go through from the back front, ensuring that overridden items 00044 //take precidence. 00045 00046 for( int i = vTypes.size()-1; i >= 0 ; i-- ) 00047 { 00048 MVector< MString > vCmds; 00049 MString TYPE = vTypes[i]; 00050 MHash< ClassCallback * > * G = m_mPreCallbacks.get(TYPE); 00051 if( !G ) 00052 continue; 00053 G->VectorIndicies( vCmds ); 00054 00055 for( unsigned cmds = 0; cmds < vCmds.size(); cmds++ ) 00056 { 00057 MString CMD = vCmds[cmds]; 00058 void * TMP = G->get(CMD); 00059 if( TMP ) 00060 m_mFinalCallbacks[sName][CMD] = (*G)[CMD]; 00061 } 00062 } 00063 m_vTemplateObjects.push_back( (MercuryObject*)pObject ); 00064 } 00065 } 00066 00067 void MercuryObjectFactory::RegisterFunction( ClassCallback * pCallback, const MString & sClassName, const MString & sCallbackName ) 00068 { 00069 m_mPreCallbacks[sClassName][sCallbackName] = pCallback; 00070 } 00071 00072 ClassCallback * MercuryObjectFactory::GetCallback( const MString & sClassName, const MString & sFunctionName ) 00073 { 00074 if( !m_mFinalCallbacks.get( sClassName ) ) 00075 { 00076 LOG.Warn( "Call attempt: " + sClassName + "::" + sFunctionName + " failed. No such class type." ); 00077 return &ObjectCallFail; 00078 } 00079 00080 if( !m_mFinalCallbacks[sClassName].get( sFunctionName ) ) 00081 { 00082 LOG.Warn( "Call attempt: " + sClassName + "::" + sFunctionName + " failed. No such function name." ); 00083 return &ObjectCallFail; 00084 } 00085 00086 return m_mFinalCallbacks[sClassName][sFunctionName]; 00087 } 00088 00089 void MercuryObjectFactory::GetAllClasses( MVector< MString > & vRet ) 00090 { 00091 m_mClasses.VectorIndicies( vRet ); 00092 } 00093 00094 void MercuryObjectFactory::GetAllFunctions( const MString & sClass, MVector< MString > vRet ) 00095 { 00096 if( m_mFinalCallbacks.get( sClass ) ) 00097 m_mFinalCallbacks[sClass].VectorIndicies( vRet ); 00098 }