engineObject.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  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 _ENGINEOBJECT_H_
  23. #define _ENGINEOBJECT_H_
  24. #ifndef _ENGINETYPES_H_
  25. #include "console/engineTypes.h"
  26. #endif
  27. #ifndef _REFBASE_H_
  28. #include "core/util/refBase.h"
  29. #endif
  30. /// Disable TMM for this file.
  31. #include "platform/tmm_off.h"
  32. /// @file
  33. /// This file contains the framework for defining class types for interfacing
  34. /// through engine API.
  35. class EngineObject;
  36. /// Assign the current class and all its subclasses to the given export scope.
  37. /// May be overridden by subclasses.
  38. ///
  39. /// @code
  40. /// class MyClass : public EngineObject
  41. /// {
  42. /// DECLARE_CLASS( MyClass, EngineObject );
  43. /// DECLARE_INSCOPE( MyAPI );
  44. /// };
  45. /// @endcode
  46. #define DECLARE_INSCOPE( name ) \
  47. typedef name __DeclScope;
  48. /// Declare that this class and all its subclasses cannot be instantiated through
  49. /// the API, i.e. objects of these classes can only be created inside the engine.
  50. ///
  51. /// @code
  52. /// class MyClass : public EngineObject
  53. /// {
  54. /// DECLARE_CLASS( MyClass, EngineObject );
  55. /// DECLARE_NONINSTANTIABLE;
  56. /// };
  57. /// @endcode
  58. #define DECLARE_NONINSTANTIABLE \
  59. typedef ::FalseType __IsInstantiableType;
  60. /// Declare that this class and all its subclasses can be instantiated through the
  61. /// API using their respective create() functions.
  62. ///
  63. /// May be overridden by subclasses.
  64. ///
  65. /// @code
  66. /// class MyClass : public EngineObject
  67. /// {
  68. /// DECLARE_CLASS( MyClass, EngineObject );
  69. /// DECLARE_INSTANTIABLE;
  70. /// };
  71. /// @endcode
  72. #define DECLARE_INSTANTIABLE \
  73. typedef ::TrueType __IsInstantiableType;
  74. /// Declare a class for which the object's may be forcefully disposed of by the engine.
  75. /// In essense, this means that such objects can only be weak-referenced from within the
  76. /// control layer as their lifetime is ultimately controlled by the engine. This is
  77. /// used for all resource type objects that are owned by their devices.
  78. ///
  79. /// An alternative to disposable types would be to shield the control layer from direct
  80. /// access to these objects and rather expose only intermediary objects. However, at some
  81. /// point this just gets crazy. The control layer wraps around engine objects that wrap
  82. /// around internal objects. The internal object goes away, invalidates the native wrapper
  83. /// which invalidates the managed wrapper.
  84. ///
  85. /// By exposing the control layer directly to in-engine resources using disposable objects,
  86. /// intermediary steps and code are made unnecessary while the control layer is still made
  87. /// aware of the fact that ownership of these objects ultimately and firmly belongs with
  88. /// the engine.
  89. ///
  90. /// One important guarantee for disposable types is that an object will <em>not</em> go
  91. /// away <em>unless</em> the control layer calls into the engine. This means that these
  92. /// objects will not magically disappear while managed code is running.
  93. ///
  94. /// @note This macro automatically redefines destroySelf().
  95. /// @warn Reference-counting is still used for disposable types!! This means that if the
  96. /// reference-count drops to zero, the object will be deleted as any other object.
  97. ///
  98. /// @see IMPLEMENT_DISPOSABLE
  99. #define DECLARE_DISPOSABLE \
  100. protected: \
  101. typedef ::TrueType __IsDisposableType; \
  102. DECLARE_CALLBACK( void, onDispose, () ); \
  103. public: \
  104. virtual void destroySelf() \
  105. { \
  106. onDispose_callback(); \
  107. SuperType::destroySelf(); \
  108. }
  109. /// Matching implement for DECLARE_DISPOSABLE.
  110. ///
  111. /// @param type The disposable C++ class type.
  112. #define IMPLEMENT_DISPOSABLE( type ) \
  113. IMPLEMENT_NEW_CALLBACK( type, onDispose, void, (), (), \
  114. "Called before the instance is disposed." );
  115. /// Declare that the current class (and any of its descendents) can only have a single instance.
  116. ///
  117. /// @code
  118. /// class MySingletonClass : public EngineObject
  119. /// {
  120. /// DECLARE_CLASS( MySingletonClass, EngineObject );
  121. /// DECLARE_SINGLETON;
  122. /// };
  123. /// @endcode
  124. ///
  125. /// @note At the moment, DECLARE_SINGLETON disallows the use of custom create methods
  126. /// on the same class.
  127. #define DECLARE_SINGLETON \
  128. private: \
  129. static ThisType* _smInstance; \
  130. struct _clearInstance; \
  131. friend struct _clearInstance; \
  132. struct _clearInstance { \
  133. ~_clearInstance() { _smInstance = NULL; } \
  134. } _clearInstanceInst; \
  135. public: \
  136. static ThisType* createSingleton(); \
  137. static void destroySingleton(); \
  138. protected: \
  139. typedef ::TrueType __IsSingletonType; \
  140. DEFINE_CREATE_METHOD \
  141. { \
  142. return createSingleton(); \
  143. } \
  144. public: \
  145. static ThisType* instance() \
  146. { \
  147. return _smInstance; \
  148. }
  149. /// Matching implement for DECLARE_SINGLETON.
  150. /// @param type The C++ class type.
  151. #define IMPLEMENT_SINGLETON( type ) \
  152. type::ThisType* type::_smInstance; \
  153. type::ThisType* type::createSingleton() \
  154. { \
  155. if( _smInstance != NULL ) \
  156. { \
  157. Con::errorf( "%s::create - Singleton instance already created", \
  158. TYPE< ThisType >()->getFullyQualifiedExportName().c_str() ); \
  159. return NULL; \
  160. } \
  161. _smInstance = new ThisType(); \
  162. _smInstance->incRefCount(); \
  163. return _smInstance; \
  164. } \
  165. void type::destroySingleton() \
  166. { \
  167. if( !_smInstance ) \
  168. return; \
  169. if( ::IsTrueType< __IsDisposableType >() ) \
  170. _smInstance->destroySelf(); \
  171. else \
  172. _smInstance->decRefCount(); \
  173. } \
  174. DefineNewEngineStaticMethod( type, getInstance, type*, (),, \
  175. "Get the singleton " #type " instance.\n\n" \
  176. "@return The " #type " singleton." ) \
  177. { \
  178. return type::instance(); \
  179. }
  180. /// Declare a static class, i.e. a class which only acts as an export scope. Static
  181. /// classes cannot be instantiated, neither through the API nor inside the engine (at
  182. /// least in a form that would be usable within the API).
  183. ///
  184. /// @code
  185. /// class MyFunctions
  186. /// {
  187. /// DECLARE_STATIC_CLASS( MyFunctions );
  188. /// };
  189. ///
  190. /// IMPLEMENT_STATIC_CLASS( MyFunctions,, "doc" );
  191. ///
  192. /// DefineStaticEngineMethod( MyFunctions, doSomething, void, (),, "" )
  193. /// {
  194. /// // ...
  195. /// }
  196. /// @endcode
  197. ///
  198. /// @param type The C++ class type.
  199. ///
  200. /// @see IMPLEMENT_STATIC_CLASS
  201. #define DECLARE_STATIC_CLASS( type ) \
  202. private: \
  203. static EngineExportScope __engineExportScopeInst; \
  204. static EngineExportScope& __engineExportScope() \
  205. { return __engineExportScopeInst; } \
  206. public: \
  207. template< typename T > friend struct ::_SCOPE; \
  208. /// Matching implement for DECLARE_STATIC_CLASS.
  209. ///
  210. /// @param type The C++ type of the static class. Also used as export name.
  211. /// @param scope Export scope to place the static class in.
  212. /// @param doc Documentation string.
  213. #define IMPLEMENT_STATIC_CLASS( type, scope, doc ) \
  214. EngineExportScope type::__engineExportScopeInst( #type, &_SCOPE< scope >()(), doc );
  215. /// Declare a concrete class @a type derived from the class @a super. Whether the
  216. /// class can be instantiated by the control layer depends on its instantiability.
  217. ///
  218. /// @code
  219. /// class MyClass : public EngineObject
  220. /// {
  221. /// DECLARE_CLASS( MyClass, EngineObject );
  222. /// };
  223. /// @endcode
  224. ///
  225. /// @param type C++ class type.
  226. /// @param super C++ class type of the superclass. May be void only for EngineObject.
  227. ///
  228. /// @see IMPLEMENT_CLASS
  229. /// @see IMPLEMENT_NONINSTANTIABLE_CLASS
  230. #define DECLARE_CLASS( type, super ) \
  231. public: \
  232. typedef type ThisType; \
  233. typedef super SuperType; \
  234. template< typename T > friend struct ::_EngineTypeTraits; \
  235. template< typename T > friend struct ::_SCOPE; \
  236. template< typename T > friend T* _CREATE(); \
  237. template< typename T, typename Base > friend class ::EngineClassTypeInfo; \
  238. private: \
  239. typedef ::_Private::_ConcreteClassBase< ThisType > _ClassBase; \
  240. static EngineClassTypeInfo< ThisType, _ClassBase > _smTypeInfo; \
  241. static EngineExportScope& __engineExportScope(); \
  242. static EnginePropertyTable& _smPropertyTable; \
  243. virtual const EngineTypeInfo* __typeinfo() const; \
  244. public:
  245. /// Declare an abstract class @a type derived from the class @a super.
  246. ///
  247. /// @code
  248. /// class MyClass : public EngineObject
  249. /// {
  250. /// DECLARE_ABSTRACT_CLASS( MyClass, EngineObject );
  251. /// };
  252. /// @endcode
  253. ///
  254. /// @param type C++ class type.
  255. /// @param super C++ class type of the superclass. May be void only for EngineObject.
  256. ///
  257. /// @see IMPLEMENT_NONINSTANTIABLE_CLASS
  258. #define DECLARE_ABSTRACT_CLASS( type, super ) \
  259. public: \
  260. typedef type ThisType; \
  261. typedef super SuperType; \
  262. template< typename T > friend struct ::_EngineTypeTraits; \
  263. template< typename T > friend struct ::_SCOPE; \
  264. template< typename T > friend T* _CREATE(); \
  265. template< typename T, typename Base > friend class ::EngineClassTypeInfo; \
  266. private: \
  267. typedef ::_Private::_AbstractClassBase< ThisType > _ClassBase; \
  268. static EngineClassTypeInfo< ThisType, _ClassBase > _smTypeInfo; \
  269. static EngineExportScope& __engineExportScope(); \
  270. static EnginePropertyTable& _smPropertyTable; \
  271. virtual const EngineTypeInfo* __typeinfo() const; \
  272. public:
  273. /// Matching implement for DECLARE_ABSTRACT_CLASS or DECLARE_CLASS for classes
  274. /// that are not instantiable through the API.
  275. ///
  276. /// @code
  277. /// class MyClass : public EngineObject
  278. /// {
  279. /// DECLARE_CLASS( MyClass, EngineObject );
  280. /// DECLARE_INSCOPE( MyScope );
  281. /// DECLARE_NONINSTANTIABLE;
  282. /// };
  283. ///
  284. /// IMPLEMENT_NONINSTANTIABLE_CLASS( MyClass, "My class." )
  285. /// PROPERTY( myProperty, 1, "My property.", EnginePropertyTransient )
  286. /// END_IMPLEMENT_CLASS;
  287. /// @endcode
  288. ///
  289. /// @note If you want the export name to be different to the actual class
  290. /// name, use a typedef.
  291. ///
  292. /// @param type The C++ class type.
  293. /// @doc Documentation string.
  294. #define IMPLEMENT_NONINSTANTIABLE_CLASS( type, doc ) \
  295. DEFINE_CALLIN( fn ## type ## _staticGetType, staticGetType, type, const EngineTypeInfo*, (),,, \
  296. "Get the type info object for the " #type " class.\n\n" \
  297. "@return The type info object for " #type ) \
  298. { \
  299. return ::TYPE< type >(); \
  300. } \
  301. EngineClassTypeInfo< type::ThisType, type::_ClassBase > \
  302. type::_smTypeInfo( #type, &_SCOPE< __DeclScope >()(), doc ); \
  303. EngineExportScope& type::__engineExportScope() { return type::_smTypeInfo; } \
  304. const EngineTypeInfo* type::__typeinfo() const { return &_smTypeInfo; } \
  305. namespace { namespace _ ## type { \
  306. extern EnginePropertyTable _propertyTable; \
  307. } } \
  308. EnginePropertyTable& type::_smPropertyTable = _ ## type::_propertyTable; \
  309. namespace { namespace _ ## type { \
  310. EnginePropertyTable::Property _properties[] = {
  311. /// Matching implement to DECLARE_CLASS for classes that are instantiable
  312. /// through the API.
  313. ///
  314. /// @note engineFunctions.h must be included for this macro to work.
  315. ///
  316. /// @param type The C++ class type.
  317. /// @param doc Documentation string.
  318. #define IMPLEMENT_CLASS( type, doc ) \
  319. DEFINE_CALLIN( fn ## type ## _create, create, type, type*, (),,, \
  320. "Create a new " #type " instance.\n" \
  321. "@return A new " #type " instance with a reference count of 1." ) \
  322. { \
  323. return ::_CREATE< type >(); \
  324. } \
  325. IMPLEMENT_NONINSTANTIABLE_CLASS( type, doc )
  326. /// Close an IMPLEMENT_CLASS or IMPLEMENT_NONINSTANTIABLE_CLASS block.
  327. #define END_IMPLEMENT_CLASS \
  328. { NULL } \
  329. }; \
  330. EnginePropertyTable _propertyTable \
  331. ( sizeof( _properties ) / sizeof( _properties[ 0 ] ) - 1, _properties ); \
  332. } }
  333. /// Define a property on the current class.
  334. ///
  335. /// A property named XXX must have a corresponding "getXXX" and/or "setXXX" accessor
  336. /// method defined on the class. If there is only a "setXXX" method, the property is
  337. /// write-only. If there is only a "getXXX", the property is read-only. If both are
  338. /// defined, the property is read-write.
  339. ///
  340. /// If the accessors are static methods, the property is a static property. Otherwise
  341. /// it is an instance property.
  342. ///
  343. /// The type of the property is determined by its accessor methods.
  344. ///
  345. /// A getXXX method must take no arguments and return a value. A setXXX method must take
  346. /// one argument and return void.
  347. ///
  348. /// If the property is indexed (@a numElements != 1), the get and set methods take an
  349. /// additional first argument which is the integer index (type S32). Additionally, the get method
  350. /// must be called "getXXXElement" and the set method must be called "setXXXElement".
  351. ///
  352. /// Indexed properties may be either fixed-size or variable-sized. Fixed-size indexed
  353. /// properties have numElements count > 1. Variable-size indexed properties have a
  354. /// numElements count of 0. Variable-sized indexed properties must have an additional
  355. /// method "getXXXCount" that returns the current count of elements for the given property.
  356. ///
  357. /// @code
  358. /// IMPLEMENT_CLASS( MyClass, "My class." )
  359. /// PROPERTY( myProperty, 1, "My property.", EnginePropertyTransient )
  360. /// END_IMPLEMENT_CLASS;
  361. /// @endcode
  362. ///
  363. /// @note Case is ignored when matching get and set methods to property definitions.
  364. ///
  365. /// @param name The name of the property. Must correspond with the get and/or set methods.
  366. /// @param numElements If this is a fixed size array property, this is the number of elements
  367. /// the fixed array has. Otherwise 1.
  368. /// @param doc Documentation string.
  369. /// @param flags A combination of EnginePropertyFlags or simply 0 if not applicable.
  370. ///
  371. /// @see EnginePropertyFlags
  372. #define PROPERTY( name, numElements, doc, flags ) \
  373. { #name, doc, numElements, flags },
  374. ///
  375. #define PROPERTY_GROUP( name, numElements, doc ) \
  376. { #name, doc, numElements, EnginePropertyGroupBegin },
  377. ///
  378. #define END_PROPERTY_GROUP \
  379. { NULL, NULL, 0, EnginePropertyGroupEnd },
  380. /// Define a custom create function for this class and its subclasses. Create
  381. /// functions are used to create new instances of class types. This code will be
  382. /// called by the automatically generated "createXXX" functions exported through
  383. /// the API.
  384. ///
  385. /// The type of class being created is available to the code as the type parameter "T"
  386. /// which is guaranteed to be a subtype of the current class type.
  387. ///
  388. /// @code
  389. /// class MyClass : public EngineObject
  390. /// {
  391. /// DECLARE_CLASS( MyClass, EngineObject );
  392. /// protected:
  393. /// DEFINE_CREATE_METHOD
  394. /// {
  395. /// T* object = new T();
  396. /// object->incRefCount();
  397. /// object->_registerObject();
  398. /// return object;
  399. /// }
  400. /// virtual void _registerObject();
  401. /// };
  402. /// @endcode
  403. ///
  404. /// @note A create method must return an object with a reference count of 1.
  405. #define DEFINE_CREATE_METHOD \
  406. template< typename T > \
  407. static T* __create()
  408. /// Define a method that calls back into the control layer.
  409. ///
  410. /// @see IMPLEMENT_CALLBACK
  411. #define DECLARE_CALLBACK( returnType, name, args ) \
  412. virtual returnType name ## _callback args
  413. // Our backdoor into calling the __create method on any class even if it is
  414. // protected or private. This function is automatically made friends of any
  415. // EngineObject class. Should be used except by internal API code.
  416. template< typename T >
  417. inline T* _CREATE()
  418. {
  419. return T::template __create< T >();
  420. }
  421. /// Interface for object memory allocation.
  422. class IEngineObjectPool
  423. {
  424. public:
  425. /// Allocate a new object memory block of the given size.
  426. /// @return Pointer to a new memory block or NULL on failure.
  427. virtual void* allocateObject( U32 size TORQUE_TMM_ARGS_DECL ) = 0;
  428. /// Return the member for the object at the given address to the
  429. /// allocator for reuse.
  430. /// @param ptr Pointer to an object memory block previously allocated with allocateObject().
  431. virtual void freeObject( void* ptr ) = 0;
  432. /// Instance of the object pool to use by default.
  433. static IEngineObjectPool* DEFAULT;
  434. };
  435. /// Singleton class that uses the C runtime memory routines for allocating objects.
  436. class EngineCRuntimeObjectPool : public IEngineObjectPool
  437. {
  438. public:
  439. typedef IEngineObjectPool Parent;
  440. protected:
  441. static EngineCRuntimeObjectPool smInstance;
  442. public:
  443. /// Return the singleton instance of this pool.
  444. static EngineCRuntimeObjectPool* instance() { return &smInstance; }
  445. // IEngineObjectPool
  446. virtual void* allocateObject( U32 size TORQUE_TMM_ARGS_DECL );
  447. virtual void freeObject( void* ptr );
  448. };
  449. /// Base class for all objects that may be passed to the control layer.
  450. ///
  451. /// A set of rules applies to all EngineObject-derived classes:
  452. ///
  453. /// - Every EngineObject class must have a default constructor.
  454. /// - The default constructor and the destructor of every EngineObject class must be public.
  455. /// - If an EngineObject class inherits from multiple classes, the class leading back to EngineObject
  456. /// must be the @b first class in the list to ensure binary-compatible class layouts.
  457. /// - EngineObjects are cooperatively reference-counted by both the engine as well as the control
  458. /// layer.
  459. class EngineObject : public StrongRefBase
  460. {
  461. public:
  462. DECLARE_ABSTRACT_CLASS( EngineObject, void );
  463. DECLARE_INSCOPE( _GLOBALSCOPE );
  464. DECLARE_INSTANTIABLE;
  465. friend const EngineTypeInfo* TYPEOF( const EngineObject* ); // __typeinfo
  466. friend void*& _USERDATA( EngineObject* ); // mEngineObjectUserData
  467. friend class StaticEngineObject; // mEngineObjectPool
  468. protected:
  469. typedef ::FalseType __IsDisposableType;
  470. typedef ::FalseType __IsSingletonType;
  471. DEFINE_CREATE_METHOD
  472. {
  473. T* object = new T;
  474. object->incRefCount();
  475. return object;
  476. }
  477. /// Subclasses should overload this method instead of the public destroySelf().
  478. virtual void _destroySelf() {}
  479. ///
  480. static void* _allocateObject( size_t size, IEngineObjectPool* pool TORQUE_TMM_ARGS_DECL );
  481. public:
  482. EngineObject();
  483. virtual ~EngineObject();
  484. /// Return a string that describes this instance. Meant primarily for debugging.
  485. virtual String describeSelf() const;
  486. #ifndef TORQUE_DISABLE_MEMORY_MANAGER
  487. // Make sure no matter what, we get the new/delete calls.
  488. void* operator new( size_t size );
  489. void* operator new( size_t size, IEngineObjectPool* pool );
  490. #endif
  491. /// Allocate a new object in the default object pool.
  492. /// @param size Size of the object in bytes.
  493. /// @return Memory block for new object; never NULL.
  494. void* operator new( size_t size TORQUE_TMM_ARGS_DECL );
  495. /// Allocate a new object in the given object pool.
  496. ///
  497. /// If the given pool's allocateObject returns NULL, the method will fall back
  498. /// to the default pool.
  499. ///
  500. /// @param size Size of the object in bytes.
  501. /// @param pool Object pool to allocate the object in.
  502. /// @return Memory block for the new object; never NULL.
  503. void* operator new( size_t size, IEngineObjectPool* pool TORQUE_TMM_ARGS_DECL );
  504. /// Placement new.
  505. void* operator new( size_t size, void* ptr ) { return ptr; }
  506. /// Release the given object's memory in the pool it has been allocated from.
  507. void operator delete( void* ptr );
  508. /// Return the pool of EngineObjects to which this object belongs.
  509. IEngineObjectPool* getEngineObjectPool() const { return mEngineObjectPool; }
  510. // StrongRefBase
  511. virtual void destroySelf();
  512. #ifdef TORQUE_DEBUG
  513. /// @name Instance Tracking (debugging only)
  514. ///
  515. /// In debug builds, all EngineObjects are kept on a global list so that it is easy
  516. /// to enumerate all live objects at any time.
  517. ///
  518. /// @note This is @b NOT thread-safe.
  519. /// @{
  520. /// Type of callback function for iterating over EngineObject instances.
  521. typedef void ( *DebugEnumInstancesCallback )( EngineObject* );
  522. /// Dump describeSelf()s of all live ConsoleObjects to the console.
  523. static void debugDumpInstances();
  524. /// Call the given callback for all instances of the given type.
  525. /// Callback may also be NULL in which case the method just iterates
  526. /// over all instances of the given type. This is useful for setting
  527. /// a breakpoint during debugging.
  528. static void debugEnumInstances( const std::type_info& type, DebugEnumInstancesCallback callback );
  529. /// Same as above but uses an export class name and also includes
  530. /// inheritance (i.e. enumerates all instances of the given class and
  531. /// its subclasses).
  532. static void debugEnumInstances( const char* className, DebugEnumInstancesCallback callback );
  533. private:
  534. /// Next object in global link chain of engine objects.
  535. /// @note Debug builds only.
  536. EngineObject* mNextEngineObject;
  537. /// Previous object in global link chain of engine objects.
  538. /// @note Debug builds only.
  539. EngineObject* mPrevEngineObject;
  540. /// Total number of engine objects currently instantiated.
  541. /// @note Debug builds only.
  542. static U32 smNumEngineObjects;
  543. /// First object in the global link chain of engine objects.
  544. /// @note Debug builds only.
  545. static EngineObject* smFirstEngineObject;
  546. /// @}
  547. #endif
  548. private:
  549. /// Object pool to which this object belongs. If this is NULL,
  550. /// the object will not deallocate itself when it is destructed.
  551. /// This is useful for inline allocation of objects.
  552. IEngineObjectPool* mEngineObjectPool;
  553. /// Opaque user data pointer that the control layer may install
  554. /// on any engine object. Most importantly, this allows control layers
  555. /// to very easily keep track of EngineObjects that they have already
  556. /// created their own wrapper objects for.
  557. void* mEngineObjectUserData;
  558. // Disable array new/delete operators.
  559. void* operator new[]( size_t );
  560. void operator delete[]( void* );
  561. };
  562. /// A statically allocated engine object.
  563. ///
  564. /// Static objects have an implicit initial reference count of one and will not
  565. /// delete themselves even when asked to do so.
  566. class StaticEngineObject : public EngineObject
  567. {
  568. public:
  569. DECLARE_ABSTRACT_CLASS( StaticEngineObject, EngineObject );
  570. DECLARE_NONINSTANTIABLE;
  571. StaticEngineObject();
  572. // EngineObject.
  573. virtual void destroySelf();
  574. };
  575. typedef StrongRefPtr< EngineObject > EngineObjectRef;
  576. typedef WeakRefPtr< EngineObject > EngineObjectWeakRef;
  577. /// Return the type info object for the dynamic type of the given object.
  578. /// @param object An EngineObject or NULL.
  579. /// @return An EngineTypeInfo instance or NULL if @a object is NULL.
  580. inline const EngineTypeInfo* TYPEOF( const EngineObject* object )
  581. {
  582. if( !object )
  583. return NULL;
  584. return object->__typeinfo();
  585. }
  586. #include "platform/tmm_on.h"
  587. #endif // !_ENGINEOBJECT_H_