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
 78public:
 79   typedef StringTableEntry typeAssetId;
 80   typedef StringTableEntry typeAssetName;
 81   typedef StringTableEntry typeReferenceFilePath;
 82   typedef HashMap<typeAssetId, AssetDefinition*> typeDeclaredAssetsHash;
 83   typedef HashTable<typeAssetId, typeReferenceFilePath> typeReferencedAssetsHash;
 84   typedef HashTable<typeAssetId, typeAssetId> typeAssetDependsOnHash;
 85   typedef HashTable<typeAssetId, typeAssetId> typeAssetIsDependedOnHash;
 86   typedef HashMap<AssetPtrBase*, AssetPtrCallback*> typeAssetPtrRefreshHash;
 87
 88private:
 89    /// Declared assets.
 90    typeDeclaredAssetsHash              mDeclaredAssets;
 91
 92    /// Referenced assets.
 93    typeReferencedAssetsHash            mReferencedAssets;
 94
 95    /// Asset dependencies.
 96    typeAssetDependsOnHash              mAssetDependsOn;
 97    typeAssetIsDependedOnHash           mAssetIsDependedOn;
 98
 99    /// Asset tags.
100    SimObjectPtr<AssetTagsManifest>     mAssetTagsManifest;
101    SimObjectPtr<ModuleDefinition>      mAssetTagsModuleDefinition;
102
103    /// Asset pointer refresh notifications.
104    typeAssetPtrRefreshHash             mAssetPtrRefreshNotifications;
105
106    /// Miscellaneous.
107    bool                                mEchoInfo;
108    bool                                mIgnoreAutoUnload;
109    U32                                 mLoadedInternalAssetsCount;
110    U32                                 mLoadedExternalAssetsCount;
111    U32                                 mLoadedPrivateAssetsCount;
112    U32                                 mAcquiredReferenceCount;
113    U32                                 mMaxLoadedInternalAssetsCount;
114    U32                                 mMaxLoadedExternalAssetsCount;
115    U32                                 mMaxLoadedPrivateAssetsCount;
116    Taml                                mTaml;
117
118public:
119    AssetManager();
120    virtual ~AssetManager() {}
121
122    /// SimObject overrides
123    virtual bool onAdd();
124    virtual void onRemove();
125    static void initPersistFields();
126
127    /// Declared assets.
128    bool addModuleDeclaredAssets( ModuleDefinition* pModuleDefinition );
129    bool addDeclaredAsset( ModuleDefinition* pModuleDefinition, const char* pAssetFilePath );
130    StringTableEntry addPrivateAsset( AssetBase* pAssetBase );
131    bool removeDeclaredAssets( ModuleDefinition* pModuleDefinition );
132    bool removeDeclaredAsset( const char* pAssetId );
133    bool renameDeclaredAsset( const char* pAssetIdFrom, const char* pAssetIdTo );
134    bool loadModuleAutoLoadAssets(ModuleDefinition* pModuleDefinition);
135    StringTableEntry getAssetName( const char* pAssetId );
136    StringTableEntry getAssetDescription( const char* pAssetId );
137    StringTableEntry getAssetCategory( const char* pAssetId );
138    StringTableEntry getAssetType( const char* pAssetId );
139    StringTableEntry getAssetFilePath( const char* pAssetId );
140    StringTableEntry getAssetPath( const char* pAssetId );
141    ModuleDefinition* getAssetModuleDefinition( const char* pAssetId );
142    bool isAssetInternal( const char* pAssetId );
143    bool isAssetPrivate( const char* pAssetId );
144    bool isAssetAutoUnload( const char* pAssetId );
145    bool isAssetLoaded( const char* pAssetId );
146    bool isDeclaredAsset( const char* pAssetId );
147    bool doesAssetDependOn( const char* pAssetId, const char* pDependsOnAssetId );
148    bool isAssetDependedOn( const char* pAssetId, const char* pDependedOnByAssetId );
149
150    /// Referenced assets.
151    bool compileReferencedAssets( ModuleDefinition* pModuleDefinition );
152    bool isReferencedAsset( const char* pAssetId );
153    bool renameReferencedAsset( const char* pAssetIdFrom, const char* pAssetIdTo );
154
155    /// Public asset acquisition.
156    template<typename T> T* acquireAsset( const char* pAssetId )
157    {
158        // Sanity!
159        AssertFatal( pAssetId != NULL, "Cannot acquire NULL asset Id." );
160
161        // Is this an empty asset Id?
162        if ( *pAssetId == 0 )
163        {
164            // Yes, so return nothing.
165            return NULL;
166        }
167
168        // Find asset.
169        AssetDefinition* pAssetDefinition = findAsset( pAssetId );
170
171        // Did we find the asset?
172        if ( pAssetDefinition == NULL )
173        {
174            // No, so warn.
175            Con::warnf( "Asset Manager: Failed to acquire asset Id '%s' as it does not exist.", pAssetId );
176            return NULL;
177        }
178
179        // Is asset loading?
180        if ( pAssetDefinition->mAssetLoading == true )
181        {
182            // Yes, so we've got a circular loop which we cannot resolve!
183            Con::warnf( "Asset Manager: Failed to acquire asset Id '%s' as loading it involves a cyclic dependency on itself which cannot be resolved.", pAssetId );
184            return NULL;
185        }
186
187        // Info.
188        if ( mEchoInfo )
189        {
190            Con::printSeparator();
191            Con::printf( "Asset Manager: Started acquiring Asset Id '%s'...", pAssetId );
192        }
193
194        // Is the asset already loaded?
195        if ( pAssetDefinition->mpAssetBase == NULL )
196        {
197            // No, so info
198            if ( mEchoInfo )
199            {
200                // Fetch asset Id.
201                StringTableEntry assetId = StringTable->insert( pAssetId );
202
203                // Find any asset dependencies.
204                typeAssetDependsOnHash::Iterator assetDependenciesItr = mAssetDependsOn.find( assetId );
205
206                // Does the asset have any dependencies?
207                if ( assetDependenciesItr != mAssetDependsOn.end() )
208                {
209                    // Yes, so show all dependency assets.
210                    Con::printf( "Asset Manager: > Found dependencies:" );
211
212                    // Iterate all dependencies.
213                    while( assetDependenciesItr != mAssetDependsOn.end() && assetDependenciesItr->key == assetId )
214                    {
215                        // Info.
216                        Con::printf( "Asset Manager: > Asset Id '%s'", assetDependenciesItr->value );
217
218                        // Next dependency.
219                        assetDependenciesItr++;
220                    }
221                }
222            }
223
224            // Flag asset as loading.
225            pAssetDefinition->mAssetLoading = true;
226
227            // Generate primary asset.
228            pAssetDefinition->mpAssetBase = mTaml.read<T>( pAssetDefinition->mAssetBaseFilePath );
229
230            // Flag asset as finished loading.
231            pAssetDefinition->mAssetLoading = false;
232
233            // Did we generate the asset?
234            if ( pAssetDefinition->mpAssetBase == NULL )
235            {
236                // No, so warn.
237                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'.",
238                    pAssetId, pAssetDefinition->mAssetBaseFilePath );
239                return NULL;
240            }
241
242            // Increase loaded count.
243            pAssetDefinition->mAssetLoadedCount++;
244
245            // Info.
246            if ( mEchoInfo )
247            {
248                Con::printf( "Asset Manager: > Loading asset into memory as object Id '%d' from file '%s'.",
249                    pAssetDefinition->mpAssetBase->getId(), pAssetDefinition->mAssetBaseFilePath );
250            }
251
252            // Set ownership by asset manager.
253            pAssetDefinition->mpAssetBase->setOwned( this, pAssetDefinition );
254
255            // Is the asset internal?
256            if ( pAssetDefinition->mAssetInternal )
257            {
258                // Yes, so increase internal loaded asset count.
259                if ( ++mLoadedInternalAssetsCount > mMaxLoadedInternalAssetsCount )
260                    mMaxLoadedInternalAssetsCount = mLoadedInternalAssetsCount;
261            }
262            else
263            {
264                // No, so increase external loaded assets count.
265                if ( ++mLoadedExternalAssetsCount > mMaxLoadedExternalAssetsCount )
266                    mMaxLoadedExternalAssetsCount = mLoadedExternalAssetsCount;
267            }
268        }
269        else if ( pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() == 0 )
270        {
271            // Info.
272            if ( mEchoInfo )
273            {
274                Con::printf( "Asset Manager: > Acquiring from idle state." );
275            }
276        }
277
278        // Set acquired asset.
279        T* pAcquiredAsset = dynamic_cast<T*>( (AssetBase*)pAssetDefinition->mpAssetBase );
280
281        // Is asset the correct type?
282        if ( pAcquiredAsset == NULL )
283        {
284            // No, so warn.
285            Con::warnf( "Asset Manager: > Failed to acquire asset Id '%s' as it was not the required asset type: '%s'.", pAssetId, pAssetDefinition->mAssetBaseFilePath );
286            return NULL;
287        }
288
289        // Acquire asset reference.
290        pAcquiredAsset->acquireAssetReference();
291
292        // Info.
293        if ( mEchoInfo )
294        {
295            Con::printf( "Asset Manager: > Finished acquiring asset.  Reference count now '%d'.", pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() );
296            Con::printSeparator();
297        }
298
299        return pAcquiredAsset;
300    }
301
302    /// Private asset acquisition.
303    template<typename T> T* acquireAsPrivateAsset( const char* pAssetId )
304    {
305        // Acquire the asset normally.
306        T* pAsset = acquireAsset<T>( pAssetId );
307
308        // Finish if the asset was not acquired.
309        if ( pAsset == NULL )
310            return NULL;
311
312        // Clone the asset.
313        T* pAssetClone = dynamic_cast<T*>( pAsset->clone() );
314
315        // Sanity!
316        AssertFatal( pAssetClone != NULL, "acquireAsPrivateAsset() - Failed to clone asset type." );
317
318        // Release the public asset.
319        releaseAsset( pAssetId );
320
321        // Add as a private asset.
322        addPrivateAsset( pAssetClone );
323
324        return pAssetClone;
325    }
326
327    bool releaseAsset( const char* pAssetId );
328    void purgeAssets( void );
329
330    /// Asset deletion.
331    bool deleteAsset( const char* pAssetId, const bool deleteLooseFiles, const bool deleteDependencies );
332
333    // Asset refresh notification.
334    bool refreshAsset( const char* pAssetId );
335    void refreshAllAssets( const bool includeUnloaded = false );
336    void registerAssetPtrRefreshNotify( AssetPtrBase* pAssetPtrBase, AssetPtrCallback* pCallback );
337    void unregisterAssetPtrRefreshNotify( AssetPtrBase* pAssetPtrBase );
338
339    /// Asset tags.
340    bool loadAssetTags( ModuleDefinition* pModuleDefinition );
341    bool saveAssetTags( void );
342    bool restoreAssetTags( void );
343    inline AssetTagsManifest* getAssetTags( void ) const { return mAssetTagsManifest; }
344
345    /// Info.
346    inline U32 getDeclaredAssetCount( void ) const { return (U32)mDeclaredAssets.size(); }
347    inline U32 getReferencedAssetCount( void ) const { return (U32)mReferencedAssets.size(); }
348    inline U32 getLoadedInternalAssetCount( void ) const { return mLoadedInternalAssetsCount; }
349    inline U32 getLoadedExternalAssetCount( void ) const { return mLoadedExternalAssetsCount; }
350    inline U32 getLoadedPrivateAssetCount( void ) const { return mLoadedPrivateAssetsCount; }
351    inline U32 getMaxLoadedInternalAssetCount( void ) const { return mMaxLoadedInternalAssetsCount; }
352    inline U32 getMaxLoadedExternalAssetCount( void ) const { return mMaxLoadedExternalAssetsCount; }
353    inline U32 getMaxLoadedPrivateAssetCount( void ) const { return mMaxLoadedPrivateAssetsCount; }
354    void dumpDeclaredAssets( void ) const;
355
356    /// Total acquired asset references.
357    inline void acquireAcquiredReferenceCount( void ) { mAcquiredReferenceCount++; }
358    inline void releaseAcquiredReferenceCount( void ) { AssertFatal( mAcquiredReferenceCount != 0, "AssetManager: Invalid acquired reference count." ); mAcquiredReferenceCount--; }
359    inline U32 getAcquiredReferenceCount( void ) const { return mAcquiredReferenceCount; }
360
361    /// Asset queries.
362    S32 findAllAssets( AssetQuery* pAssetQuery, const bool ignoreInternal = true, const bool ignorePrivate = true );
363    S32 findAssetName( AssetQuery* pAssetQuery, const char* pAssetName, const bool partialName = false );
364    S32 findAssetCategory( AssetQuery* pAssetQuery, const char* pAssetCategory, const bool assetQueryAsSource = false );
365    S32 findAssetAutoUnload( AssetQuery* pAssetQuery, const bool assetAutoUnload, const bool assetQueryAsSource = false );
366    S32 findAssetInternal( AssetQuery* pAssetQuery, const bool assetInternal, const bool assetQueryAsSource = false );
367    S32 findAssetPrivate( AssetQuery* pAssetQuery, const bool assetPrivate, const bool assetQueryAsSource = false );
368    S32 findAssetType( AssetQuery* pAssetQuery, const char* pAssetType, const bool assetQueryAsSource = false );
369    S32 findAssetDependsOn( AssetQuery* pAssetQuery, const char* pAssetId );
370    S32 findAssetIsDependedOn( AssetQuery* pAssetQuery, const char* pAssetId );
371    S32 findInvalidAssetReferences( AssetQuery* pAssetQuery );
372    S32 findTaggedAssets( AssetQuery* pAssetQuery, const char* pAssetTagNames, const bool assetQueryAsSource = false );
373    S32 findAssetLooseFile( AssetQuery* pAssetQuery, const char* pLooseFile, const bool assetQueryAsSource = false );
374
375    typeAssetDependsOnHash* getDependedOnAssets();
376
377    /// Declare Console Object.
378    DECLARE_CONOBJECT( AssetManager );
379
380private:
381    bool scanDeclaredAssets( const char* pPath, const char* pExtension, const bool recurse, ModuleDefinition* pModuleDefinition );
382    bool scanReferencedAssets( const char* pPath, const char* pExtension, const bool recurse );
383    AssetDefinition* findAsset( const char* pAssetId );
384    void addReferencedAsset( StringTableEntry assetId, StringTableEntry referenceFilePath );
385    void renameAssetReferences( StringTableEntry assetIdFrom, StringTableEntry assetIdTo );
386    void removeAssetReferences( StringTableEntry assetId );
387    void renameAssetDependencies( StringTableEntry assetIdFrom, StringTableEntry assetIdTo );
388    void removeAssetDependencies( const char* pAssetId );
389    void removeAssetLooseFiles( const char* pAssetId );
390    void unloadAsset( AssetDefinition* pAssetDefinition );
391
392    /// Module callbacks.
393    virtual void onModulePreLoad( ModuleDefinition* pModuleDefinition );
394    virtual void onModulePreUnload( ModuleDefinition* pModuleDefinition );
395    virtual void onModulePostUnload( ModuleDefinition* pModuleDefinition );
396};
397
398//-----------------------------------------------------------------------------
399
400extern AssetManager AssetDatabase;
401
402#endif // _ASSET_MANAGER_H_
403