runtimeClassRep.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _RUNTIME_CLASSREP_H_
  23. #define _RUNTIME_CLASSREP_H_
  24. #include "console/consoleObject.h"
  25. #include "console/consoleInternal.h"
  26. /// This class is to allow new types to be added, at run-time, to Torque.
  27. /// This is primarily for dynamic libraries, plugins etc.
  28. ///
  29. /// The idea is the same, one instance per type which is getting registered
  30. /// however it doesn't get added to the dictionary until it is told to
  31. /// add itself. It can be removed, as well, though no safe-execution
  32. /// assurances are made by this class. If an object type is removed
  33. /// behavior of existing console objects of that type is undefined.
  34. /// (aka bad stuff will probably happen but I don't know exactly what)
  35. template <class T>
  36. class RuntimeClassRep : public AbstractClassRep
  37. {
  38. protected:
  39. static bool smConRegistered; ///< This variable will be set to true if this class-rep is currently registered
  40. public:
  41. RuntimeClassRep( const char *name, const char* conTypeName, S32* conTypeIdPtr, S32 netClassGroupMask, S32 netClassType, S32 netEventDir, AbstractClassRep *parent )
  42. : AbstractClassRep( conTypeIdPtr, conTypeName )
  43. {
  44. // name is a static compiler string so no need to worry about copying or deleting
  45. mClassName = name;
  46. mTypeInfo = _MAPTYPE< T >();
  47. // Clean up mClassId
  48. for( U32 i = 0; i < NetClassGroupsCount; i++ )
  49. mClassId[i] = -1;
  50. // Set properties for this ACR
  51. mClassType = netClassType;
  52. mClassGroupMask = netClassGroupMask;
  53. mNetEventDir = netEventDir;
  54. parentClass = parent;
  55. };
  56. virtual AbstractClassRep* getContainerChildClass(const bool recurse)
  57. {
  58. // Fetch container children type.
  59. AbstractClassRep* pChildren = T::getContainerChildStaticClassRep();
  60. if (!recurse || pChildren != NULL)
  61. return pChildren;
  62. // Fetch parent type.
  63. AbstractClassRep* pParent = T::getParentStaticClassRep();
  64. if (pParent == NULL)
  65. return NULL;
  66. // Get parent container children.
  67. return pParent->getContainerChildClass(recurse);
  68. }
  69. virtual WriteCustomTamlSchema getCustomTamlSchema(void)
  70. {
  71. return T::getStaticWriteCustomTamlSchema();
  72. }
  73. /// Perform class specific initialization tasks.
  74. ///
  75. /// Link namespaces, call initPersistFields() and consoleInit().
  76. void init() const
  77. {
  78. // Get handle to our parent class, if any, and ourselves (we are our parent's child).
  79. AbstractClassRep *parent = T::getParentStaticClassRep();
  80. AbstractClassRep *child = T::getStaticClassRep ();
  81. // If we got reps, then link those namespaces! (To get proper inheritance.)
  82. if( parent && child )
  83. Con::classLinkNamespaces( parent->getNameSpace(), child->getNameSpace() );
  84. // Finally, do any class specific initialization...
  85. T::initPersistFields();
  86. T::consoleInit();
  87. }
  88. /// Wrap constructor.
  89. ConsoleObject *create() const { return new T; }
  90. //-----------------------------------------------------------------------------
  91. /// Register this class with the Torque console
  92. void consoleRegister()
  93. {
  94. AssertFatal( !smConRegistered, "Calling consoleRegister, but this type is already linked into the class list" );
  95. if( !smConRegistered )
  96. registerClassRep( this );
  97. // Now initialize the namespace
  98. mNamespace = Con::lookupNamespace( StringTable->insert( getClassName() ) );
  99. mNamespace->mClassRep = this;
  100. // Perform field initialization
  101. sg_tempFieldList.setSize(0);
  102. init();
  103. // So if we have things in it, copy it over...
  104. if ( sg_tempFieldList.size() != 0 )
  105. mFieldList = sg_tempFieldList;
  106. // And of course delete it every round.
  107. sg_tempFieldList.clear();
  108. smConRegistered = true;
  109. }
  110. /// Unregister this class with the Torque console
  111. void consoleUnRegister()
  112. {
  113. AssertFatal( smConRegistered, "Calling consoleUnRegister, but this type is not linked into the class list" );
  114. if( !smConRegistered )
  115. return;
  116. removeClassRep( this );
  117. smConRegistered = false;
  118. }
  119. /// Returns true if this class type is registered with the console system
  120. static const bool isRegistered() { return smConRegistered; }
  121. /// @name Console Type Interface
  122. /// @{
  123. virtual void setData( void* dptr, S32 argc, const char** argv, const EnumTable* tbl, BitSet32 flag )
  124. {
  125. if( argc == 1 )
  126. {
  127. T** obj = ( T** ) dptr;
  128. *obj = dynamic_cast< T* >( T::__findObject( argv[ 0 ] ) );
  129. }
  130. else
  131. Con::errorf( "Cannot set multiple args to a single ConsoleObject*.");
  132. }
  133. virtual const char* getData( void* dptr, const EnumTable* tbl, BitSet32 flag )
  134. {
  135. T** obj = ( T** ) dptr;
  136. return Con::getReturnBuffer( T::__getObjectId( *obj ) );
  137. }
  138. virtual const char* getTypeClassName() { return mClassName; }
  139. virtual const bool isDatablock() { return T::__smIsDatablock; };
  140. /// @}
  141. };
  142. template<class T> bool RuntimeClassRep<T>::smConRegistered = false;
  143. //-----------------------------------------------------------------------------
  144. #define DECLARE_RUNTIME_CONOBJECT(className) \
  145. DECLARE_CLASS( className, Parent ); \
  146. static S32 _sTypeId; \
  147. static RuntimeClassRep<className> dynRTClassRep; \
  148. static AbstractClassRep* getParentStaticClassRep(); \
  149. static AbstractClassRep* getStaticClassRep(); \
  150. virtual AbstractClassRep* getClassRep() const
  151. #define IMPLEMENT_RUNTIME_CONOBJECT(className) \
  152. IMPLEMENT_CLASS( className, NULL ) \
  153. END_IMPLEMENT_CLASS; \
  154. S32 className::_sTypeId; \
  155. AbstractClassRep* className::getClassRep() const { return &className::dynRTClassRep; } \
  156. AbstractClassRep* className::getStaticClassRep() { return &dynRTClassRep; } \
  157. AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
  158. RuntimeClassRep<className> className::dynRTClassRep(#className, "Type" #className, &_sTypeId, 0, -1, 0, className::getParentStaticClassRep())
  159. #endif