assetManager.h
Engine/source/assets/assetManager.h
Classes:
class
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