123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- //-----------------------------------------------------------------------------
- // 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_BASE_H_
- #include "assetBase.h"
- #endif
- #ifndef _ASSET_MANAGER_H_
- #include "assetManager.h"
- #endif
- #ifndef _CONSOLETYPES_H_
- #include "console/consoleTypes.h"
- #endif
- // Script bindings.
- #include "assetBase_ScriptBinding.h"
- // Debug Profiling.
- #include "platform/profiler.h"
- //-----------------------------------------------------------------------------
- IMPLEMENT_CONOBJECT(AssetBase);
- //-----------------------------------------------------------------------------
- StringTableEntry assetNameField = StringTable->insert("AssetName");
- StringTableEntry assetDescriptionField = StringTable->insert("AssetDescription");
- StringTableEntry assetCategoryField = StringTable->insert("AssetCategory");
- StringTableEntry assetAutoUnloadField = StringTable->insert("AssetAutoUnload");
- StringTableEntry assetInternalField = StringTable->insert("AssetInternal");
- StringTableEntry assetPrivateField = StringTable->insert("AssetPrivate");
- //-----------------------------------------------------------------------------
- const String AssetBase::mErrCodeStrings[] =
- {
- "Failed",
- "Ok",
- "NotLoaded",
- "BadFileReference",
- "InvalidFormat",
- "DependencyNotFound",
- "FileTooLarge",
- "UsingFallback",
- "UnKnown"
- };
- AssetBase::AssetBase() :
- mpOwningAssetManager(NULL),
- mAcquireReferenceCount(0),
- mAssetInitialized(false)
- {
- // Generate an asset definition.
- mpAssetDefinition = new AssetDefinition();
- mInternalName = StringTable->EmptyString();
- mClassName = StringTable->EmptyString();
- mSuperClassName = StringTable->EmptyString();
- mLoadedState = AssetErrCode::NotLoaded;
- }
- //-----------------------------------------------------------------------------
- AssetBase::~AssetBase()
- {
- // If the asset manager does not own the asset then we own the
- // asset definition so delete it.
- if (!getOwned())
- SAFE_DELETE(mpAssetDefinition);
- }
- //-----------------------------------------------------------------------------
- void AssetBase::initPersistFields()
- {
- // Call parent.
- Parent::initPersistFields();
- // Asset configuration.
- addProtectedField(assetNameField, TypeString, 0, &setAssetName, &getAssetName, &writeAssetName, "The name of the asset. The is not a unique identification like an asset Id.");
- addProtectedField(assetDescriptionField, TypeString, 0, &setAssetDescription, &getAssetDescription, &writeAssetDescription, "The simple description of the asset contents.");
- addProtectedField(assetCategoryField, TypeString, 0, &setAssetCategory, &getAssetCategory, &writeAssetCategory, "An arbitrary category that can be used to categorized assets.");
- addProtectedField(assetAutoUnloadField, TypeBool, 0, &setAssetAutoUnload, &getAssetAutoUnload, &writeAssetAutoUnload, "Whether the asset is automatically unloaded when an asset is released and has no other acquisitions or not.");
- addProtectedField(assetInternalField, TypeBool, 0, &setAssetInternal, &getAssetInternal, &writeAssetInternal, "Whether the asset is used internally only or not.");
- addProtectedField(assetPrivateField, TypeBool, 0, &defaultProtectedNotSetFn, &getAssetPrivate, &defaultProtectedNotWriteFn, "Whether the asset is private or not.");
- }
- //------------------------------------------------------------------------------
- void AssetBase::copyTo(SimObject* object)
- {
- // Call to parent.
- Parent::copyTo(object);
- // Cast to asset.
- AssetBase* pAsset = static_cast<AssetBase*>(object);
- // Sanity!
- AssertFatal(pAsset != NULL, "AssetBase::copyTo() - Object is not the correct type.");
- // Copy state.
- pAsset->setAssetName(getAssetName());
- pAsset->setAssetDescription(getAssetDescription());
- pAsset->setAssetCategory(getAssetCategory());
- pAsset->setAssetAutoUnload(getAssetAutoUnload());
- pAsset->setAssetInternal(getAssetInternal());
- }
- //-----------------------------------------------------------------------------
- void AssetBase::setAssetDescription(const char* pAssetDescription)
- {
- // Fetch asset description.
- StringTableEntry assetDescription = StringTable->insert(pAssetDescription);
- // Ignore no change.
- if (mpAssetDefinition->mAssetDescription == assetDescription)
- return;
- // Update.
- mpAssetDefinition->mAssetDescription = assetDescription;
- // Refresh the asset.
- refreshAsset();
- }
- //-----------------------------------------------------------------------------
- void AssetBase::setAssetCategory(const char* pAssetCategory)
- {
- // Fetch asset category.
- StringTableEntry assetCategory = StringTable->insert(pAssetCategory);
- // Ignore no change.
- if (mpAssetDefinition->mAssetCategory == assetCategory)
- return;
- // Update.
- mpAssetDefinition->mAssetCategory = assetCategory;
- // Refresh the asset.
- refreshAsset();
- }
- //-----------------------------------------------------------------------------
- void AssetBase::setAssetAutoUnload(const bool autoUnload)
- {
- // Ignore no change.
- if (mpAssetDefinition->mAssetAutoUnload == autoUnload)
- return;
- // Update.
- mpAssetDefinition->mAssetAutoUnload = autoUnload;
- // Refresh the asset.
- refreshAsset();
- }
- //-----------------------------------------------------------------------------
- void AssetBase::setAssetInternal(const bool assetInternal)
- {
- // Ignore no change,
- if (mpAssetDefinition->mAssetInternal == assetInternal)
- return;
- // Update.
- mpAssetDefinition->mAssetInternal = assetInternal;
- // Refresh the asset.
- refreshAsset();
- }
- //-----------------------------------------------------------------------------
- StringTableEntry AssetBase::expandAssetFilePath(const char* pAssetFilePath) const
- {
- // Debug Profiling.
- PROFILE_SCOPE(AssetBase_ExpandAssetFilePath);
- // Sanity!
- AssertFatal(pAssetFilePath != NULL, "Cannot expand a NULL asset path.");
- // Fetch asset file-path length.
- const U32 assetFilePathLength = dStrlen(pAssetFilePath);
- // Are there any characters in the path?
- if (assetFilePathLength == 0)
- {
- // No, so return empty.
- return StringTable->EmptyString();
- }
- // Fetch the asset base-path hint.
- StringTableEntry assetBasePathHint;
- if (getOwned() && !getAssetPrivate())
- {
- assetBasePathHint = mpOwningAssetManager->getAssetPath(getAssetId());
- }
- else
- {
- assetBasePathHint = NULL;
- }
- // Expand the path with the asset base-path hint.
- char assetFilePathBuffer[1024];
- Con::expandPath(assetFilePathBuffer, sizeof(assetFilePathBuffer), pAssetFilePath, assetBasePathHint);
- return StringTable->insert(assetFilePathBuffer);
- }
- //-----------------------------------------------------------------------------
- StringTableEntry AssetBase::collapseAssetFilePath(const char* pAssetFilePath) const
- {
- // Debug Profiling.
- PROFILE_SCOPE(AssetBase_CollapseAssetFilePath);
- // Sanity!
- AssertFatal(pAssetFilePath != NULL, "Cannot collapse a NULL asset path.");
- // Fetch asset file-path length.
- const U32 assetFilePathLength = dStrlen(pAssetFilePath);
- // Are there any characters in the path?
- if (assetFilePathLength == 0)
- {
- // No, so return empty.
- return StringTable->EmptyString();
- }
- char assetFilePathBuffer[1024];
- // Is the asset not owned or private?
- if (!getOwned() || getAssetPrivate())
- {
- // Yes, so we can only collapse the path using the platform layer.
- Con::collapsePath(assetFilePathBuffer, sizeof(assetFilePathBuffer), pAssetFilePath);
- return StringTable->insert(assetFilePathBuffer);
- }
- // Fetch asset base-path.
- StringTableEntry assetBasePath = mpOwningAssetManager->getAssetPath(getAssetId());
- // Is the asset file-path location within the asset base-path?
- if (Con::isBasePath(pAssetFilePath, assetBasePath))
- {
- // Yes, so fetch path relative to the asset base-path.
- StringTableEntry relativePath = Platform::makeRelativePathName(pAssetFilePath, assetBasePath);
- // Format the collapsed path.
- dSprintf(assetFilePathBuffer, sizeof(assetFilePathBuffer), "%s", relativePath);
- }
- else
- {
- // No, so we can collapse the path using the platform layer.
- Con::collapsePath(assetFilePathBuffer, sizeof(assetFilePathBuffer), pAssetFilePath);
- }
- return StringTable->insert(assetFilePathBuffer);
- }
- //-----------------------------------------------------------------------------
- void AssetBase::refreshAsset(void)
- {
- // Debug Profiling.
- PROFILE_SCOPE(AssetBase_RefreshAsset);
- // Finish if asset is not owned or is not initialized.
- if (mpOwningAssetManager == NULL || !mAssetInitialized)
- return;
- // Yes, so refresh the asset via the asset manager.
- mpOwningAssetManager->refreshAsset(getAssetId());
- }
- //-----------------------------------------------------------------------------
- S32 AssetBase::getAssetDependencyFieldCount(const char* pFieldName)
- {
- S32 matchedFieldCount = 0;
- SimFieldDictionary* fieldDictionary = getFieldDictionary();
- for (SimFieldDictionaryIterator itr(fieldDictionary); *itr; ++itr)
- {
- SimFieldDictionary::Entry* entry = *itr;
- if (String(entry->slotName).startsWith(pFieldName))
- {
- matchedFieldCount++;
- }
- }
- return matchedFieldCount;
- }
- //-----------------------------------------------------------------------------
- StringTableEntry AssetBase::getAssetDependencyField(const char* pFieldName, S32 index)
- {
- SimFieldDictionary* fieldDictionary = getFieldDictionary();
- for (SimFieldDictionaryIterator itr(fieldDictionary); *itr; ++itr)
- {
- SimFieldDictionary::Entry* entry = *itr;
- String slotName = String(entry->slotName);
- if (slotName.startsWith(pFieldName))
- {
- S32 trailingNum;
- String::GetTrailingNumber(slotName.c_str(), trailingNum);
- if (trailingNum == index)
- {
- return StringTable->insert(String(entry->value).replace(ASSET_ID_FIELD_PREFIX, "").c_str());
- }
- }
- }
- return StringTable->EmptyString();
- }
- //-----------------------------------------------------------------------------
- void AssetBase::clearAssetDependencyFields(const char* pFieldName)
- {
- SimFieldDictionary* fieldDictionary = getFieldDictionary();
- for (SimFieldDictionaryIterator itr(fieldDictionary); *itr; ++itr)
- {
- SimFieldDictionary::Entry* entry = *itr;
- if (String(entry->slotName).startsWith(pFieldName))
- {
- setDataField(entry->slotName, NULL, "");
- }
- }
- }
- //-----------------------------------------------------------------------------
- void AssetBase::addAssetDependencyField(const char* pFieldName, const char* pAssetId)
- {
- U32 existingFieldCount = getAssetDependencyFieldCount(pFieldName);
- //we have a match!
- char depSlotName[50];
- dSprintf(depSlotName, sizeof(depSlotName), "%s%d", pFieldName, existingFieldCount);
- char depValue[255];
- dSprintf(depValue, sizeof(depValue), "%s=%s", ASSET_ID_SIGNATURE, pAssetId);
- setDataField(StringTable->insert(depSlotName), NULL, StringTable->insert(depValue));
- }
- //-----------------------------------------------------------------------------
- bool AssetBase::saveAsset()
- {
- // Set the format mode.
- Taml taml;
- // Yes, so set it.
- taml.setFormatMode(Taml::getFormatModeEnum("xml"));
- // Turn-off auto-formatting.
- taml.setAutoFormat(false);
- // Read object.
- bool success = taml.write(this, AssetDatabase.getAssetFilePath(getAssetId()));
- if (!success)
- return false;
- return true;
- }
- //-----------------------------------------------------------------------------
- void AssetBase::acquireAssetReference(void)
- {
- // Acquired the acquired reference count.
- if (mpOwningAssetManager != NULL)
- mpOwningAssetManager->acquireAcquiredReferenceCount();
- mAcquireReferenceCount++;
- }
- //-----------------------------------------------------------------------------
- bool AssetBase::releaseAssetReference(void)
- {
- // Are there any acquisition references?
- if (mAcquireReferenceCount == 0)
- {
- // Return "unload" unless auto unload is off.
- return mpAssetDefinition->mAssetAutoUnload;
- }
- // Release the acquired reference count.
- if (mpOwningAssetManager != NULL)
- mpOwningAssetManager->releaseAcquiredReferenceCount();
- // Release reference.
- mAcquireReferenceCount--;
- // Are there any acquisition references?
- if (mAcquireReferenceCount == 0)
- {
- // No, so return "unload" unless auto unload is off.
- return mpAssetDefinition->mAssetAutoUnload;
- }
- // Return "don't unload".
- return false;
- }
- //-----------------------------------------------------------------------------
- void AssetBase::setOwned(AssetManager* pAssetManager, AssetDefinition* pAssetDefinition)
- {
- // Debug Profiling.
- PROFILE_SCOPE(AssetBase_setOwned);
- // Sanity!
- AssertFatal(pAssetManager != NULL, "Cannot set asset ownership with NULL asset manager.");
- AssertFatal(mpOwningAssetManager == NULL, "Cannot set asset ownership if it is already owned.");
- AssertFatal(pAssetDefinition != NULL, "Cannot set asset ownership with a NULL asset definition.");
- AssertFatal(mpAssetDefinition != NULL, "Asset ownership assigned but has a NULL asset definition.");
- AssertFatal(mpAssetDefinition->mAssetName == pAssetDefinition->mAssetName, "Asset ownership differs by asset name.");
- AssertFatal(mpAssetDefinition->mAssetDescription == pAssetDefinition->mAssetDescription, "Asset ownership differs by asset description.");
- AssertFatal(mpAssetDefinition->mAssetCategory == pAssetDefinition->mAssetCategory, "Asset ownership differs by asset category.");
- AssertFatal(mpAssetDefinition->mAssetAutoUnload == pAssetDefinition->mAssetAutoUnload, "Asset ownership differs by asset auto-unload flag.");
- AssertFatal(mpAssetDefinition->mAssetInternal == pAssetDefinition->mAssetInternal, "Asset ownership differs by asset internal flag.");
- // Transfer asset definition ownership state.
- delete mpAssetDefinition;
- mpAssetDefinition = pAssetDefinition;
- // Flag as owned.
- // NOTE: This must be done prior to initializing the asset so any initialization can assume ownership.
- mpOwningAssetManager = pAssetManager;
- // Initialize the asset.
- initializeAsset();
- // Flag asset as initialized.
- mAssetInitialized = true;
- }
|