mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
CompileAll - allows us to compile all assets to binary CompileModuleAssets - allows us to just compile assets for a specific module CompileAsset - compile a single asset
430 lines
17 KiB
C++
430 lines
17 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2013 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _ASSET_MANAGER_H_
|
|
#define _ASSET_MANAGER_H_
|
|
|
|
#ifndef _SIMBASE_H_
|
|
#include "console/sim.h"
|
|
#endif
|
|
|
|
#ifndef _TAML_H_
|
|
#include "persistence/taml/taml.h"
|
|
#endif
|
|
|
|
#ifndef _MODULE_DEFINITION_H
|
|
#include "module/moduleDefinition.h"
|
|
#endif
|
|
|
|
#ifndef _MODULE_CALLBACKS_H_
|
|
#include "module/moduleCallbacks.h"
|
|
#endif
|
|
|
|
#ifndef _ASSET_BASE_H_
|
|
#include "assets/assetBase.h"
|
|
#endif
|
|
|
|
#ifndef _ASSET_DEFINITION_H_
|
|
#include "assets/assetDefinition.h"
|
|
#endif
|
|
|
|
#ifndef _ASSET_TAGS_MANIFEST_H_
|
|
#include "assets/assetTagsManifest.h"
|
|
#endif
|
|
|
|
#ifndef _ASSET_QUERY_H_
|
|
#include "assets/assetQuery.h"
|
|
#endif
|
|
|
|
#ifndef _ASSET_FIELD_TYPES_H_
|
|
#include "assets/assetFieldTypes.h"
|
|
#endif
|
|
|
|
// Debug Profiling.
|
|
#include "platform/profiler.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class AssetPtrCallback;
|
|
class AssetPtrBase;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class AssetManager : public SimObject, public ModuleCallbacks
|
|
{
|
|
private:
|
|
typedef SimObject Parent;
|
|
|
|
public:
|
|
typedef StringTableEntry typeAssetId;
|
|
typedef StringTableEntry typeAssetName;
|
|
typedef StringTableEntry typeReferenceFilePath;
|
|
typedef HashMap<typeAssetId, AssetDefinition*> typeDeclaredAssetsHash;
|
|
typedef HashTable<typeAssetId, typeReferenceFilePath> typeReferencedAssetsHash;
|
|
typedef HashTable<typeAssetId, typeAssetId> typeAssetDependsOnHash;
|
|
typedef HashTable<typeAssetId, typeAssetId> typeAssetIsDependedOnHash;
|
|
typedef HashMap<AssetPtrBase*, AssetPtrCallback*> typeAssetPtrRefreshHash;
|
|
|
|
private:
|
|
/// Declared assets.
|
|
typeDeclaredAssetsHash mDeclaredAssets;
|
|
|
|
/// Referenced assets.
|
|
typeReferencedAssetsHash mReferencedAssets;
|
|
|
|
/// Asset dependencies.
|
|
typeAssetDependsOnHash mAssetDependsOn;
|
|
typeAssetIsDependedOnHash mAssetIsDependedOn;
|
|
|
|
/// Asset tags.
|
|
SimObjectPtr<AssetTagsManifest> mAssetTagsManifest;
|
|
SimObjectPtr<ModuleDefinition> mAssetTagsModuleDefinition;
|
|
|
|
/// Asset pointer refresh notifications.
|
|
typeAssetPtrRefreshHash mAssetPtrRefreshNotifications;
|
|
|
|
/// Miscellaneous.
|
|
bool mEchoInfo;
|
|
bool mIgnoreAutoUnload;
|
|
U32 mLoadedInternalAssetsCount;
|
|
U32 mLoadedExternalAssetsCount;
|
|
U32 mLoadedPrivateAssetsCount;
|
|
U32 mAcquiredReferenceCount;
|
|
U32 mMaxLoadedInternalAssetsCount;
|
|
U32 mMaxLoadedExternalAssetsCount;
|
|
U32 mMaxLoadedPrivateAssetsCount;
|
|
Taml mTaml;
|
|
|
|
public:
|
|
AssetManager();
|
|
virtual ~AssetManager() {}
|
|
|
|
/// SimObject overrides
|
|
bool onAdd() override;
|
|
void onRemove() override;
|
|
static void initPersistFields();
|
|
|
|
/// Declared assets.
|
|
bool addModuleDeclaredAssets( ModuleDefinition* pModuleDefinition );
|
|
bool addDeclaredAsset( ModuleDefinition* pModuleDefinition, const char* pAssetFilePath );
|
|
StringTableEntry addPrivateAsset( AssetBase* pAssetBase );
|
|
bool removeDeclaredAssets( ModuleDefinition* pModuleDefinition );
|
|
bool removeDeclaredAsset( const char* pAssetId );
|
|
bool renameDeclaredAsset( const char* pAssetIdFrom, const char* pAssetIdTo );
|
|
bool loadModuleAutoLoadAssets(ModuleDefinition* pModuleDefinition);
|
|
StringTableEntry getAssetName( const char* pAssetId );
|
|
StringTableEntry getAssetDescription( const char* pAssetId );
|
|
StringTableEntry getAssetCategory( const char* pAssetId );
|
|
StringTableEntry getAssetType( const char* pAssetId );
|
|
StringTableEntry getAssetFilePath( const char* pAssetId );
|
|
StringTableEntry getAssetPath( const char* pAssetId );
|
|
ModuleDefinition* getAssetModuleDefinition( const char* pAssetId );
|
|
bool isAssetInternal( const char* pAssetId );
|
|
bool isAssetPrivate( const char* pAssetId );
|
|
bool isAssetAutoUnload( const char* pAssetId );
|
|
bool isAssetLoaded( const char* pAssetId );
|
|
bool isDeclaredAsset( const char* pAssetId );
|
|
bool doesAssetDependOn( const char* pAssetId, const char* pDependsOnAssetId );
|
|
bool isAssetDependedOn( const char* pAssetId, const char* pDependedOnByAssetId );
|
|
|
|
/// Referenced assets.
|
|
bool compileReferencedAssets( ModuleDefinition* pModuleDefinition );
|
|
bool isReferencedAsset( const char* pAssetId );
|
|
bool renameReferencedAsset( const char* pAssetIdFrom, const char* pAssetIdTo );
|
|
|
|
/// <summary>
|
|
/// Compile all assets.
|
|
/// </summary>
|
|
/// <param name="compressed">Do we want binary compression?</param>
|
|
/// <param name="includeUnloaded">Do we want to include unloaded assets?</param>
|
|
/// <returns>True if successful, otherwise false.</returns>
|
|
bool compileAllAssets(const bool compressed = false, const bool includeUnloaded = false);
|
|
|
|
/// <summary>
|
|
/// Compile all assets for a module.
|
|
/// </summary>
|
|
/// <param name="pModuleDefinition">The module definition to compile.</param>
|
|
/// <returns></returns>
|
|
bool compileModuleAssets(ModuleDefinition* pModuleDefinition);
|
|
|
|
/// <summary>
|
|
/// Compile a single asset to binary.
|
|
/// </summary>
|
|
/// <param name="pAssetId">The asset id to be compiled.</param>
|
|
/// <returns>True if successful, otherwise false.</returns>
|
|
bool compileAsset(const char* pAssetId);
|
|
|
|
/// Public asset acquisition.
|
|
template<typename T> T* acquireAsset( const char* pAssetId )
|
|
{
|
|
// Sanity!
|
|
AssertFatal( pAssetId != NULL, "Cannot acquire NULL asset Id." );
|
|
|
|
// Is this an empty asset Id?
|
|
if ( *pAssetId == 0 )
|
|
{
|
|
// Yes, so return nothing.
|
|
return NULL;
|
|
}
|
|
|
|
// Find asset.
|
|
AssetDefinition* pAssetDefinition = findAsset( pAssetId );
|
|
|
|
// Did we find the asset?
|
|
if ( pAssetDefinition == NULL )
|
|
{
|
|
// No, so warn.
|
|
Con::warnf( "Asset Manager: Failed to acquire asset Id '%s' as it does not exist.", pAssetId );
|
|
return NULL;
|
|
}
|
|
|
|
// Is asset loading?
|
|
if ( pAssetDefinition->mAssetLoading == true )
|
|
{
|
|
// Yes, so we've got a circular loop which we cannot resolve!
|
|
Con::warnf( "Asset Manager: Failed to acquire asset Id '%s' as loading it involves a cyclic dependency on itself which cannot be resolved.", pAssetId );
|
|
return NULL;
|
|
}
|
|
|
|
// Info.
|
|
if ( mEchoInfo )
|
|
{
|
|
Con::printSeparator();
|
|
Con::printf( "Asset Manager: Started acquiring Asset Id '%s'...", pAssetId );
|
|
}
|
|
|
|
// Is the asset already loaded?
|
|
if ( pAssetDefinition->mpAssetBase == NULL )
|
|
{
|
|
// No, so info
|
|
if ( mEchoInfo )
|
|
{
|
|
// Fetch asset Id.
|
|
StringTableEntry assetId = StringTable->insert( pAssetId );
|
|
|
|
// Find any asset dependencies.
|
|
typeAssetDependsOnHash::Iterator assetDependenciesItr = mAssetDependsOn.find( assetId );
|
|
|
|
// Does the asset have any dependencies?
|
|
if ( assetDependenciesItr != mAssetDependsOn.end() )
|
|
{
|
|
// Yes, so show all dependency assets.
|
|
Con::printf( "Asset Manager: > Found dependencies:" );
|
|
|
|
// Iterate all dependencies.
|
|
while( assetDependenciesItr != mAssetDependsOn.end() && assetDependenciesItr->key == assetId )
|
|
{
|
|
// Info.
|
|
Con::printf( "Asset Manager: > Asset Id '%s'", assetDependenciesItr->value );
|
|
|
|
// Next dependency.
|
|
assetDependenciesItr++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Flag asset as loading.
|
|
pAssetDefinition->mAssetLoading = true;
|
|
|
|
// Generate primary asset.
|
|
pAssetDefinition->mpAssetBase = mTaml.read<T>( pAssetDefinition->mAssetBaseFilePath );
|
|
|
|
// Flag asset as finished loading.
|
|
pAssetDefinition->mAssetLoading = false;
|
|
|
|
// Did we generate the asset?
|
|
if ( pAssetDefinition->mpAssetBase == NULL )
|
|
{
|
|
// No, so warn.
|
|
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'.",
|
|
pAssetId, pAssetDefinition->mAssetBaseFilePath );
|
|
return NULL;
|
|
}
|
|
|
|
// Increase loaded count.
|
|
pAssetDefinition->mAssetLoadedCount++;
|
|
|
|
// Info.
|
|
if ( mEchoInfo )
|
|
{
|
|
Con::printf( "Asset Manager: > Loading asset into memory as object Id '%d' from file '%s'.",
|
|
pAssetDefinition->mpAssetBase->getId(), pAssetDefinition->mAssetBaseFilePath );
|
|
}
|
|
|
|
// Set ownership by asset manager.
|
|
pAssetDefinition->mpAssetBase->setOwned( this, pAssetDefinition );
|
|
|
|
// Is the asset internal?
|
|
if ( pAssetDefinition->mAssetInternal )
|
|
{
|
|
// Yes, so increase internal loaded asset count.
|
|
if ( ++mLoadedInternalAssetsCount > mMaxLoadedInternalAssetsCount )
|
|
mMaxLoadedInternalAssetsCount = mLoadedInternalAssetsCount;
|
|
}
|
|
else
|
|
{
|
|
// No, so increase external loaded assets count.
|
|
if ( ++mLoadedExternalAssetsCount > mMaxLoadedExternalAssetsCount )
|
|
mMaxLoadedExternalAssetsCount = mLoadedExternalAssetsCount;
|
|
}
|
|
}
|
|
else if ( pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() == 0 )
|
|
{
|
|
// Info.
|
|
if ( mEchoInfo )
|
|
{
|
|
Con::printf( "Asset Manager: > Acquiring from idle state." );
|
|
}
|
|
}
|
|
|
|
// Set acquired asset.
|
|
T* pAcquiredAsset = dynamic_cast<T*>( (AssetBase*)pAssetDefinition->mpAssetBase );
|
|
|
|
// Is asset the correct type?
|
|
if ( pAcquiredAsset == NULL )
|
|
{
|
|
// No, so warn.
|
|
Con::warnf( "Asset Manager: > Failed to acquire asset Id '%s' as it was not the required asset type: '%s'.", pAssetId, pAssetDefinition->mAssetBaseFilePath );
|
|
return NULL;
|
|
}
|
|
|
|
// Acquire asset reference.
|
|
pAcquiredAsset->acquireAssetReference();
|
|
|
|
// Info.
|
|
if ( mEchoInfo )
|
|
{
|
|
Con::printf( "Asset Manager: > Finished acquiring asset. Reference count now '%d'.", pAssetDefinition->mpAssetBase->getAcquiredReferenceCount() );
|
|
Con::printSeparator();
|
|
}
|
|
|
|
return pAcquiredAsset;
|
|
}
|
|
|
|
/// Private asset acquisition.
|
|
template<typename T> T* acquireAsPrivateAsset( const char* pAssetId )
|
|
{
|
|
// Acquire the asset normally.
|
|
T* pAsset = acquireAsset<T>( pAssetId );
|
|
|
|
// Finish if the asset was not acquired.
|
|
if ( pAsset == NULL )
|
|
return NULL;
|
|
|
|
// Clone the asset.
|
|
T* pAssetClone = dynamic_cast<T*>( pAsset->clone() );
|
|
|
|
// Sanity!
|
|
AssertFatal( pAssetClone != NULL, "acquireAsPrivateAsset() - Failed to clone asset type." );
|
|
|
|
// Release the public asset.
|
|
releaseAsset( pAssetId );
|
|
|
|
// Add as a private asset.
|
|
addPrivateAsset( pAssetClone );
|
|
|
|
return pAssetClone;
|
|
}
|
|
|
|
bool releaseAsset( const char* pAssetId );
|
|
void purgeAssets( void );
|
|
|
|
/// Asset deletion.
|
|
bool deleteAsset( const char* pAssetId, const bool deleteLooseFiles, const bool deleteDependencies );
|
|
|
|
// Asset refresh notification.
|
|
bool refreshAsset( const char* pAssetId );
|
|
void refreshAllAssets( const bool includeUnloaded = false );
|
|
void registerAssetPtrRefreshNotify( AssetPtrBase* pAssetPtrBase, AssetPtrCallback* pCallback );
|
|
void unregisterAssetPtrRefreshNotify( AssetPtrBase* pAssetPtrBase );
|
|
|
|
/// Asset tags.
|
|
bool loadAssetTags( ModuleDefinition* pModuleDefinition );
|
|
bool saveAssetTags( void );
|
|
bool restoreAssetTags( void );
|
|
inline AssetTagsManifest* getAssetTags( void ) const { return mAssetTagsManifest; }
|
|
|
|
/// Loose File management
|
|
const char* getAssetLooseFiles(const char* pAssetId);
|
|
|
|
/// Info.
|
|
inline U32 getDeclaredAssetCount( void ) const { return (U32)mDeclaredAssets.size(); }
|
|
inline U32 getReferencedAssetCount( void ) const { return (U32)mReferencedAssets.size(); }
|
|
inline U32 getLoadedInternalAssetCount( void ) const { return mLoadedInternalAssetsCount; }
|
|
inline U32 getLoadedExternalAssetCount( void ) const { return mLoadedExternalAssetsCount; }
|
|
inline U32 getLoadedPrivateAssetCount( void ) const { return mLoadedPrivateAssetsCount; }
|
|
inline U32 getMaxLoadedInternalAssetCount( void ) const { return mMaxLoadedInternalAssetsCount; }
|
|
inline U32 getMaxLoadedExternalAssetCount( void ) const { return mMaxLoadedExternalAssetsCount; }
|
|
inline U32 getMaxLoadedPrivateAssetCount( void ) const { return mMaxLoadedPrivateAssetsCount; }
|
|
void dumpDeclaredAssets( void ) const;
|
|
|
|
/// Total acquired asset references.
|
|
inline void acquireAcquiredReferenceCount( void ) { mAcquiredReferenceCount++; }
|
|
inline void releaseAcquiredReferenceCount( void ) { AssertFatal( mAcquiredReferenceCount != 0, "AssetManager: Invalid acquired reference count." ); mAcquiredReferenceCount--; }
|
|
inline U32 getAcquiredReferenceCount( void ) const { return mAcquiredReferenceCount; }
|
|
|
|
/// Asset queries.
|
|
S32 findAllAssets( AssetQuery* pAssetQuery, const bool ignoreInternal = true, const bool ignorePrivate = true );
|
|
S32 findAssetName( AssetQuery* pAssetQuery, const char* pAssetName, const bool partialName = false );
|
|
S32 findAssetCategory( AssetQuery* pAssetQuery, const char* pAssetCategory, const bool assetQueryAsSource = false );
|
|
S32 findAssetAutoUnload( AssetQuery* pAssetQuery, const bool assetAutoUnload, const bool assetQueryAsSource = false );
|
|
S32 findAssetInternal( AssetQuery* pAssetQuery, const bool assetInternal, const bool assetQueryAsSource = false );
|
|
S32 findAssetPrivate( AssetQuery* pAssetQuery, const bool assetPrivate, const bool assetQueryAsSource = false );
|
|
S32 findAssetType( AssetQuery* pAssetQuery, const char* pAssetType, const bool assetQueryAsSource = false );
|
|
S32 findAssetDependsOn( AssetQuery* pAssetQuery, const char* pAssetId );
|
|
S32 findAssetIsDependedOn( AssetQuery* pAssetQuery, const char* pAssetId );
|
|
S32 findInvalidAssetReferences( AssetQuery* pAssetQuery );
|
|
S32 findTaggedAssets( AssetQuery* pAssetQuery, const char* pAssetTagNames, const bool assetQueryAsSource = false );
|
|
S32 findAssetLooseFile( AssetQuery* pAssetQuery, const char* pLooseFile, const bool assetQueryAsSource = false );
|
|
|
|
typeAssetDependsOnHash* getDependedOnAssets();
|
|
|
|
S32 getAssetLooseFileCount(const char* pAssetId);
|
|
const char* getAssetLooseFile(const char* pAssetId, const S32& index);
|
|
|
|
/// Declare Console Object.
|
|
DECLARE_CONOBJECT( AssetManager );
|
|
|
|
private:
|
|
bool scanDeclaredAssets( const char* pPath, const char* pExtension, const bool recurse, ModuleDefinition* pModuleDefinition );
|
|
bool scanReferencedAssets( const char* pPath, const char* pExtension, const bool recurse );
|
|
AssetDefinition* findAsset( const char* pAssetId );
|
|
void addReferencedAsset( StringTableEntry assetId, StringTableEntry referenceFilePath );
|
|
void renameAssetReferences( StringTableEntry assetIdFrom, StringTableEntry assetIdTo );
|
|
void removeAssetReferences( StringTableEntry assetId );
|
|
void renameAssetDependencies( StringTableEntry assetIdFrom, StringTableEntry assetIdTo );
|
|
void removeAssetDependencies( const char* pAssetId );
|
|
void removeAssetLooseFiles( const char* pAssetId );
|
|
void unloadAsset( AssetDefinition* pAssetDefinition );
|
|
|
|
/// Module callbacks.
|
|
void onModulePreLoad( ModuleDefinition* pModuleDefinition ) override;
|
|
void onModulePreUnload( ModuleDefinition* pModuleDefinition ) override;
|
|
void onModulePostUnload( ModuleDefinition* pModuleDefinition ) override;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
extern AssetManager AssetDatabase;
|
|
|
|
#endif // _ASSET_MANAGER_H_
|