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;
}
Example #2
0
/// 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();
}