assetManager.h

Engine/source/assets/assetManager.h

More...

Classes:

Public Variables

Detailed Description

Public Variables

AssetManager AssetDatabase 
  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2013 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _ASSET_MANAGER_H_
 25#define _ASSET_MANAGER_H_
 26
 27#ifndef _SIMBASE_H_
 28#include "console/sim.h"
 29#endif
 30
 31#ifndef _TAML_H_
 32#include "persistence/taml/taml.h"
 33#endif
 34
 35#ifndef _MODULE_DEFINITION_H
 36#include "module/moduleDefinition.h"
 37#endif
 38
 39#ifndef _MODULE_CALLBACKS_H_
 40#include "module/moduleCallbacks.h"
 41#endif
 42
 43#ifndef _ASSET_BASE_H_
 44#include "assets/assetBase.h"
 45#endif
 46
 47#ifndef _ASSET_DEFINITION_H_
 48#include "assets/assetDefinition.h"
 49#endif
 50
 51#ifndef _ASSET_TAGS_MANIFEST_H_
 52#include "assets/assetTagsManifest.h"
 53#endif
 54
 55#ifndef _ASSET_QUERY_H_
 56#include "assets/assetQuery.h"
 57#endif
 58
 59#ifndef _ASSET_FIELD_TYPES_H_
 60#include "assets/assetFieldTypes.h"
 61#endif
 62
 63// Debug Profiling.
 64#include "platform/profiler.h"
 65
 66//-----------------------------------------------------------------------------
 67
 68class AssetPtrCallback;
 69class AssetPtrBase;
 70
 71//-----------------------------------------------------------------------------
 72
 73class AssetManager : public SimObject, public ModuleCallbacks
 74{
 75private:
 76    typedef SimObject Parent;
 77    typedef StringTableEntry typeAssetId;
 78    typedef StringTableEntry typeAssetName;
 79    typedef StringTableEntry typeReferenceFilePath;
 80    typedef HashMap<typeAssetId, AssetDefinition*> typeDeclaredAssetsHash;
 81    typedef HashTable<typeAssetId, typeReferenceFilePath> typeReferencedAssetsHash;
 82    typedef HashTable<typeAssetId, typeAssetId> typeAssetDependsOnHash;
 83    typedef HashTable<typeAssetId, typeAssetId> typeAssetIsDependedOnHash;
 84    typedef HashMap<AssetPtrBase*, AssetPtrCallback*> typeAssetPtrRefreshHash;
 85
 86    /// Declared assets.
 87    typeDeclaredAssetsHash              mDeclaredAssets;
 88
 89    /// Referenced assets.
 90    typeReferencedAssetsHash            mReferencedAssets;
 91
 92    /// Asset dependencies.
 93    typeAssetDependsOnHash              mAssetDependsOn;
 94    typeAssetIsDependedOnHash           mAssetIsDependedOn;
 95
 96    /// Asset tags.
 97    SimObjectPtr<AssetTagsManifest>     mAssetTagsManifest;
 98    SimObjectPtr<ModuleDefinition>      mAssetTagsModuleDefinition;
 99
100    /// Asset pointer refresh notifications.
101    typeAssetPtrRefreshHash             mAssetPtrRefreshNotifications;
102
103    /// Miscellaneous.
104    bool                                mEchoInfo;
105    bool                                mIgnoreAutoUnload;
106    U32                                 mLoadedInternalAssetsCount;
107    U32                                 mLoadedExternalAssetsCount;
108    U32                                 mLoadedPrivateAssetsCount;
109    U32                                 mAcquiredReferenceCount;
110    U32                                 mMaxLoadedInternalAssetsCount;
111    U32                                 mMaxLoadedExternalAssetsCount;
112    U32                                 mMaxLoadedPrivateAssetsCount;
113    Taml                                mTaml;
114
115public:
116    AssetManager();
117    virtual ~AssetManager() {}
118
119    /// SimObject overrides
120    virtual bool onAdd();
121    virtual void onRemove();
122    static void initPersistFields();
123
124    /// Declared assets.
125    bool addModuleDeclaredAssets( ModuleDefinition* pModuleDefinition );
126    bool addDeclaredAsset( ModuleDefinition* pModuleDefinition, const char* pAssetFilePath );
127    StringTableEntry addPrivateAsset( AssetBase* pAssetBase );
128    bool removeDeclaredAssets( ModuleDefinition* pModuleDefinition );
129    bool removeDeclaredAsset( const char* pAssetId );
130    bool renameDeclaredAsset( const char* pAssetIdFrom, const char* pAssetIdTo );
131    StringTableEntry getAssetName( const char* pAssetId );
132    StringTableEntry getAssetDescription( const char* pAssetId );
133    StringTableEntry getAssetCategory( const char* pAssetId );
134    StringTableEntry getAssetType( const char* pAssetId );
135    StringTableEntry getAssetFilePath( const char* pAssetId );
136    StringTableEntry getAssetPath( const char* pAssetId );
137    ModuleDefinition* getAssetModuleDefinition( const char* pAssetId );
138    bool isAssetInternal( const char* pAssetId );
139    bool isAssetPrivate( const char* pAssetId );
140    bool isAssetAutoUnload( const char* pAssetId );
141    bool isAssetLoaded( const char* pAssetId );
142    bool isDeclaredAsset( const char* pAssetId );
143    bool doesAssetDependOn( const char* pAssetId, const char* pDependsOnAssetId );
144    bool isAssetDependedOn( const char* pAssetId, const char* pDependedOnByAssetId );
145
146    /// Referenced assets.
147    bool compileReferencedAssets( ModuleDefinition* pModuleDefinition );
148    bool isReferencedAsset( const char* pAssetId );
149    bool renameReferencedAsset( const char* pAssetIdFrom, const char* pAssetIdTo );
150
151    /// Public asset acquisition.
152    template<typename T> T* acquireAsset( const char* pAssetId )
153    {
154        // Sanity!
155        AssertFatal( pAssetId != NULL, "Cannot acquire NULL asset Id." );
156
157        // Is this an empty asset Id?
158        if ( *pAssetId == 0 )
159        {
160            // Yes, so return nothing.
161            return NULL;
162        }
163
164        // Find asset.
165        AssetDefinition* pAssetDefinition = findAsset( pAssetId );
166
167        // Did we find the asset?
168        if ( pAssetDefinition == NULL )
169        {
170            // No, so warn.
171            Con::warnf( "Asset Manager: Failed to acquire asset Id '%s' as it does not exist.", pAssetId );
172            return NULL;
173        }
174
175        // Is asset loading?
176        if ( pAssetDefinition->mAssetLoading == true )
177        {
178            // Yes, so we've got a circular loop which we cannot resolve!
179            Con::warnf( "Asset Manager: Failed to acquire asset Id '%s' as loading it involves a cyclic dependency on itself which cannot be resolved.", pAssetId );
180            return NULL;
181        }
182
183        // Info.
184        if ( mEchoInfo )
185        {
186            Con::printSeparator();
187            Con::printf( "Asset Manager: Started acquiring Asset Id '%s'...", pAssetId );
188        }
189
190        // Is the asset already loaded?
191        if ( pAssetDefinition->mpAssetBase == NULL )
192        {
193            // No, so info
194            if ( mEchoInfo )
195            {
196                // Fetch asset Id.
197                StringTableEntry assetId = StringTable->insert( pAssetId );
198
199                // Find any asset dependencies.
200                typeAssetDependsOnHash::Iterator assetDependenciesItr = mAssetDependsOn.find( assetId );
201
202                // Does the asset have any dependencies?
203                if ( assetDependenciesItr != mAssetDependsOn.end() )
204                {
205                    // Yes, so show all dependency assets.
206                    Con::printf( "Asset Manager: > Found dependencies:" );
207
208                    // Iterate all dependencies.
209                    while( assetDependenciesItr != mAssetDependsOn.end() && assetDependenciesItr->key == assetId )
210                    {
211                        // Info.
212                        Con::printf( "Asset Manager: > Asset Id '%s'", assetDependenciesItr->value );
213
214                        // Next dependency.
215                        assetDependenciesItr++;
216                    }
217                }
218            }
219
220            // Flag asset as loading.
221            pAssetDefinition->mAssetLoading = true;
222
223            // Generate primary asset.
224            pAssetDefinition->mpAssetBase = mTaml.read<T>( pAssetDefinition->mAssetBaseFilePath );
225
226            // Flag asset as finished loading.
227            pAssetDefinition->mAssetLoading = false;
228
229            // Did we generate the asset?
230            if ( pAssetDefinition->mpAssetBase == NULL )
231            {
232                // No, so warn.
233                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'.",
234                    pAssetId, pAssetDefinition->mAssetBaseFilePath );
235                return NULL;
236            }
237
238            // Increase loaded count.
239            pAssetDefinition->mAssetLoadedCount++;
240
241            // Info.
242            if ( mEchoInfo )
243            {
244                Con::printf( "Asset Manager: > Loading asset into memory as object Id '%d' from file '%s'.",
245                    pAssetDefinition->mpAssetBase->getId(), pAssetDefinition->mAssetBaseFilePath );
246            }
247
248            // Set ownership by asset manager.
249            pAssetDefinition->mpAssetBase->setOwned( this, pAssetDefinition );
250
251            // Is the asset internal?
252            if ( pAssetDefinition->mAssetInternal )
253            {
254                // Yes, so increase internal loaded asset count.
255                if ( ++mLoadedInternalAssetsCount > mMaxLoadedInternalAssetsCount )
256                    mMaxLoadedInternalAssetsCount = mLoadedInternalAssetsCount;
257            }
258            else
259            {
260                // No, so increase external loaded assets count.
261                if ( ++mLoadedExternalAssetsCount > mMaxLoadedExternalAssetsCount )
262                    mMaxLoadedExternalAssetsCount = mLoadedExternalAssetsCount;
263            }
264        }
265        else if ( pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() == 0 )
266        {
267            // Info.
268            if ( mEchoInfo )
269            {
270                Con::printf( "Asset Manager: > Acquiring from idle state." );
271            }
272        }
273
274        // Set acquired asset.
275        T* pAcquiredAsset = dynamic_cast<T*>( (AssetBase*)pAssetDefinition->mpAssetBase );
276
277        // Is asset the correct type?
278        if ( pAcquiredAsset == NULL )
279        {
280            // No, so warn.
281            Con::warnf( "Asset Manager: > Failed to acquire asset Id '%s' as it was not the required asset type: '%s'.", pAssetId, pAssetDefinition->mAssetBaseFilePath );
282            return NULL;
283        }
284
285        // Acquire asset reference.
286        pAcquiredAsset->acquireAssetReference();
287
288        // Info.
289        if ( mEchoInfo )
290        {
291            Con::printf( "Asset Manager: > Finished acquiring asset.  Reference count now '%d'.", pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() );
292            Con::printSeparator();
293        }
294
295        return pAcquiredAsset;
296    }
297
298    /// Private asset acquisition.
299    template<typename T> T* acquireAsPrivateAsset( const char* pAssetId )
300    {
301        // Acquire the asset normally.
302        T* pAsset = acquireAsset<T>( pAssetId );
303
304        // Finish if the asset was not acquired.
305        if ( pAsset == NULL )
306            return NULL;
307
308        // Clone the asset.
309        T* pAssetClone = dynamic_cast<T*>( pAsset->clone() );
310
311        // Sanity!
312        AssertFatal( pAssetClone != NULL, "acquireAsPrivateAsset() - Failed to clone asset type." );
313
314        // Release the public asset.
315        releaseAsset( pAssetId );
316
317        // Add as a private asset.
318        addPrivateAsset( pAssetClone );
319
320        return pAssetClone;
321    }
322
323    bool releaseAsset( const char* pAssetId );
324    void purgeAssets( void );
325
326    /// Asset deletion.
327    bool deleteAsset( const char* pAssetId, const bool deleteLooseFiles, const bool deleteDependencies );
328
329    // Asset refresh notification.
330    bool refreshAsset( const char* pAssetId );
331    void refreshAllAssets( const bool includeUnloaded = false );
332    void registerAssetPtrRefreshNotify( AssetPtrBase* pAssetPtrBase, AssetPtrCallback* pCallback );
333    void unregisterAssetPtrRefreshNotify( AssetPtrBase* pAssetPtrBase );
334
335    /// Asset tags.
336    bool loadAssetTags( ModuleDefinition* pModuleDefinition );
337    bool saveAssetTags( void );
338    bool restoreAssetTags( void );
339    inline AssetTagsManifest* getAssetTags( void ) const { return mAssetTagsManifest; }
340
341    /// Info.
342    inline U32 getDeclaredAssetCount( void ) const { return (U32)mDeclaredAssets.size(); }
343    inline U32 getReferencedAssetCount( void ) const { return (U32)mReferencedAssets.size(); }
344    inline U32 getLoadedInternalAssetCount( void ) const { return mLoadedInternalAssetsCount; }
345    inline U32 getLoadedExternalAssetCount( void ) const { return mLoadedExternalAssetsCount; }
346    inline U32 getLoadedPrivateAssetCount( void ) const { return mLoadedPrivateAssetsCount; }
347    inline U32 getMaxLoadedInternalAssetCount( void ) const { return mMaxLoadedInternalAssetsCount; }
348    inline U32 getMaxLoadedExternalAssetCount( void ) const { return mMaxLoadedExternalAssetsCount; }
349    inline U32 getMaxLoadedPrivateAssetCount( void ) const { return mMaxLoadedPrivateAssetsCount; }
350    void dumpDeclaredAssets( void ) const;
351
352    /// Total acquired asset references.
353    inline void acquireAcquiredReferenceCount( void ) { mAcquiredReferenceCount++; }
354    inline void releaseAcquiredReferenceCount( void ) { AssertFatal( mAcquiredReferenceCount != 0, "AssetManager: Invalid acquired reference count." ); mAcquiredReferenceCount--; }
355    inline U32 getAcquiredReferenceCount( void ) const { return mAcquiredReferenceCount; }
356
357    /// Asset queries.
358    S32 findAllAssets( AssetQuery* pAssetQuery, const bool ignoreInternal = true, const bool ignorePrivate = true );
359    S32 findAssetName( AssetQuery* pAssetQuery, const char* pAssetName, const bool partialName = false );
360    S32 findAssetCategory( AssetQuery* pAssetQuery, const char* pAssetCategory, const bool assetQueryAsSource = false );
361    S32 findAssetAutoUnload( AssetQuery* pAssetQuery, const bool assetAutoUnload, const bool assetQueryAsSource = false );
362    S32 findAssetInternal( AssetQuery* pAssetQuery, const bool assetInternal, const bool assetQueryAsSource = false );
363    S32 findAssetPrivate( AssetQuery* pAssetQuery, const bool assetPrivate, const bool assetQueryAsSource = false );
364    S32 findAssetType( AssetQuery* pAssetQuery, const char* pAssetType, const bool assetQueryAsSource = false );
365    S32 findAssetDependsOn( AssetQuery* pAssetQuery, const char* pAssetId );
366    S32 findAssetIsDependedOn( AssetQuery* pAssetQuery, const char* pAssetId );
367    S32 findInvalidAssetReferences( AssetQuery* pAssetQuery );
368    S32 findTaggedAssets( AssetQuery* pAssetQuery, const char* pAssetTagNames, const bool assetQueryAsSource = false );
369    S32 findAssetLooseFile( AssetQuery* pAssetQuery, const char* pLooseFile, const bool assetQueryAsSource = false );
370
371    /// Declare Console Object.
372    DECLARE_CONOBJECT( AssetManager );
373
374private:
375    bool scanDeclaredAssets( const char* pPath, const char* pExtension, const bool recurse, ModuleDefinition* pModuleDefinition );
376    bool scanReferencedAssets( const char* pPath, const char* pExtension, const bool recurse );
377    AssetDefinition* findAsset( const char* pAssetId );
378    void addReferencedAsset( StringTableEntry assetId, StringTableEntry referenceFilePath );
379    void renameAssetReferences( StringTableEntry assetIdFrom, StringTableEntry assetIdTo );
380    void removeAssetReferences( StringTableEntry assetId );
381    void renameAssetDependencies( StringTableEntry assetIdFrom, StringTableEntry assetIdTo );
382    void removeAssetDependencies( const char* pAssetId );
383    void removeAssetLooseFiles( const char* pAssetId );
384    void unloadAsset( AssetDefinition* pAssetDefinition );
385
386    /// Module callbacks.
387    virtual void onModulePreLoad( ModuleDefinition* pModuleDefinition );
388    virtual void onModulePreUnload( ModuleDefinition* pModuleDefinition );
389    virtual void onModulePostUnload( ModuleDefinition* pModuleDefinition );
390};
391
392//-----------------------------------------------------------------------------
393
394extern AssetManager AssetDatabase;
395
396#endif // _ASSET_MANAGER_H_
397