Browse Source

- Added the ability to specify assets to preload on a Scene.

MelvMay-GG 12 years ago
parent
commit
274ccf6

+ 182 - 8
engine/source/2d/scene/Scene.cc

@@ -144,6 +144,9 @@ static StringTableEntry jointMotorCorrectionFactorName;
 
 static StringTableEntry controllerCustomNodeName;
 
+static StringTableEntry assetPreloadNodeName;
+static StringTableEntry assetNodeName;
+
 //-----------------------------------------------------------------------------
 
 Scene::Scene() :
@@ -176,7 +179,7 @@ Scene::Scene() :
     // Initialize Taml property names.
     if ( !tamlPropertiesInitialized )
     {
-        jointCustomNodeName           = StringTable->insert( "Joints" );
+        jointCustomNodeName               = StringTable->insert( "Joints" );
         jointCollideConnectedName         = StringTable->insert( "CollideConnected" );
         jointLocalAnchorAName             = StringTable->insert( "LocalAnchorA" );
         jointLocalAnchorBName             = StringTable->insert( "LocalAnchorB" );
@@ -239,6 +242,9 @@ Scene::Scene() :
 
         controllerCustomNodeName	      = StringTable->insert( "Controllers" );
 
+        assetPreloadNodeName              = StringTable->insert( "AssetPreloads" );
+        assetNodeName                     = StringTable->insert( "Asset" );
+
         // Flag as initialized.
         tamlPropertiesInitialized = true;
     }
@@ -248,7 +254,8 @@ Scene::Scene() :
     VECTOR_SET_ASSOCIATION( mDeleteRequests );
     VECTOR_SET_ASSOCIATION( mDeleteRequestsTemp );
     VECTOR_SET_ASSOCIATION( mEndContacts );
-      
+    VECTOR_SET_ASSOCIATION( mAssetPreloads );
+     
     // Initialize layer sort mode.
     for ( U32 n = 0; n < MAX_LAYERS_SUPPORTED; ++n )
        mLayerSortModes[n] = SceneRenderQueue::RENDER_SORT_NEWEST;
@@ -270,7 +277,8 @@ Scene::Scene() :
 Scene::~Scene()
 {
     // Unregister the scene controllers set.
-    mControllers->deleteObject();
+    if ( mControllers.notNull() )
+        mControllers->deleteObject();
 
     // Decrease scene count.
     --sSceneCount;
@@ -1361,12 +1369,15 @@ void Scene::clearScene( bool deleteObjects )
     SimSet* pControllerSet = getControllers();
 
     // Do we have any scene controllers?
-    if ( pControllerSet == NULL )
-        return;
+    if ( pControllerSet != NULL )
+    {
+        // Yes, so delete them all.
+        while( pControllerSet->size() > 0 )
+            pControllerSet->at(0)->deleteObject();
+    }
 
-    // Delete all the scene controllers.
-    while( pControllerSet->size() > 0 )
-        pControllerSet->at(0)->deleteObject();
+    // Clear asset preloads.
+    clearAssetPreloads();
 }
 
 //-----------------------------------------------------------------------------
@@ -1520,6 +1531,92 @@ U32 Scene::getSceneObjects( typeSceneObjectVector& objects, const U32 sceneLayer
 
 //-----------------------------------------------------------------------------
 
+const AssetPtr<AssetBase>* Scene::getAssetPreload( const S32 index ) const
+{
+    // Is the index valid?
+    if ( index < 0 || index >= mAssetPreloads.size() )
+    {
+        // Yes, so warn.
+        Con::warnf( "Scene::getAssetPreload() - Out of range index '%d'.  There are only '%d' asset preloads.", index, mAssetPreloads.size() );
+        return NULL;
+    }
+
+    return mAssetPreloads[index];
+}
+
+//-----------------------------------------------------------------------------
+
+void Scene::addAssetPreload( const char* pAssetId )
+{
+    // Sanity!
+    AssertFatal( pAssetId != NULL, "Scene::addAssetPreload() - Cannot add a NULL asset preload." );
+
+    // Fetch asset Id.
+    StringTableEntry assetId = StringTable->insert( pAssetId );
+
+    // Ignore if asset already added.
+    const S32 assetPreloadCount = mAssetPreloads.size();
+    for( S32 index = 0; index < assetPreloadCount; ++index )
+    {
+        if ( mAssetPreloads[index]->getAssetId() == assetId )
+            return;
+    }
+
+    // Create asset pointer.
+    AssetPtr<AssetBase>* pAssetPtr = new AssetPtr<AssetBase>( pAssetId );
+
+    // Was the asset acquired?
+    if ( pAssetPtr->isNull() )
+    {
+        // No, so warn.
+        Con::warnf( "Scene::addAssetPreload() - Failed to acquire asset '%s' so not added as a preload.", pAssetId );
+
+        // No, so delete the asset pointer.
+        delete pAssetPtr;
+        return;
+    }
+
+    // Add asset.
+    mAssetPreloads.push_back( pAssetPtr );
+}
+
+//-----------------------------------------------------------------------------
+
+void Scene::removeAssetPreload( const char* pAssetId )
+{
+    // Sanity!
+    AssertFatal( pAssetId != NULL, "Scene::removeAssetPreload() - Cannot remove a NULL asset preload." );
+
+    // Fetch asset Id.
+    StringTableEntry assetId = StringTable->insert( pAssetId );
+
+    // Remove asset Id.
+    const S32 assetPreloadCount = mAssetPreloads.size();
+    for( S32 index = 0; index < assetPreloadCount; ++index )
+    {
+        if ( mAssetPreloads[index]->getAssetId() == assetId )
+        {
+            delete mAssetPreloads[index];
+            mAssetPreloads.erase_fast( index );
+            return;
+        }
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+void Scene::clearAssetPreloads( void )
+{
+    // Delete all the asset preloads.
+    while( mAssetPreloads.size() > 0 )
+    {
+        delete mAssetPreloads.back();
+        mAssetPreloads.pop_back();
+    }
+}
+
+//-----------------------------------------------------------------------------
+
 void Scene::mergeScene( const Scene* pScene )
 {
     // Fetch the scene object count.
@@ -4583,6 +4680,56 @@ void Scene::onTamlPostRead( const TamlCustomNodes& customNodes )
             pControllerSet->addObject( pProxyObject );
         }
     }
+
+    // Find asset preload custom node.
+    const TamlCustomNode* pAssetPreloadNode = customNodes.findNode( assetPreloadNodeName );
+
+    // Do we have any asset preloads?
+    if ( pAssetPreloadNode != NULL )
+    {
+        // Yes, so clear any existing asset preloads.
+        clearAssetPreloads();
+
+        // Yes, so fetch asset Id type prefix.
+        StringTableEntry assetIdTypePrefix = ConsoleBaseType::getType( TypeAssetId )->getTypePrefix();
+
+        // Fetch the prefix length.
+        const S32 assetIdPrefixLength = dStrlen( assetIdTypePrefix );
+
+        // Fetch the preload children nodes.
+        const TamlCustomNodeVector& preloadChildren = pAssetPreloadNode->getChildren();
+
+        // Iterate asset preloads.
+        for( TamlCustomNodeVector::const_iterator assetPreloadNodeItr = preloadChildren.begin(); assetPreloadNodeItr != preloadChildren.end(); ++assetPreloadNodeItr )
+        {
+            // Fetch asset node.
+            const TamlCustomNode* pAssetNode = *assetPreloadNodeItr;
+
+            // Ignore non-asset nodes.
+            if ( pAssetNode->getNodeName() != assetNodeName )
+                continue;
+
+            // Find the asset Id field.
+            const TamlCustomField* pAssetIdField = pAssetNode->findField( "Id" );
+
+            // Did we find the field?
+            if ( pAssetIdField == NULL )
+            {
+                // No, so warn.
+                Con::warnf("Scene::onTamlPostRead() - Found asset preload but failed to find asset Id field." );
+                continue;
+            }
+
+            // Fetch field value.
+            const char* pFieldValue = pAssetIdField->getFieldValue();
+
+            // Calculate the field value start (skip any type prefix).
+            const S32 prefixOffset = dStrnicmp( pFieldValue, assetIdTypePrefix, assetIdPrefixLength ) == 0 ? assetIdPrefixLength : 0;
+
+            // Add asset preload.
+            addAssetPreload( pFieldValue + prefixOffset );
+        }
+    }   
 }
 
 //-----------------------------------------------------------------------------
@@ -5033,6 +5180,32 @@ void Scene::onTamlCustomWrite( TamlCustomNodes& customNodes )
             pControllerCustomNode->addNode( pSetObject );
         }
     }
+
+    // Fetch asset preload count.
+    const S32 assetPreloadCount = getAssetPreloadCount();
+
+    // Do we have any asset preloads?
+    if ( assetPreloadCount > 0 )
+    {
+        // Yes, so fetch asset Id type prefix.
+        StringTableEntry assetIdTypePrefix = ConsoleBaseType::getType( TypeAssetId )->getTypePrefix();
+
+        // Add asset preload node.
+        TamlCustomNode* pAssetPreloadCustomNode = customNodes.addNode( assetPreloadNodeName );
+
+        // Iterate asset preloads.
+        for( typeAssetPtrVector::const_iterator assetItr = mAssetPreloads.begin(); assetItr != mAssetPreloads.end(); ++assetItr )
+        {
+            // Add node.
+            TamlCustomNode* pAssetNode = pAssetPreloadCustomNode->addNode( assetNodeName );
+
+            char valueBuffer[1024];
+            dSprintf( valueBuffer, sizeof(valueBuffer), "%s%s", assetIdTypePrefix, (*assetItr)->getAssetId() );
+
+            // Add asset Id.
+            pAssetNode->addField( "Id", valueBuffer );
+        }        
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -5251,3 +5424,4 @@ const char* Scene::getPickModeDescription( Scene::PickMode pickMode )
 
     return StringTable->EmptyString;
 }
+

+ 14 - 0
engine/source/2d/scene/Scene.h

@@ -71,6 +71,10 @@
 #include "component/behaviors/behaviorComponent.h"
 #endif
 
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif
+
 //-----------------------------------------------------------------------------
 
 extern EnumTable jointTypeTable;
@@ -167,6 +171,7 @@ public:
     typedef Vector<tDeleteRequest>              typeDeleteVector;
     typedef Vector<TickContact>                 typeContactVector;
     typedef HashMap<b2Contact*, TickContact>    typeContactHash;
+    typedef Vector<AssetPtr<AssetBase>*>        typeAssetPtrVector;
 
     /// Scene Debug Options.
     enum DebugOption
@@ -224,6 +229,9 @@ private:
     /// Scene controllers.
     SimObjectPtr<SimSet>	    mControllers;
 
+    /// Asset pre-loads.
+    typeAssetPtrVector          mAssetPreloads;
+
     /// Scene time.
     F32                         mSceneTime;
     bool                        mScenePause;
@@ -345,6 +353,12 @@ public:
 
     inline SimSet*			getControllers( void )						{ return mControllers; }
 
+    inline S32              getAssetPreloadCount( void ) const          { return mAssetPreloads.size(); }
+    const AssetPtr<AssetBase>* getAssetPreload( const S32 index ) const;
+    void                    addAssetPreload( const char* pAssetId );
+    void                    removeAssetPreload( const char* pAssetId );
+    void                    clearAssetPreloads( void );
+
     /// Scene time.
     inline F32              getSceneTime( void ) const                  { return mSceneTime; };
     inline void             setScenePause( bool status )                { mScenePause = status; }

+ 60 - 0
engine/source/2d/scene/Scene_ScriptBinding.h

@@ -250,6 +250,66 @@ ConsoleMethod(Scene, getSceneObjectList, const char*, 2, 2, "() Gets the Scene O
 
 //-----------------------------------------------------------------------------
 
+ConsoleMethod(Scene, getAssetPreloadCount, S32, 2, 2,   "() Gets the number of assets set to preload for this scene.\n"
+                                                        "@return The number of assets set to preload for this scene.")
+{
+    return object->getAssetPreloadCount();
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(Scene, getAssetPreload, const char*, 3, 3,    "(index) Gets the asset to be preloaded at the specified index.\n"
+                                                            "@param index The index of the preloaded asset.\n"
+                                                            "@return The asset to be preloaded at the specified index.")
+{
+    // Fetch preload index.
+    const S32 index = dAtoi(argv[2]);
+
+    // Fetch the asset pointer.
+    const AssetPtr<AssetBase>* pAssetPtr = object->getAssetPreload( index );
+
+    return pAssetPtr == NULL ? NULL : pAssetPtr->getAssetId();
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(Scene, addAssetPreload, void, 3, 3,   "(assetId) Adds the asset Id so that it is preloaded when the scene is loaded.\n"
+                                                    "The asset loaded immediately by this operation.  Duplicate assets are ignored.\n"
+                                                    "@param assetId The asset Id to be added.\n"
+                                                    "@return No return value.")
+{
+    // Fetch asset Id.
+    const char* pAssetId = argv[2];
+
+    // Add asset preload.
+    object->addAssetPreload( pAssetId );
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(Scene, removeAssetPreload, void, 3, 3,    "(assetId) Removes the asset Id from being preloaded when the scene is loaded.\n"
+                                                        "The asset may be unloaded immediately by this operation if it has no other references.\n"
+                                                        "@param assetId The asset Id to be removed.\n"
+                                                        "@return No return value.")
+{
+    // Fetch asset Id.
+    const char* pAssetId = argv[2];
+
+    // Remove asset preload.
+    object->removeAssetPreload( pAssetId );
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(Scene, clearAssetPreloads, void, 2, 2,    "() Clears all assets added as a preload.\n"
+                                                        "@return No return value.")
+{
+    // Clear asset preloads.
+    object->clearAssetPreloads();
+}
+
+//-----------------------------------------------------------------------------
+
 ConsoleMethod(Scene, mergeScene, void, 3, 3,    "(scene) Merges the specified scene into this scene by cloning the scenes contents.")
 {
     // Find the specified scene.