From 220771d2fe7e863b4ae9b155dc906a13f9c82977 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 1 Dec 2020 19:16:36 -0600 Subject: [PATCH 1/3] variation on #387 that also introduces errorcodes --- Engine/source/T3D/assets/ShapeAsset.cpp | 36 +++++++---- Engine/source/T3D/assets/ShapeAsset.h | 80 ++++++++++++++++++++++++- Engine/source/T3D/shapeBase.cpp | 17 ++---- Engine/source/assets/assetBase.h | 13 ++++ 4 files changed, 123 insertions(+), 23 deletions(-) diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index d0b652851..0c89ae5b1 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -119,6 +119,7 @@ ShapeAsset::ShapeAsset() mConstructorFileName = StringTable->EmptyString(); mFilePath = StringTable->EmptyString(); mConstructorFilePath = StringTable->EmptyString(); + mLoadedState = AssetErrCode::NotLoaded; } //----------------------------------------------------------------------------- @@ -264,7 +265,8 @@ bool ShapeAsset::loadShape() if (!mShape) { - Con::errorf("StaticMesh::updateShape : failed to load shape file!"); + Con::errorf("ShapeAsset::loadShape : failed to load shape file!"); + mLoadedState = BadFileReference; return false; //if it failed to load, bail out } @@ -280,8 +282,10 @@ bool ShapeAsset::loadShape() if (!mShape->addSequence(srcPath, srcName, srcName, mAnimationAssets[i]->getStartFrame(), mAnimationAssets[i]->getEndFrame(), mAnimationAssets[i]->getPadRotation(), mAnimationAssets[i]->getPadTransforms())) + { + mLoadedState = MissingAnimatons; return false; - + } if (mAnimationAssets[i]->isBlend()) hasBlends = true; } @@ -300,14 +304,20 @@ bool ShapeAsset::loadShape() if (blendAnimAsset.isNull()) { Con::errorf("ShapeAsset::initializeAsset - Unable to acquire reference animation asset %s for asset %s to blend!", mAnimationAssets[i]->getBlendAnimationName(), mAnimationAssets[i]->getAssetName()); - return false; + { + mLoadedState = MissingAnimatons; + return false; + } } String refAnimName = blendAnimAsset->getAnimationName(); if (!mShape->setSequenceBlend(mAnimationAssets[i]->getAnimationName(), true, blendAnimAsset->getAnimationName(), mAnimationAssets[i]->getBlendFrame())) { Con::errorf("ShapeAnimationAsset::initializeAsset - Unable to set animation clip %s for asset %s to blend!", mAnimationAssets[i]->getAnimationName(), mAnimationAssets[i]->getAssetName()); - return false; + { + mLoadedState = MissingAnimatons; + return false; + } } } } @@ -315,6 +325,7 @@ bool ShapeAsset::loadShape() mChangeSignal.trigger(); + mLoadedState = Ok; return true; } @@ -410,21 +421,21 @@ StringTableEntry ShapeAsset::getAssetIdByFilename(StringTableEntry fileName) return shapeAssetId; } -bool ShapeAsset::getAssetById(StringTableEntry assetId, AssetPtr* shapeAsset) +U32 ShapeAsset::getAssetById(StringTableEntry assetId, AssetPtr* shapeAsset) { (*shapeAsset) = assetId; - if (!shapeAsset->isNull()) - return true; + if ((*shapeAsset)) + return (*shapeAsset)->mLoadedState; //Didn't work, so have us fall back to a placeholder asset StringTableEntry noShapeId = StringTable->insert("Core_Rendering:noshape"); shapeAsset->setAssetId(noShapeId); + (*shapeAsset)->mLoadedState = AssetErrCode::UsingFallback; + if (shapeAsset->notNull()) + return AssetErrCode::UsingFallback; - if (!shapeAsset->isNull()) - return true; - - return false; + return AssetErrCode::Failed; } //------------------------------------------------------------------------------ @@ -503,6 +514,7 @@ DefineEngineMethod(ShapeAsset, getAnimation, ShapeAnimationAsset*, (S32 index), // GuiInspectorTypeAssetId //----------------------------------------------------------------------------- +#ifdef TORQUE_TOOLS IMPLEMENT_CONOBJECT(GuiInspectorTypeShapeAssetPtr); ConsoleDocClass(GuiInspectorTypeShapeAssetPtr, @@ -596,6 +608,8 @@ void GuiInspectorTypeShapeAssetId::consoleInit() ConsoleBaseType::getType(TypeShapeAssetId)->setInspectorFieldType("GuiInspectorTypeShapeAssetId"); } +#endif + DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), , "Creates a new script asset using the targetFilePath.\n" "@return The bool result of calling exec") diff --git a/Engine/source/T3D/assets/ShapeAsset.h b/Engine/source/T3D/assets/ShapeAsset.h index 65e0a4ca9..3843379e7 100644 --- a/Engine/source/T3D/assets/ShapeAsset.h +++ b/Engine/source/T3D/assets/ShapeAsset.h @@ -54,7 +54,9 @@ #include "ShapeAnimationAsset.h" #endif +#ifdef TORQUE_TOOLS #include "gui/editor/guiInspectorTypes.h" +#endif //----------------------------------------------------------------------------- class ShapeAsset : public AssetBase @@ -81,6 +83,13 @@ protected: ShapeAssetChanged mChangeSignal; public: + enum ShapeAssetErrCode + { + TooManyVerts = AssetErrCode::Extended, + TooManyBones, + MissingAnimatons + }; + ShapeAsset(); virtual ~ShapeAsset(); @@ -96,6 +105,7 @@ public: DECLARE_CONOBJECT(ShapeAsset); bool loadShape(); + U32 mLoadedState; TSShape* getShape() { return mShape; } @@ -138,8 +148,9 @@ public: inline StringTableEntry getShapeConstructorFilePath(void) const { return mConstructorFilePath; }; static bool getAssetByFilename(StringTableEntry fileName, AssetPtr* shapeAsset); + static StringTableEntry getAssetIdByFilename(StringTableEntry fileName); - static bool getAssetById(StringTableEntry assetId, AssetPtr* shapeAsset); + static U32 getAssetById(StringTableEntry assetId, AssetPtr* shapeAsset); static StringTableEntry getNoShapeAssetId() { return StringTable->insert("Core_Rendering:noshape"); } @@ -154,6 +165,7 @@ protected: }; +#ifdef TORQUE_TOOLS DefineConsoleType(TypeShapeAssetPtr, S32) DefineConsoleType(TypeShapeAssetId, String) @@ -182,6 +194,72 @@ public: DECLARE_CONOBJECT(GuiInspectorTypeShapeAssetId); static void consoleInit(); }; +#endif + +#define assetText(x,suff) std::string(std::string(#x) + std::string(#suff)).c_str() + +#define initShapeAsset(name) m##name##Filename = StringTable->EmptyString(); m##name##AssetId = StringTable->EmptyString(); m##name##Asset = NULL; +#define bindShapeAsset(name) if (m##name##AssetId != StringTable->EmptyString()) m##name##Asset = m##name##AssetId; + +#define scriptBindShapeAsset(name, consoleClass, docs) addProtectedField(assetText(name, File), TypeShapeFilename, Offset(m##name##Filename, consoleClass), consoleClass::_set##name##Filename, & defaultProtectedGetFn, assetText(name, docs)); \ + addProtectedField(assetText(name, Asset), TypeShapeAssetId, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.)); + +#define DECLARE_SHAPEASSET(className,name) protected: \ + StringTableEntry m##name##Filename;\ + StringTableEntry m##name##AssetId;\ + AssetPtr m##name##Asset;\ + public: \ + const StringTableEntry& get##name() const { return m##name##Filename; }\ + void set##name(FileName _in) { m##name##Filename = _in; }\ + const AssetPtr & get##name##Asset() const { return m##name##Asset; }\ + void set##name##Asset(AssetPtr_in) { m##name##Asset = _in; }\ +static bool _set##name##Filename(void* obj, const char* index, const char* data)\ +{\ + className* shape = static_cast(obj);\ + \ + StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(StringTable->insert(data));\ + if (assetId != StringTable->EmptyString())\ + {\ + if (shape->_set##name##Asset(obj, index, assetId))\ + {\ + if (assetId == StringTable->insert("Core_Rendering:noShape"))\ + {\ + shape->m##name##Filename = data;\ + shape->m##name##AssetId = StringTable->EmptyString();\ + \ + return true;\ + }\ + else\ + {\ + shape->m##name##AssetId = assetId;\ + shape->m##name##Filename = StringTable->EmptyString();\ + \ + return false;\ + }\ + }\ + }\ + else\ + {\ + shape->m##name##Asset = StringTable->EmptyString();\ + }\ + \ + return true;\ +}\ +\ +static bool _set##name##Asset(void* obj, const char* index, const char* data)\ +{\ + className* shape = static_cast(obj);\ + shape->m##name##AssetId = StringTable->insert(data);\ + if (ShapeAsset::getAssetById(shape->m##name##AssetId, &shape->m##name##Asset))\ + {\ + if (shape->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noShape"))\ + shape->m##name##Filename = StringTable->EmptyString();\ + \ + shape->setMaskBits(-1);\ + return true;\ + }\ + return false;\ +} #endif diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index 6f70e2760..29c5b8b8c 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/Engine/source/T3D/shapeBase.cpp @@ -361,20 +361,15 @@ bool ShapeBaseData::preload(bool server, String &errorStr) } //Legacy catch - if (shapeAssetId == StringTable->EmptyString() && shapeName != StringTable->EmptyString()) + if (shapeName != StringTable->EmptyString()) { - StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(shapeName); - if (assetId != StringTable->EmptyString()) - { - shapeAssetId = assetId; - } + shapeAssetId = ShapeAsset::getAssetIdByFilename(shapeName); } - - if (ShapeAsset::getAssetById(shapeAssetId, &shapeAsset)) + U32 assetState = ShapeAsset::getAssetById(shapeAssetId, &shapeAsset); + if (AssetErrCode::Failed != assetState) { - //Special exception case. If we've defaulted to the 'no shape' mesh, don't save it out, we'll retain the original ids/paths so it doesn't break - //the TSStatic - if (shapeAsset.getAssetId() != StringTable->insert("Core_Rendering:noshape")) + //only clear the legacy direct file reference if everything checks out fully + if (assetState == AssetErrCode::Ok) { shapeName = StringTable->EmptyString(); } diff --git a/Engine/source/assets/assetBase.h b/Engine/source/assets/assetBase.h index f127c83cc..cdffbc14e 100644 --- a/Engine/source/assets/assetBase.h +++ b/Engine/source/assets/assetBase.h @@ -56,6 +56,19 @@ extern StringTableEntry assetAutoUnloadField; //----------------------------------------------------------------------------- +enum AssetErrCode +{ + Failed, + Ok, + NotLoaded, + BadFileReference, + InvalidFormat, + DependencyNotFound, + FileTooLarge, + UsingFallback, + Extended +}; + class AssetBase : public SimObject { friend class AssetManager; From 8bb43dd5ae20b89e93d79aab67d9110876c75b4c Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Thu, 3 Dec 2020 15:37:51 -0600 Subject: [PATCH 2/3] error string interpreter, example of usage in shapebase::preload, plus flips the datablock filter back on to save some network bandwidth. --- Engine/source/T3D/assets/ShapeAsset.cpp | 9 +++++++ Engine/source/T3D/assets/ShapeAsset.h | 11 +++++++- Engine/source/T3D/shapeBase.cpp | 24 ++++++++++++----- Engine/source/assets/assetBase.cpp | 12 +++++++++ Engine/source/assets/assetBase.h | 34 +++++++++++++++---------- 5 files changed, 68 insertions(+), 22 deletions(-) diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index 0c89ae5b1..1f667fb6f 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -113,6 +113,15 @@ ConsoleSetType(TypeShapeAssetId) //----------------------------------------------------------------------------- +const String ShapeAsset::mErrCodeStrings[] = +{ + "TooManyVerts", + "TooManyBones", + "MissingAnimatons", + "UnKnown" +}; +//----------------------------------------------------------------------------- + ShapeAsset::ShapeAsset() { mFileName = StringTable->EmptyString(); diff --git a/Engine/source/T3D/assets/ShapeAsset.h b/Engine/source/T3D/assets/ShapeAsset.h index 3843379e7..5db8837af 100644 --- a/Engine/source/T3D/assets/ShapeAsset.h +++ b/Engine/source/T3D/assets/ShapeAsset.h @@ -87,7 +87,16 @@ public: { TooManyVerts = AssetErrCode::Extended, TooManyBones, - MissingAnimatons + MissingAnimatons, + Extended + }; + + static const String mErrCodeStrings[ShapeAssetErrCode::Extended - Parent::Extended + 1]; + static String getAssetErrstrn(U32 errCode) + { + if (errCode < Parent::Extended) return Parent::getAssetErrstrn(errCode); + if (errCode > ShapeAssetErrCode::Extended) return "undefined error"; + return mErrCodeStrings[errCode]; }; ShapeAsset(); diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index 29c5b8b8c..72f537141 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/Engine/source/T3D/shapeBase.cpp @@ -366,14 +366,14 @@ bool ShapeBaseData::preload(bool server, String &errorStr) shapeAssetId = ShapeAsset::getAssetIdByFilename(shapeName); } U32 assetState = ShapeAsset::getAssetById(shapeAssetId, &shapeAsset); - if (AssetErrCode::Failed != assetState) + if (ShapeAsset::Failed != assetState) { //only clear the legacy direct file reference if everything checks out fully - if (assetState == AssetErrCode::Ok) + if (assetState == ShapeAsset::Ok) { shapeName = StringTable->EmptyString(); } - + else Con::warnf("Warning: ShapeBaseData::preload-%s", ShapeAsset::getAssetErrstrn(assetState).c_str()); S32 i; // Resolve shapename @@ -798,10 +798,14 @@ void ShapeBaseData::packData(BitStream* stream) stream->write(shadowSphereAdjust); - //if (stream->writeFlag(shapeAsset.notNull())) + if (stream->writeFlag(shapeAsset.notNull())) + { stream->writeString(shapeAsset.getAssetId()); - //else + } + else + { stream->writeString(shapeName); + } stream->writeString(cloakTexName); if(stream->writeFlag(mass != gShapeBaseDataProto.mass)) @@ -880,10 +884,16 @@ void ShapeBaseData::unpackData(BitStream* stream) stream->read(&shadowSphereAdjust); - //if (stream->readFlag()) + if (stream->readFlag()) + { shapeAssetId = stream->readSTString(); - //else + ShapeAsset::getAssetById(shapeAssetId, &shapeAsset); + shapeName = shapeAsset->getShapeFilename(); + } + else + { shapeName = stream->readSTString(); + } cloakTexName = stream->readSTString(); if(stream->readFlag()) diff --git a/Engine/source/assets/assetBase.cpp b/Engine/source/assets/assetBase.cpp index 2eb33a299..14bc3026e 100644 --- a/Engine/source/assets/assetBase.cpp +++ b/Engine/source/assets/assetBase.cpp @@ -52,6 +52,18 @@ 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), diff --git a/Engine/source/assets/assetBase.h b/Engine/source/assets/assetBase.h index cdffbc14e..b6480f0b1 100644 --- a/Engine/source/assets/assetBase.h +++ b/Engine/source/assets/assetBase.h @@ -55,20 +55,6 @@ extern StringTableEntry assetAutoUnloadField; //#define ASSET_BASE_AUTOUNLOAD_FIELD "AssetAutoUnload" //----------------------------------------------------------------------------- - -enum AssetErrCode -{ - Failed, - Ok, - NotLoaded, - BadFileReference, - InvalidFormat, - DependencyNotFound, - FileTooLarge, - UsingFallback, - Extended -}; - class AssetBase : public SimObject { friend class AssetManager; @@ -82,6 +68,26 @@ protected: U32 mAcquireReferenceCount; public: + enum AssetErrCode + { + Failed, + Ok, + NotLoaded, + BadFileReference, + InvalidFormat, + DependencyNotFound, + FileTooLarge, + UsingFallback, + Extended + }; + + static const String mErrCodeStrings[AssetErrCode::Extended + 1]; + static String getAssetErrstrn(U32 errCode) + { + if (errCode > AssetErrCode::Extended) return "undefined error"; + return mErrCodeStrings[errCode]; + }; + AssetBase(); virtual ~AssetBase(); From ae5f766abec43446a2b34c1eb1209cb042c2cac9 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Thu, 3 Dec 2020 15:38:42 -0600 Subject: [PATCH 3/3] just to save a PR: default asset visitor variables to emptystring --- Engine/source/assets/tamlAssetDeclaredUpdateVisitor.h | 5 ++++- Engine/source/assets/tamlAssetReferencedUpdateVisitor.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Engine/source/assets/tamlAssetDeclaredUpdateVisitor.h b/Engine/source/assets/tamlAssetDeclaredUpdateVisitor.h index 7a022d1d2..54a4de8e9 100644 --- a/Engine/source/assets/tamlAssetDeclaredUpdateVisitor.h +++ b/Engine/source/assets/tamlAssetDeclaredUpdateVisitor.h @@ -49,7 +49,10 @@ private: StringTableEntry mAssetNameTo; public: - TamlAssetDeclaredUpdateVisitor() {} + TamlAssetDeclaredUpdateVisitor(): + mAssetIdFrom(StringTable->EmptyString()), mAssetIdTo(StringTable->EmptyString()), + mAssetNameFrom(StringTable->EmptyString()), mAssetNameTo(StringTable->EmptyString()) {} + virtual ~TamlAssetDeclaredUpdateVisitor() {} void setAssetIdFrom( const char* pAssetIdFrom ) diff --git a/Engine/source/assets/tamlAssetReferencedUpdateVisitor.h b/Engine/source/assets/tamlAssetReferencedUpdateVisitor.h index 3bf3623a4..499fc7428 100644 --- a/Engine/source/assets/tamlAssetReferencedUpdateVisitor.h +++ b/Engine/source/assets/tamlAssetReferencedUpdateVisitor.h @@ -55,7 +55,7 @@ private: StringTableEntry mAssetIdTo; public: - TamlAssetReferencedUpdateVisitor() {} + TamlAssetReferencedUpdateVisitor() : mAssetIdFrom(StringTable->EmptyString()), mAssetIdTo(StringTable->EmptyString()) {} virtual ~TamlAssetReferencedUpdateVisitor() {} void setAssetIdFrom( const char* pAssetIdFrom )