MercuryCommands.h

Go to the documentation of this file.
00001 #ifndef _MERCURY_COMMANDS
00002 #define _MERCURY_COMMANDS
00003 
00004 #include <map>
00005 #include "PStack.h"
00006 #include "MercuryUtil.h"
00007 
00008 class MercuryObject;
00009 
00010 typedef MercuryObject * (*MakeObjectCommand)( const MString & );
00011 
00012 typedef bool (*CMDCallback)( PStack &, const char *, PStack &, void * );
00013 
00015 class MercuryCommandRegisteringSystem
00016 {
00017 public:
00018     void CheckInit();
00019     int Register( const MString & command, CMDCallback reg );
00020     bool ExecuteCommand( PStack & ret, const MString & command, PStack & args, void * source = NULL );
00021     bool ExecuteObjectCommand( PStack & ret, const MString & object, const MString & command, PStack & args );
00022     bool ExecuteCommandString( const MString & sCommand );
00023 private:
00024     std::map< MString, CMDCallback > * mCommands;
00025     bool bInit;
00026 };
00027 
00028 extern MercuryCommandRegisteringSystem CMDMAN;
00029 
00031 class MercuryCommandHandler
00032 {
00033 public:
00034     virtual ~MercuryCommandHandler() {};
00035 
00037     virtual bool Command( PStack & ret, const char * command, PStack & args );
00038     virtual void EnumerateCommands( MVector< MString > & toAdd );
00039 
00040     virtual MString GetType() { return "MercuryCommandHandler"; }
00041     virtual void GetAllTypes( MVector<MString> & vOut ) { vOut.push_back( "MercuryCommandHandler" ); }
00042     virtual bool IsTypeOf( const MString & sType ) { return sType == "MercuryCommandHandler"; }
00043 };
00044 
00045 
00046 #if defined( MAKE_DLL )
00047 typedef PSElement (ClassCallback)( MercuryCommandHandler * pThs, const PStack & pParameters );
00048 #else
00049 typedef PSElement (ClassCallback)( MercuryCommandHandler * pThs, const PStack & pParameters );
00050 #endif
00051 
00052 
00053 
00054 #define REGISTER_STATEMENT_TO_COMMAND( command, code ) \
00055     bool regcmdstr_##command( PStack & ret, const char * command, PStack & args, void * data ) \
00056     { \
00057         code \
00058         return true; \
00059     } \
00060     int sub##commandID = CMDMAN.Register( #command, regcmdstr_##command );
00061 
00062 #define REGISTER_FUNCTION_TO_COMMAND( command, function ) \
00063     int sub##commandIDs = CMDMAN.Register( #command, &function ); 
00064 
00065 
00066 
00067 
00068 
00069 //For general DLL usage, primarily in programs that cannot use C++'s exported classes.
00070 bool HGEXPORT RunCommandOnObject( const char * sObjectName, const char * sCommandName, int iMPStackArgs, int iMPStackRet );
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 //Below are the macros for registering an object command.  There's a lot and they're pretty big :(
00081 
00082 //when your typecast needs to be to MString, GCC acts funny, use this to typecast.
00083 #if defined( WIN32 ) && !defined( __GNUC__ )
00084 #define TYPECASTMSTRING (MString)
00085 #else
00086 #define TYPECASTMSTRING
00087 #endif
00088 
00089 
00090 #define CLASS_FUNCTION_NOARGS( CLASSNAME, FUNCTIONNAME, RETURNTYPE ) \
00091     PSElement PS_##CLASSNAME##_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters )   \
00092     {   \
00093         return PSElement(((CLASSNAME*)pThs)->FUNCTIONNAME() ); \
00094     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME##_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &PS_##CLASSNAME##_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00095     EXPORTPREFIX RETURNTYPE HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs ) \
00096     { \
00097         return ((CLASSNAME*)pThs)->FUNCTIONNAME(); \
00098     } EXPORTSUFFIX
00099 
00100 #define CLASS_FUNCTION_VOID_NOARGS( CLASSNAME, FUNCTIONNAME ) \
00101     PSElement PS_##CLASSNAME##_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters )   \
00102     {   \
00103         ((CLASSNAME*)pThs)->FUNCTIONNAME(); \
00104         return PSElement(); \
00105     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME##_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &PS_##CLASSNAME##_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00106     EXPORTPREFIX void HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs ) \
00107     { \
00108         ((CLASSNAME*)pThs)->FUNCTIONNAME(); \
00109     } EXPORTSUFFIX
00110 
00111 #define CLASS_FUNCTION_ONEARG( CLASSNAME, FUNCTIONNAME, RETURNTYPE, CONVTYPE, ARGTYPE ) \
00112     PSElement PS_##CLASSNAME_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters ) \
00113     {   \
00114         return PSElement(((CLASSNAME*)pThs)->FUNCTIONNAME(  CONVTYPE pParameters.PeekItem(0) ) ); \
00115     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &CLASSNAME_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00116     EXPORTPREFIX RETURNTYPE HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs, ARGTYPE p1 ) \
00117     { \
00118         return ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE p1 ); \
00119     } EXPORTSUFFIX
00120 
00121 #define CLASS_FUNCTION_VOID_ONEARG( CLASSNAME, FUNCTIONNAME, CONVTYPE, ARGTYPE ) \
00122     PSElement PS_##CLASSNAME_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters ) \
00123     {   \
00124         ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE pParameters.PeekItem(0) ); \
00125         return PSElement(); \
00126     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &PS_##CLASSNAME_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00127     EXPORTPREFIX void HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs, ARGTYPE p1 ) \
00128     { \
00129         ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE p1 ); \
00130     } EXPORTSUFFIX
00131 
00132 #define CLASS_FUNCTION_TWOARGS( CLASSNAME, FUNCTIONNAME, RETURNTYPE, CONVTYPE1, ARGTYPE1, CONVTYPE2, ARGTYPE2 ) \
00133     PSElement PS_##CLASSNAME##_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters )   \
00134     {   \
00135         return PSElement(((CLASSNAME*)pThs)->FUNCTIONNAME(  CONVTYPE1 pParameters.PeekItem(0), CONVTYPE2 pParameters.PeekItem(1) ) ); \
00136     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &PS_##CLASSNAME##_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00137     EXPORTPREFIX RETURNTYPE HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs, ARGTYPE1 p1, ARGTYPE2 p2 ) \
00138     { \
00139         return ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 p1, CONVTYPE2 p2 ); \
00140     } EXPORTSUFFIX
00141 
00142 #define CLASS_FUNCTION_VOID_TWOARGS( CLASSNAME, FUNCTIONNAME, CONVTYPE1, ARGTYPE1, CONVTYPE2, ARGTYPE2 ) \
00143     PSElement PS_##CLASSNAME_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters ) \
00144     {   \
00145         ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 pParameters.PeekItem(0), CONVTYPE2 pParameters.PeekItem(1) ); \
00146         return PSElement(); \
00147     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &PS_##CLASSNAME_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00148     EXPORTPREFIX void HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs, ARGTYPE1 p1, ARGTYPE2 p2 ) \
00149     { \
00150         ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 p1, CONVTYPE2 p2 ); \
00151     } EXPORTSUFFIX
00152 
00153 #define CLASS_FUNCTION_THREEARGS( CLASSNAME, FUNCTIONNAME, RETURNTYPE, CONVTYPE1, ARGTYPE1, CONVTYPE2, ARGTYPE2, CONVTYPE3, ARGTYPE3 ) \
00154     PSElement PS_##CLASSNAME##_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters )   \
00155     {   \
00156         return PSElement(((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 pParameters.PeekItem(0), CONVTYPE2 pParameters.PeekItem(1), CONVTYPE3 pParameters.PeekItem(2) ) ); \
00157     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME##_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &PS_##CLASSNAME##_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00158     EXPORTPREFIX RETURNTYPE HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs, ARGTYPE1 p1, ARGTYPE2 p2, ARGTYPE3 p3 ) \
00159     { \
00160         return ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 p1, CONVTYPE2 p2, CONVTYPE3 p3 ); \
00161     } EXPORTSUFFIX
00162 
00163 #define CLASS_FUNCTION_VOID_THREEARGS( CLASSNAME, FUNCTIONNAME, CONVTYPE1, ARGTYPE1, CONVTYPE2, ARGTYPE2, CONVTYPE3, ARGTYPE3 ) \
00164     PSElement PS_##CLASSNAME##_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters )   \
00165     {   \
00166         ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 pParameters.PeekItem(0), CONVTYPE2 pParameters.PeekItem(1), CONVTYPE3 pParameters.PeekItem(2) ); \
00167         return PSElement(); \
00168     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &PS_##CLASSNAME##_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00169     EXPORTPREFIX void HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs, ARGTYPE1 p1, ARGTYPE2 p2, ARGTYPE3 p3 ) \
00170     { \
00171         ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 p1, CONVTYPE2 p2, CONVTYPE3 p3 ); \
00172     } EXPORTSUFFIX
00173 
00174 #define CLASS_FUNCTION_FOURARGS( CLASSNAME, FUNCTIONNAME, RETURNTYPE, CONVTYPE1, ARGTYPE1, CONVTYPE2, ARGTYPE2, CONVTYPE3, ARGTYPE3, CONVTYPE4, ARGTYPE4 ) \
00175     PSElement PS_##CLASSNAME_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters ) \
00176     {   \
00177         return PSElement(((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 pParameters.PeekItem(0), CONVTYPE2 pParameters.PeekItem(1), CONVTYPE3 pParameters.PeekItem(2), CONVTYPE4 pParameters.PeekItem(3) ) ); \
00178     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &CLASSNAME_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00179     EXPORTPREFIX RETURNTYPE HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs, ARGTYPE p1, ARGTYPE2 p2, ARGTYPE3 p3, ARGTYPE p4 ) \
00180     { \
00181         return ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 p1, CONVTYPE2 p2, CONVTYPE3 p3, CONVTYPE4 p4 ); \
00182     } EXPORTSUFFIX
00183 
00184 #define CLASS_FUNCTION_VOID_FOURARGS( CLASSNAME, FUNCTIONNAME, CONVTYPE1, ARGTYPE1, CONVTYPE2, ARGTYPE2, CONVTYPE3, ARGTYPE3, CONVTYPE4, ARGTYPE4 ) \
00185     PSElement PS_##CLASSNAME_##FUNCTIONNAME( MercuryCommandHandler * pThs, const PStack & pParameters ) \
00186     {   \
00187         ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 pParameters.PeekItem(0), CONVTYPE2 pParameters.PeekItem(1), CONVTYPE3 pParameters.PeekItem(2), CONVTYPE4 pParameters.PeekItem(3) ); \
00188         return PSElement(); \
00189     } RUN_STATEMENT_AT_BOOT( REGISTER_##CLASSNAME_##FUNCTIONNAME, MercuryObjectFactory::GetInstance().RegisterFunction( &PS_##CLASSNAME_##FUNCTIONNAME, #CLASSNAME, #FUNCTIONNAME ); ) \
00190     EXPORTPREFIX void HGEXPORT CLASSNAME##_##FUNCTIONNAME( void * pThs, ARGTYPE1 p1, ARGTYPE2 p2, ARGTYPE3 p3, ARGTYPE4 p4 ) \
00191     { \
00192         ((CLASSNAME*)pThs)->FUNCTIONNAME( CONVTYPE1 p1, CONVTYPE2 p2, CONVTYPE3 p3, CONVTYPE4 p4 ); \
00193     } EXPORTSUFFIX
00194 
00195 #endif
00196 /* 
00197  * Copyright (c) 2006 Charles Lohr
00198  * All rights reserved.
00199  *
00200  * Redistribution and use in source and binary forms, with or
00201  * without modification, are permitted provided that the following
00202  * conditions are met:
00203  *  -   Redistributions of source code must retain the above
00204  *      copyright notice, this list of conditions and the following disclaimer.
00205  *  -   Redistributions in binary form must reproduce the above copyright
00206  *      notice, this list of conditions and the following disclaimer in
00207  *      the documentation and/or other materials provided with the distribution.
00208  *  -   Neither the name of the Mercury Engine nor the names of its
00209  *      contributors may be used to endorse or promote products derived from
00210  *      this software without specific prior written permission.
00211  *
00212  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00213  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00214  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00215  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00216  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00217  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00218  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00219  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00220  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00221  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00222  */

Hosted by SourceForge.net Logo