Browse Source

- The asset manager now tracks overall reference counts. The SceneWindow now reports this in the metrics overlay.
- State reset for the particle-system to ensure that animation asset references are freed when the particle is released. The AnimationController needs some further work so completely remove the need to assign an animation-asset to it; rather it should use one assigned from the parent-owner object. This is the typical use-case as an AnimationController would never be used on its own. This would stop the doubling-up of animation of asset references.

MelvMay-GG 12 years ago
parent
commit
dbb8042

+ 23 - 11
engine/source/2d/assets/AnimationController.cc

@@ -32,20 +32,13 @@
 
 //-----------------------------------------------------------------------------
 
-AnimationController::AnimationController() :
-    mCurrentFrameIndex(0),
-    mLastFrameIndex(0),
-    mMaxFrameIndex(0),
-    mCurrentTime(0.0f),
-    mPausedTime(0.0f),
-    mAnimationTimeScale(1.0f),
-    mTotalIntegrationTime(0.0f),
-    mFrameIntegrationTime(0.0f),
-    mAutoRestoreAnimation(false),
-    mAnimationFinished(true)
+AnimationController::AnimationController()
 {
     // Register for animation asset refresh notifications.
     mAnimationAsset.registerRefreshNotify( this );
+
+    // Reset the state.
+    resetState();
 }
 
 //-----------------------------------------------------------------------------
@@ -56,6 +49,25 @@ AnimationController::~AnimationController()
 
 //-----------------------------------------------------------------------------
 
+void AnimationController::resetState( void )
+{
+    mCurrentFrameIndex = 0;
+    mLastFrameIndex = 0;
+    mMaxFrameIndex = 0;
+    mCurrentTime = 0.0f;
+    mPausedTime = 0.0f;
+    mAnimationTimeScale = 1.0f;
+    mTotalIntegrationTime = 0.0f;
+    mFrameIntegrationTime = 0.0f;
+    mAutoRestoreAnimation = false;
+    mAnimationFinished = true;
+
+    mAnimationAsset.clear();
+    mLastAnimationAsset.clear();
+}
+
+//-----------------------------------------------------------------------------
+
 void AnimationController::onAssetRefreshed( AssetPtrBase* pAssetPtrBase )
 {
     // Don't perform any action if the animation is not already playing.

+ 7 - 1
engine/source/2d/assets/AnimationController.h

@@ -35,9 +35,13 @@
 #include "assets/assetPtr.h"
 #endif
 
+#ifndef _FACTORY_CACHE_H_
+#include "memory/factoryCache.h"
+#endif
+
 ///-----------------------------------------------------------------------------
 
-class AnimationController : private AssetPtrCallback
+class AnimationController : public IFactoryObjectReset, private AssetPtrCallback
 {
 private:
     AssetPtr<AnimationAsset>                mAnimationAsset;
@@ -82,6 +86,8 @@ public:
     bool updateAnimation( const F32 elapsedTime );
     void stopAnimation( void );
     void resetTime( void );
+
+    virtual void resetState( void );
 };
 
 

+ 3 - 0
engine/source/2d/core/ParticleSystem.cc

@@ -118,6 +118,9 @@ ParticleSystem::ParticleNode* ParticleSystem::createParticle( void )
 
 void ParticleSystem::freeParticle( ParticleNode* pParticleNode )
 {
+    // Reset the particle.
+    pParticleNode->resetState();
+
     // Remove the previous node reference.
     pParticleNode->mPreviousNode = NULL;
     

+ 6 - 1
engine/source/2d/core/ParticleSystem.h

@@ -33,7 +33,7 @@ class ParticleSystem
 {
 public:
     /// Particle node.
-    struct ParticleNode
+    struct ParticleNode : public IFactoryObjectReset
     {
         /// Particle Node Linkages.
         ParticleNode*           mPreviousNode;
@@ -72,6 +72,11 @@ public:
         Vector2                 mPreTickPosition;
         Vector2                 mPostTickPosition;
         Vector2                 mRenderTickPosition;
+
+        virtual void resetState( void )
+        {
+            mAnimationController.resetState();
+        }
     };
 
 private:

+ 3 - 2
engine/source/2d/gui/SceneWindow.cc

@@ -1868,12 +1868,13 @@ void SceneWindow::renderMetricsOverlay( Point2I offset, const RectI& updateRect
 
         // Asset Manager.
         dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Assets", NULL );
-        dSprintf( mDebugText, sizeof( mDebugText ), "- Declared=%d, Referenced=%d, LoadedInternal=%d<%d>, LoadedExternal=%d<%d>, LoadedPrivate=%d<%d>",
+        dSprintf( mDebugText, sizeof( mDebugText ), "- AcquiredRefs=%d, Declared=%d, Referenced=%d, LoadedInternal=%d<%d>, LoadedExternal=%d<%d>, LoadedPrivate=%d<%d>",
+            AssetDatabase.getAcquiredReferenceCount(),
             AssetDatabase.getDeclaredAssetCount(),
             AssetDatabase.getReferencedAssetCount(),
             AssetDatabase.getLoadedInternalAssetCount(), AssetDatabase.getMaxLoadedInternalAssetCount(),
             AssetDatabase.getLoadedExternalAssetCount(), AssetDatabase.getMaxLoadedExternalAssetCount(),
-            AssetDatabase.getLoadedPrivateAssetCount(), AssetDatabase.getMaxLoadedPrivateAssetCount());
+            AssetDatabase.getLoadedPrivateAssetCount(), AssetDatabase.getMaxLoadedPrivateAssetCount() );
         dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
         linePositionY += linePositionOffsetY;
     }

+ 6 - 1
engine/source/2d/sceneobject/ParticlePlayer.cc

@@ -106,6 +106,8 @@ ParticlePlayer::ParticlePlayer() :
 
 ParticlePlayer::~ParticlePlayer()
 {
+    // Destroy the particle asset.
+    destroyParticleAsset();
 }
 
 //------------------------------------------------------------------------------
@@ -192,6 +194,9 @@ void ParticlePlayer::OnRegisterScene( Scene* pScene )
 
 void ParticlePlayer::OnUnregisterScene( Scene* pScene )
 {
+    // Stop the player.
+    stop( false, false );
+
     // Remove always in scope.
     pScene->getWorldQuery()->removeAlwaysInScope( this );
 
@@ -1290,7 +1295,7 @@ void ParticlePlayer::configureParticle( EmitterNode* pEmitterNode, ParticleSyste
         if ( animationAsset.notNull() )
         {
             // Yes, so play it.
-            pParticleNode->mAnimationController.playAnimation( animationAsset.getAssetId(), false );
+            pParticleNode->mAnimationController.playAnimation( animationAsset, false );
         }
     }
 

+ 3 - 3
engine/source/2d/sceneobject/ParticlePlayer.h

@@ -147,9 +147,6 @@ public:
     virtual void copyTo(SimObject* object);
     virtual void safeDelete( void );
 
-    virtual void OnRegisterScene( Scene* pScene );
-    virtual void OnUnregisterScene( Scene* pScene );
-
     virtual void preIntegrate( const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats );
     void integrateObject( const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats );
     void interpolateObject( const F32 timeDelta );
@@ -194,6 +191,9 @@ public:
     DECLARE_CONOBJECT(ParticlePlayer);
 
 protected:
+    virtual void OnRegisterScene( Scene* pScene );
+    virtual void OnUnregisterScene( Scene* pScene );
+
     /// Particle Creation/Integration.
     void configureParticle( EmitterNode* pEmitterNode, ParticleSystem::ParticleNode* pParticleNode );
     void integrateParticle( EmitterNode* pEmitterNode, ParticleSystem::ParticleNode* pParticleNode, const F32 particleAge, const F32 elapsedTime );

+ 15 - 3
engine/source/assets/assetBase.cc

@@ -250,18 +250,30 @@ void AssetBase::refreshAsset( void )
 
 //-----------------------------------------------------------------------------
 
+void AssetBase::acquireAssetReference( void )
+{
+    // Acquired the acquired reference count.
+    if ( mpOwningAssetManager != NULL )
+        mpOwningAssetManager->acquireAcquiredReferenceCount();
+    
+    mAcquireReferenceCount++;
+}
+
+//-----------------------------------------------------------------------------
+
 bool AssetBase::releaseAssetReference( void )
 {
     // Are there any acquisition references?
     if ( mAcquireReferenceCount == 0 )
     {
-        // No, so warn.
-        Con::warnf( "AssetBase: Cannot release asset reference as there are no current acquisitions." );
-
         // Return "unload" unless auto unload is off.
         return mpAssetDefinition->mAssetAutoUnload;
     }
 
+    // Release the acquired reference count.
+    if ( mpOwningAssetManager != NULL )
+        mpOwningAssetManager->releaseAcquiredReferenceCount(); 
+
     // Release reference.
     mAcquireReferenceCount--;
 

+ 1 - 1
engine/source/assets/assetBase.h

@@ -127,7 +127,7 @@ protected:
     static const char*      getAssetPrivate(void* obj, const char* data)        { return Con::getBoolArg(static_cast<AssetBase*>(obj)->getAssetPrivate()); }
 
 private:
-    inline void             acquireAssetReference( void )                       { mAcquireReferenceCount++; }
+    void                    acquireAssetReference( void );
     bool                    releaseAssetReference( void );
 
     /// Set asset manager ownership.

+ 8 - 41
engine/source/assets/assetManager.cc

@@ -74,6 +74,7 @@ AssetManager::AssetManager() :
     mMaxLoadedInternalAssetsCount( 0 ),
     mMaxLoadedExternalAssetsCount( 0 ),
     mMaxLoadedPrivateAssetsCount( 0 ),
+    mAcquiredReferenceCount( 0 ),
     mEchoInfo( false ),
     mIgnoreAutoUnload( false )
 {
@@ -898,29 +899,6 @@ bool AssetManager::releaseAsset( const char* pAssetId )
     {
         Con::printSeparator();
         Con::printf( "Asset Manager: Started releasing Asset Id '%s'...", pAssetId );
-
-        // Fetch asset Id.
-        StringTableEntry assetId = StringTable->insert( pAssetId );
-
-        // Yes, so find any asset dependencies.
-        typeAssetDependsOnHash::iterator assetDependenciesItr = mAssetDependsOn.find( assetId );
-
-        // Do we have any asset dependencies?
-        if ( assetDependenciesItr != mAssetDependsOn.end() )
-        {
-            // Yes, so show all dependency assets.
-            Con::printf( "Asset Manager: Found dependencies for Asset Id '%s' of:", pAssetId );
-
-            // Iterate all dependencies.
-            while( assetDependenciesItr != mAssetDependsOn.end() && assetDependenciesItr->key == assetId )
-            {
-                // Info.
-                Con::printf( "Asset Manager: > Asset Id '%s'", assetDependenciesItr->value );
-
-                // Next dependency.
-                assetDependenciesItr++;
-            }
-        }
     }
 
     // Release asset reference.
@@ -932,9 +910,7 @@ bool AssetManager::releaseAsset( const char* pAssetId )
             // Yes, so info.
             if ( mEchoInfo )
             {
-                Con::printf( "Asset Manager: Asset Id '%s' now has a reference count of '0' but ignoring auto-unloading of assets.",
-                    pAssetId,
-                    pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() );
+                Con::printf( "Asset Manager: > Releasing to idle state." );
             }
         }
         else
@@ -942,7 +918,7 @@ bool AssetManager::releaseAsset( const char* pAssetId )
             // No, so info.
             if ( mEchoInfo )
             {
-                Con::printf( "Asset Manager: Asset Id '%s' is being unloaded.", pAssetId );
+                Con::printf( "Asset Manager: > Unload the asset from memory." );
             }
 
             // Unload the asset.
@@ -952,24 +928,14 @@ bool AssetManager::releaseAsset( const char* pAssetId )
     // Info.
     else if ( mEchoInfo )
     {
-        if ( pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() > 0 )
-        {
-            Con::printf( "Asset Manager: Asset Id '%s' now has a reference count of '%d'.",
-                pAssetId,
-                pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() );
-        }
-        else
-        {
-            Con::printf( "Asset Manager: Asset Id '%s' now has a reference count of '0' but set to not auto-unload.",
-                pAssetId,
-                pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() );
-        }
+        Con::printf( "Asset Manager: > Reference count now '%d'.", pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() );
     }
 
     // Info.
     if ( mEchoInfo )
     {
-        Con::printf( "Asset Manager: ... Finished releasing Asset Id '%s'.", pAssetId );
+        Con::printf( "Asset Manager: > Finished releasing Asset Id '%s'.", pAssetId );
+        Con::printSeparator();
     }
 
     return true;
@@ -1690,8 +1656,9 @@ void AssetManager::dumpDeclaredAssets( void ) const
         const AssetDefinition* pAssetDefinition = *assetItr;
 
         // Info.
-        Con::printf( "AssetId:'%s', LoadCount:%d, UnloadCount:%d, AutoUnload:%d, Loaded:%d, Internal:%d, Private: %d, Type:'%s', Module/Version:'%s'/'%d', File:'%s'",
+        Con::printf( "AssetId:'%s', RefCount:%d, LoadCount:%d, UnloadCount:%d, AutoUnload:%d, Loaded:%d, Internal:%d, Private: %d, Type:'%s', Module/Version:'%s'/'%d', File:'%s'",
             pAssetDefinition->mAssetId,
+            pAssetDefinition->mpAssetBase == NULL ? 0 : pAssetDefinition->mpAssetBase->getAcquiredReferenceCount(),
             pAssetDefinition->mAssetLoadedCount,
             pAssetDefinition->mAssetUnloadedCount,
             pAssetDefinition->mAssetAutoUnload,

+ 26 - 11
engine/source/assets/assetManager.h

@@ -109,6 +109,7 @@ private:
     U32                                 mLoadedInternalAssetsCount;
     U32                                 mLoadedExternalAssetsCount;
     U32                                 mLoadedPrivateAssetsCount;
+    U32                                 mAcquiredReferenceCount;
     U32                                 mMaxLoadedInternalAssetsCount;
     U32                                 mMaxLoadedExternalAssetsCount;
     U32                                 mMaxLoadedPrivateAssetsCount;
@@ -191,12 +192,12 @@ public:
         // Is the asset already loaded?
         if ( pAssetDefinition->mpAssetBase == NULL )
         {
-            // No, so fetch asset Id.
-            StringTableEntry assetId = StringTable->insert( pAssetId );
-
-            // Info.
+            // No, so info
             if ( mEchoInfo )
             {
+                // Fetch asset Id.
+                StringTableEntry assetId = StringTable->insert( pAssetId );
+
                 // Find any asset dependencies.
                 typeAssetDependsOnHash::iterator assetDependenciesItr = mAssetDependsOn.find( assetId );
 
@@ -204,7 +205,7 @@ public:
                 if ( assetDependenciesItr != mAssetDependsOn.end() )
                 {
                     // Yes, so show all dependency assets.
-                    Con::printf( "Asset Manager: Found dependencies for Asset Id '%s' of:", pAssetId );
+                    Con::printf( "Asset Manager: > Found dependencies:" );
 
                     // Iterate all dependencies.
                     while( assetDependenciesItr != mAssetDependsOn.end() && assetDependenciesItr->key == assetId )
@@ -231,7 +232,8 @@ public:
             if ( pAssetDefinition->mpAssetBase == NULL )
             {
                 // No, so warn.
-                Con::warnf( "Asset Manager: Failed to acquire asset Id '%s' as loading the asset file failed to return the asset or the correct asset type: '%s'.", pAssetId, pAssetDefinition->mAssetBaseFilePath );
+                Con::warnf( "Asset Manager: > Failed to acquire asset Id '%s' as loading the asset file failed to return the asset or the correct asset type: '%s'.",
+                    pAssetId, pAssetDefinition->mAssetBaseFilePath );
                 return NULL;
             }
 
@@ -241,8 +243,8 @@ public:
             // Info.
             if ( mEchoInfo )
             {
-                Con::printf( "Asset Manager: Acquiring Asset Id '%s' resulted in asset object Id '%d' being loaded from file '%s'.",
-                    pAssetId, pAssetDefinition->mpAssetBase->getId(), pAssetDefinition->mAssetBaseFilePath );
+                Con::printf( "Asset Manager: > Loading asset into memory as object Id '%d' from file '%s'.",
+                    pAssetDefinition->mpAssetBase->getId(), pAssetDefinition->mAssetBaseFilePath );
             }
 
             // Set ownership by asset manager.
@@ -262,6 +264,14 @@ public:
                     mMaxLoadedExternalAssetsCount = mLoadedExternalAssetsCount;
             }
         }
+        else if ( pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() == 0 )
+        {
+            // Info.
+            if ( mEchoInfo )
+            {
+                Con::printf( "Asset Manager: > Acquiring from idle state." );
+            }
+        }
 
         // Set acquired asset.
         T* pAcquiredAsset = dynamic_cast<T*>( (AssetBase*)pAssetDefinition->mpAssetBase );
@@ -270,7 +280,7 @@ public:
         if ( pAcquiredAsset == NULL )
         {
             // No, so warn.
-            Con::warnf( "Asset Manager: Failed to acquire asset Id '%s' as it was not of the specified asset type: '%s'.", pAssetId, pAssetDefinition->mAssetBaseFilePath );
+            Con::warnf( "Asset Manager: > Failed to acquire asset Id '%s' as it was not the required asset type: '%s'.", pAssetId, pAssetDefinition->mAssetBaseFilePath );
             return NULL;
         }
 
@@ -280,7 +290,7 @@ public:
         // Info.
         if ( mEchoInfo )
         {
-            Con::printf( "Asset Manager: ... Finished acquiring Asset Id '%s' (Ref Count '%d').", pAssetId, pAcquiredAsset->getAcquiredReferenceCount() );
+            Con::printf( "Asset Manager: > Finished acquiring asset.  Reference count now '%d'.", pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() );
             Con::printSeparator();
         }
 
@@ -319,7 +329,12 @@ public:
     inline U32 getMaxLoadedExternalAssetCount( void ) const { return mMaxLoadedExternalAssetsCount; }
     inline U32 getMaxLoadedPrivateAssetCount( void ) const { return mMaxLoadedPrivateAssetsCount; }
     void dumpDeclaredAssets( void ) const;
-    
+
+    /// Total acquired asset references.
+    inline void acquireAcquiredReferenceCount( void ) { mAcquiredReferenceCount++; }
+    inline void releaseAcquiredReferenceCount( void ) { AssertFatal( mAcquiredReferenceCount != 0, "AssetManager: Invalid acquired reference count." ); mAcquiredReferenceCount--; }
+    inline U32 getAcquiredReferenceCount( void ) const { return mAcquiredReferenceCount; }
+
     /// Asset queries.
     S32 findAllAssets( AssetQuery* pAssetQuery, const bool ignoreInternal = true, const bool ignorePrivate = true );
     S32 findAssetName( AssetQuery* pAssetQuery, const char* pAssetName, const bool partialName = false );

+ 2 - 2
engine/source/assets/assetPtr.h

@@ -45,7 +45,7 @@ public:
     AssetPtrBase() {};
     virtual ~AssetPtrBase()
     {
-        // Unregister any notifications.
+        // Un-register any notifications.
         unregisterRefreshNotify();
     };
 
@@ -72,7 +72,7 @@ public:
 
     void unregisterRefreshNotify( void )
     {
-        // Unregister the refresh notify if the asset system is available.
+        // Un-register the refresh notify if the asset system is available.
         if ( AssetDatabase.isProperlyAdded() )
             AssetDatabase.unregisterAssetPtrRefreshNotify( this );
     }