void ObjectRefCountSupport::Shutdown() { #if HELIUM_ENABLE_MEMORY_TRACKING ConcurrentHashSet< RefCountProxy< Reflect::Object >* >::ConstAccessor refCountProxyAccessor; if( Reflect::ObjectRefCountSupport::GetFirstActiveProxy( refCountProxyAccessor ) ) { HELIUM_TRACE( TraceLevels::Error, TXT( "%" ) PRIuSZ TXT( " reference counted object(s) still active during shutdown!\n" ), Reflect::ObjectRefCountSupport::GetActiveProxyCount() ); #if 0 refCountProxyAccessor.Release(); #else Reflect::ObjectRefCountSupport::GetFirstActiveProxy( refCountProxyAccessor ); while( refCountProxyAccessor.IsValid() ) { RefCountProxy< Reflect::Object >* pProxy = *refCountProxyAccessor; HELIUM_ASSERT( pProxy ); HELIUM_TRACE( TraceLevels::Error, TXT( " - 0x%p: (%" ) PRIu16 TXT( " strong ref(s), %" ) PRIu16 TXT( " weak ref(s))\n" ), pProxy, pProxy->GetStrongRefCount(), pProxy->GetWeakRefCount() ); ++refCountProxyAccessor; } refCountProxyAccessor.Release(); #endif } #endif // HELIUM_ENABLE_MEMORY_TRACKING delete sm_pStaticTranslator; sm_pStaticTranslator = NULL; }
/// Perform shutdown of the GameObject system. /// /// This releases all final references to objects and releases all allocated memory. This should be called during /// the shutdown process after all types have been unregistered as well as after calling GameObjectType::Shutdown(). /// /// @see GameObjectType::Shutdown() void GameObject::Shutdown() { HELIUM_TRACE( TraceLevels::Info, TXT( "Shutting down GameObject system.\n" ) ); GameObject::ReleaseStaticType(); #pragma TODO( "Fix support for casting between Reflect::Object and GameObject once the type systems have been properly integrated." ) #if HELIUM_ENABLE_MEMORY_TRACKING ConcurrentHashSet< RefCountProxy< Reflect::Object >* >::ConstAccessor refCountProxyAccessor; if( Reflect::ObjectRefCountSupport::GetFirstActiveProxy( refCountProxyAccessor ) ) { HELIUM_TRACE( TraceLevels::Error, TXT( "%" ) TPRIuSZ TXT( " smart pointer(s) still active during shutdown!\n" ), Reflect::ObjectRefCountSupport::GetActiveProxyCount() ); #if 1 refCountProxyAccessor.Release(); #else size_t activeGameObjectCount = 0; while( refCountProxyAccessor.IsValid() ) { RefCountProxy< Reflect::Object >* pProxy = *refCountProxyAccessor; HELIUM_ASSERT( pProxy ); GameObject* pGameObject = Reflect::SafeCast< GameObject >( pProxy->GetObject() ); if( pGameObject ) { ++activeGameObjectCount; } ++refCountProxyAccessor; } HELIUM_TRACE( TraceLevels::Error, TXT( "%" ) TPRIuSZ TXT( " active GameObject smart pointer(s):\n" ), activeGameObjectCount ); Reflect::ObjectRefCountSupport::GetFirstActiveProxy( refCountProxyAccessor ); while( refCountProxyAccessor.IsValid() ) { RefCountProxy< Reflect::Object >* pProxy = *refCountProxyAccessor; HELIUM_ASSERT( pProxy ); GameObject* pGameObject = Reflect::SafeCast< GameObject >( pProxy->GetObject() ); if( pGameObject ) { HELIUM_TRACE( TraceLevels::Error, TXT( "- 0x%p: %s (%" ) TPRIu16 TXT( " strong ref(s), %" ) TPRIu16 TXT( " weak ref(s))\n" ), pProxy, ( pGameObject ? *pGameObject->GetPath().ToString() : TXT( "(cleared reference)" ) ), pProxy->GetStrongRefCount(), pProxy->GetWeakRefCount() ); } ++refCountProxyAccessor; } #endif } #endif // HELIUM_ENABLE_MEMORY_TRACKING #if !HELIUM_RELEASE size_t objectCountActual = sm_objects.GetUsedSize(); if( objectCountActual != 0 ) { HELIUM_TRACE( TraceLevels::Error, TXT( "%" ) TPRIuSZ TXT( " object(s) still referenced during shutdown!\n" ), objectCountActual ); size_t objectCount = sm_objects.GetSize(); for( size_t objectIndex = 0; objectIndex < objectCount; ++objectIndex ) { if( !sm_objects.IsElementValid( objectIndex ) ) { continue; } GameObject* pObject = sm_objects[ objectIndex ]; if( !pObject ) { continue; } HELIUM_TRACE( TraceLevels::Error, TXT( "- %s\n" ), *pObject->GetPath().ToString() ); } } #endif // !HELIUM_RELEASE sm_objects.Clear(); sm_wpFirstTopLevelObject.Release(); delete sm_pNameInstanceIndexMap; sm_pNameInstanceIndexMap = NULL; delete sm_pEmptyNameInstanceIndexMap; sm_pEmptyNameInstanceIndexMap = NULL; delete sm_pEmptyInstanceIndexSet; sm_pEmptyInstanceIndexSet = NULL; sm_serializationBuffer.Clear(); }