123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _RUNTIME_CLASSREP_H_
- #define _RUNTIME_CLASSREP_H_
- #include "console/consoleObject.h"
- #include "console/consoleInternal.h"
- /// This class is to allow new types to be added, at run-time, to Torque.
- /// This is primarily for dynamic libraries, plugins etc.
- ///
- /// The idea is the same, one instance per type which is getting registered
- /// however it doesn't get added to the dictionary until it is told to
- /// add itself. It can be removed, as well, though no safe-execution
- /// assurances are made by this class. If an object type is removed
- /// behavior of existing console objects of that type is undefined.
- /// (aka bad stuff will probably happen but I don't know exactly what)
- template <class T>
- class RuntimeClassRep : public AbstractClassRep
- {
- protected:
- static bool smConRegistered; ///< This variable will be set to true if this class-rep is currently registered
- public:
- RuntimeClassRep( const char *name, const char* conTypeName, S32* conTypeIdPtr, S32 netClassGroupMask, S32 netClassType, S32 netEventDir, AbstractClassRep *parent )
- : AbstractClassRep( conTypeIdPtr, conTypeName )
- {
- // name is a static compiler string so no need to worry about copying or deleting
- mClassName = name;
- mTypeInfo = _MAPTYPE< T >();
- // Clean up mClassId
- for( U32 i = 0; i < NetClassGroupsCount; i++ )
- mClassId[i] = -1;
- // Set properties for this ACR
- mClassType = netClassType;
- mClassGroupMask = netClassGroupMask;
- mNetEventDir = netEventDir;
- parentClass = parent;
- };
- virtual AbstractClassRep* getContainerChildClass(const bool recurse)
- {
- // Fetch container children type.
- AbstractClassRep* pChildren = T::getContainerChildStaticClassRep();
- if (!recurse || pChildren != NULL)
- return pChildren;
- // Fetch parent type.
- AbstractClassRep* pParent = T::getParentStaticClassRep();
- if (pParent == NULL)
- return NULL;
- // Get parent container children.
- return pParent->getContainerChildClass(recurse);
- }
- virtual WriteCustomTamlSchema getCustomTamlSchema(void)
- {
- return T::getStaticWriteCustomTamlSchema();
- }
- /// Perform class specific initialization tasks.
- ///
- /// Link namespaces, call initPersistFields() and consoleInit().
- void init() const
- {
- // Get handle to our parent class, if any, and ourselves (we are our parent's child).
- AbstractClassRep *parent = T::getParentStaticClassRep();
- AbstractClassRep *child = T::getStaticClassRep ();
- // If we got reps, then link those namespaces! (To get proper inheritance.)
- if( parent && child )
- Con::classLinkNamespaces( parent->getNameSpace(), child->getNameSpace() );
- // Finally, do any class specific initialization...
- T::initPersistFields();
- T::consoleInit();
- }
- /// Wrap constructor.
- ConsoleObject *create() const { return new T; }
- //-----------------------------------------------------------------------------
- /// Register this class with the Torque console
- void consoleRegister()
- {
- AssertFatal( !smConRegistered, "Calling consoleRegister, but this type is already linked into the class list" );
- if( !smConRegistered )
- registerClassRep( this );
- // Now initialize the namespace
- mNamespace = Con::lookupNamespace( StringTable->insert( getClassName() ) );
- mNamespace->mClassRep = this;
- // Perform field initialization
- sg_tempFieldList.setSize(0);
- init();
- // So if we have things in it, copy it over...
- if ( sg_tempFieldList.size() != 0 )
- mFieldList = sg_tempFieldList;
- // And of course delete it every round.
- sg_tempFieldList.clear();
- smConRegistered = true;
- }
- /// Unregister this class with the Torque console
- void consoleUnRegister()
- {
- AssertFatal( smConRegistered, "Calling consoleUnRegister, but this type is not linked into the class list" );
- if( !smConRegistered )
- return;
- removeClassRep( this );
- smConRegistered = false;
- }
- /// Returns true if this class type is registered with the console system
- static const bool isRegistered() { return smConRegistered; }
- /// @name Console Type Interface
- /// @{
- virtual void setData( void* dptr, S32 argc, const char** argv, const EnumTable* tbl, BitSet32 flag )
- {
- if( argc == 1 )
- {
- T** obj = ( T** ) dptr;
- *obj = dynamic_cast< T* >( T::__findObject( argv[ 0 ] ) );
- }
- else
- Con::errorf( "Cannot set multiple args to a single ConsoleObject*.");
- }
-
- virtual const char* getData( void* dptr, const EnumTable* tbl, BitSet32 flag )
- {
- T** obj = ( T** ) dptr;
- return Con::getReturnBuffer( T::__getObjectId( *obj ) );
- }
-
- virtual const char* getTypeClassName() { return mClassName; }
- virtual const bool isDatablock() { return T::__smIsDatablock; };
-
- /// @}
- };
- template<class T> bool RuntimeClassRep<T>::smConRegistered = false;
- //-----------------------------------------------------------------------------
- #define DECLARE_RUNTIME_CONOBJECT(className) \
- DECLARE_CLASS( className, Parent ); \
- static S32 _sTypeId; \
- static RuntimeClassRep<className> dynRTClassRep; \
- static AbstractClassRep* getParentStaticClassRep(); \
- static AbstractClassRep* getStaticClassRep(); \
- virtual AbstractClassRep* getClassRep() const
- #define IMPLEMENT_RUNTIME_CONOBJECT(className) \
- IMPLEMENT_CLASS( className, NULL ) \
- END_IMPLEMENT_CLASS; \
- S32 className::_sTypeId; \
- AbstractClassRep* className::getClassRep() const { return &className::dynRTClassRep; } \
- AbstractClassRep* className::getStaticClassRep() { return &dynRTClassRep; } \
- AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
- RuntimeClassRep<className> className::dynRTClassRep(#className, "Type" #className, &_sTypeId, 0, -1, 0, className::getParentStaticClassRep())
- #endif
|