123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- //-----------------------------------------------------------------------------
- // 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.
- //-----------------------------------------------------------------------------
- #include "console/engineObject.h"
- #include "console/engineAPI.h"
- #include "platform/tmm_off.h"
- IMPLEMENT_NONINSTANTIABLE_CLASS( EngineObject,
- "Abstract base class for all objects exposed through the engine API." )
- END_IMPLEMENT_CLASS;
- IMPLEMENT_NONINSTANTIABLE_CLASS( StaticEngineObject,
- "Abstract base class for objects that are statically allocated in the engine." )
- END_IMPLEMENT_CLASS;
- #ifdef TORQUE_DEBUG
- U32 EngineObject::smNumEngineObjects;
- EngineObject* EngineObject::smFirstEngineObject;
- #endif
- IEngineObjectPool* IEngineObjectPool::DEFAULT = EngineCRuntimeObjectPool::instance();
- EngineCRuntimeObjectPool EngineCRuntimeObjectPool::smInstance;
- // Helper to get to engine object's user data. Not exposed through get/set methods
- // as the rest of the engine has no business accessing this data. It is for the
- // exclusive use by the control layer.
- void*& _USERDATA( EngineObject* object )
- {
- return object->mEngineObjectUserData;
- }
- //-----------------------------------------------------------------------------
- EngineObject::EngineObject()
- : mEngineObjectPool(NULL), mEngineObjectUserData( NULL )
- {
- #ifdef TORQUE_DEBUG
- // Add to instance list.
- mNextEngineObject = smFirstEngineObject;
- mPrevEngineObject = NULL;
- if( smFirstEngineObject )
- smFirstEngineObject->mPrevEngineObject = this;
- smFirstEngineObject = this;
- smNumEngineObjects ++;
- #endif
- }
- //-----------------------------------------------------------------------------
- EngineObject::~EngineObject()
- {
- #ifdef TORQUE_DEBUG
- if( mPrevEngineObject )
- mPrevEngineObject->mNextEngineObject = mNextEngineObject;
- else
- smFirstEngineObject = mNextEngineObject;
-
- if( mNextEngineObject )
- mNextEngineObject->mPrevEngineObject = mPrevEngineObject;
- smNumEngineObjects --;
- #endif
- }
- //-----------------------------------------------------------------------------
- void EngineObject::destroySelf()
- {
- if( !engineAPI::gUseConsoleInterop )
- AssertFatal( !getRefCount() || TYPEOF( this )->isDisposable(), "EngineObject::destroySelf - object still referenced!" );
- // Call the internal _destroySelf().
- _destroySelf();
- // Destruct the object and release it in the pool.
-
- IEngineObjectPool* pool = this->mEngineObjectPool;
- void* object = this;
-
- destructInPlace( this );
- if( pool )
- pool->freeObject( object );
- }
- //-----------------------------------------------------------------------------
- String EngineObject::describeSelf() const
- {
- String desc = String::ToString( "class: %s", TYPEOF( this )->getFullyQualifiedExportName().c_str() );
-
- return desc;
- }
- //-----------------------------------------------------------------------------
- #ifndef TORQUE_DISABLE_MEMORY_MANAGER
- void* EngineObject::operator new( size_t size )
- {
- AssertFatal( IEngineObjectPool::DEFAULT, "EngineObject::new - No default pool set!" );
- void* ptr = IEngineObjectPool::DEFAULT->allocateObject( size TORQUE_TMM_LOC );
- if( !ptr )
- {
- Platform::AlertOK( "Torque Memory Error", "Out of memory. Shutting down.\n");
- Platform::forceShutdown( -1 );
- }
-
- EngineObject* object = reinterpret_cast< EngineObject* >( ptr );
- object->mEngineObjectPool = IEngineObjectPool::DEFAULT;
-
- return ptr;
- }
- #endif
- //-----------------------------------------------------------------------------
- #ifndef TORQUE_DISABLE_MEMORY_MANAGER
- void* EngineObject::operator new( size_t size, IEngineObjectPool* pool )
- {
- AssertFatal( pool, "EngineObject::new - Got a NULL pool pointer!" );
- void* ptr = pool->allocateObject( size TORQUE_TMM_LOC );
- if( !ptr )
- {
- // Fall back to default pool.
-
- pool = IEngineObjectPool::DEFAULT;
- AssertFatal( pool, "EngineObject::new - No default pool set!" );
- ptr = pool->allocateObject( size TORQUE_TMM_LOC );
-
- if( !ptr )
- {
- Platform::AlertOK( "Torque Memory Error", "Out of memory. Shutting down.\n");
- Platform::forceShutdown( -1 );
- }
- }
-
- EngineObject* object = reinterpret_cast< EngineObject* >( ptr );
- object->mEngineObjectPool = pool;
-
- return ptr;
- }
- #endif
- //-----------------------------------------------------------------------------
- void* EngineObject::operator new( size_t size TORQUE_TMM_ARGS_DECL )
- {
- AssertFatal( IEngineObjectPool::DEFAULT, "EngineObject::new - No default pool set!" );
- void* ptr = IEngineObjectPool::DEFAULT->allocateObject( size TORQUE_TMM_ARGS );
- if( !ptr )
- {
- Platform::AlertOK( "Torque Memory Error", "Out of memory. Shutting down.\n");
- Platform::forceShutdown( -1 );
- }
-
- EngineObject* object = reinterpret_cast< EngineObject* >( ptr );
- object->mEngineObjectPool = IEngineObjectPool::DEFAULT;
-
- return ptr;
- }
- //-----------------------------------------------------------------------------
- void* EngineObject::operator new( size_t size, IEngineObjectPool* pool TORQUE_TMM_ARGS_DECL )
- {
- AssertFatal( pool, "EngineObject::new - Got a NULL pool pointer!" );
- void* ptr = pool->allocateObject( size TORQUE_TMM_ARGS );
- if( !ptr )
- {
- // Fall back to default pool.
-
- pool = IEngineObjectPool::DEFAULT;
- AssertFatal( pool, "EngineObject::new - No default pool set!" );
- ptr = pool->allocateObject( size TORQUE_TMM_ARGS );
-
- if( !ptr )
- {
- Platform::AlertOK( "Torque Memory Error", "Out of memory. Shutting down.\n");
- Platform::forceShutdown( -1 );
- }
- }
-
- EngineObject* object = reinterpret_cast< EngineObject* >( ptr );
- object->mEngineObjectPool = pool;
-
- return ptr;
- }
- //-----------------------------------------------------------------------------
- void EngineObject::operator delete( void* ptr )
- {
- if( !ptr )
- return;
- // AssertWarn( false, "EngineObject::delete - Directly deleting an EngineObject is disallowed!" );
-
- EngineObject* object = reinterpret_cast< EngineObject* >( ptr );
- AssertFatal( !object->getRefCount(), "EngineObject::delete - object still referenced!" );
- if( object->mEngineObjectPool )
- object->mEngineObjectPool->freeObject( object );
- }
- //-----------------------------------------------------------------------------
- #ifdef TORQUE_DEBUG
- void EngineObject::debugDumpInstances()
- {
- Con::printf( "----------- Dumping EngineObjects ----------------" );
- for( EngineObject* object = smFirstEngineObject; object != NULL; object = object->mNextEngineObject )
- Con::printf( object->describeSelf() );
- Con::printf( "%i EngineObjects", smNumEngineObjects );
- }
- //-----------------------------------------------------------------------------
- void EngineObject::debugEnumInstances( const std::type_info& type, DebugEnumInstancesCallback callback )
- {
- for( EngineObject* object = smFirstEngineObject; object != NULL; object = object->mNextEngineObject )
- if( typeid( *object ) == type )
- {
- // Set breakpoint here to break for each instance.
- if( callback )
- callback( object );
- }
- }
- //-----------------------------------------------------------------------------
- void EngineObject::debugEnumInstances( const char* className, DebugEnumInstancesCallback callback )
- {
- for( EngineObject* object = smFirstEngineObject; object != NULL; object = object->mNextEngineObject )
- {
- for( const EngineTypeInfo* type = TYPEOF( object ); type != NULL; type = type->getSuperType() )
- if( dStricmp( type->getTypeName(), className ) == 0 )
- {
- // Set breakpoint here to break for each instance.
- if( callback )
- callback( object );
-
- break;
- }
- }
- }
- #endif // TORQUE_DEBUG
- //-----------------------------------------------------------------------------
- void* EngineCRuntimeObjectPool::allocateObject( U32 size TORQUE_TMM_ARGS_DECL )
- {
- #ifdef TORQUE_DISABLE_MEMORY_MANAGER
- return dMalloc( size );
- #else
- return dMalloc_r( size TORQUE_TMM_ARGS );
- #endif
- }
- //-----------------------------------------------------------------------------
- void EngineCRuntimeObjectPool::freeObject( void* ptr )
- {
- dFree( ptr );
- }
- //-----------------------------------------------------------------------------
- StaticEngineObject::StaticEngineObject()
- {
- mEngineObjectPool = NULL;
-
- // Add an artificial reference to the object.
- incRefCount();
- }
- //-----------------------------------------------------------------------------
- void StaticEngineObject::destroySelf()
- {
- AssertFatal( false, "StaticEngineObject::destroySelf - Cannot destroy static object!" );
- }
- //=============================================================================
- // API.
- //=============================================================================
- // MARK: ---- API ----
- //-----------------------------------------------------------------------------
- DefineNewEngineMethod( EngineObject, getType, const EngineTypeInfo*, (),,
- "Return the type descriptor for the type the object is an instance of.\n"
- "@return The type descriptor for the object's dynamic type." )
- {
- return TYPEOF( object );
- }
- //-----------------------------------------------------------------------------
- DefineNewEngineMethod( EngineObject, addRef, void, (),,
- "Increase the reference count of the given object.\n\n"
- "@param object An object." )
- {
- object->incRefCount();
- }
- //-----------------------------------------------------------------------------
- DefineNewEngineMethod( EngineObject, release, void, (),,
- "Decrease the reference count of the given object. If the count drops to "
- "zero, the object will be deleted.\n\n"
- "@param object An object." )
- {
- object->decRefCount();
- }
- //-----------------------------------------------------------------------------
- DefineNewEngineMethod( EngineObject, getUserData, void*, (),,
- "Get the opaque user data pointer installed on the object.\n"
- "@return The user data pointer previously installed on the object; NULL by default." )
- {
- return _USERDATA( object );
- }
- //-----------------------------------------------------------------------------
- DefineNewEngineMethod( EngineObject, setUserData, void, ( void* ptr ),,
- "Install an opaque pointer on the object that the control layer can use to "
- "associate data with the object.\n"
- "@param ptr A pointer.\n" )
- {
- _USERDATA( object ) = ptr;
- }
- //-----------------------------------------------------------------------------
- #ifdef TORQUE_DEBUG
- DefineEngineFunction( debugDumpAllObjects, void, (),,
- "@brief Dumps all current EngineObject instances to the console.\n\n"
- "@note This function is only available in debug builds.\n\n"
- "@ingroup Debugging" )
- {
- EngineObject::debugDumpInstances();
- }
- #endif // TORQUE_DEBUG
|