assetManager.h 16 KB

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