mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 23:54:35 +00:00
Enforces filename string case sensitivity for assets' internal filenames, which avoids the stringtable messing with the case preventing file name case sensitivity issues.
This commit is contained in:
parent
c04f3ae166
commit
cfe122f714
18 changed files with 109 additions and 102 deletions
|
|
@ -132,14 +132,14 @@ void CppAsset::setCppFile(const char* pCppFile)
|
||||||
AssertFatal(pCppFile != NULL, "Cannot use a NULL code file.");
|
AssertFatal(pCppFile != NULL, "Cannot use a NULL code file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pCppFile = StringTable->insert(pCppFile);
|
pCppFile = StringTable->insert(pCppFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pCppFile == mCodeFile)
|
if (pCppFile == mCodeFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mCodeFile = /*getOwned() ? expandAssetFilePath(pCppFile) : */StringTable->insert(pCppFile);
|
mCodeFile = getOwned() ? expandAssetFilePath(pCppFile) : pCppFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -158,7 +158,7 @@ void CppAsset::setHeaderFile(const char* pHeaderFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mHeaderFile = /*getOwned() ? expandAssetFilePath(pHeaderFile) :*/ StringTable->insert(pHeaderFile);
|
mHeaderFile = getOwned() ? expandAssetFilePath(pHeaderFile) : pHeaderFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -134,18 +134,21 @@ void CubemapAsset::copyTo(SimObject* object)
|
||||||
|
|
||||||
void CubemapAsset::initializeAsset()
|
void CubemapAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mScriptFile = expandAssetFilePath(mScriptFile);
|
// Call parent.
|
||||||
|
Parent::initializeAsset();
|
||||||
|
|
||||||
if(Torque::FS::IsScriptFile(mScriptFile))
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
Con::executeFile(mScriptFile, false, false);
|
|
||||||
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
|
Con::executeFile(mScriptPath, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubemapAsset::onAssetRefresh()
|
void CubemapAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mScriptFile = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptFile))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptFile, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubemapAsset::setScriptFile(const char* pScriptFile)
|
void CubemapAsset::setScriptFile(const char* pScriptFile)
|
||||||
|
|
@ -154,14 +157,14 @@ void CubemapAsset::setScriptFile(const char* pScriptFile)
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pScriptFile == mScriptFile)
|
if (pScriptFile == mScriptFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : StringTable->insert(pScriptFile);
|
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ class CubemapAsset : public AssetBase
|
||||||
StringTableEntry mDescription;
|
StringTableEntry mDescription;
|
||||||
|
|
||||||
StringTableEntry mScriptFile;
|
StringTableEntry mScriptFile;
|
||||||
|
StringTableEntry mScriptPath;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CubemapAsset();
|
CubemapAsset();
|
||||||
|
|
|
||||||
|
|
@ -117,12 +117,12 @@ void GUIAsset::copyTo(SimObject* object)
|
||||||
|
|
||||||
void GUIAsset::initializeAsset()
|
void GUIAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mGUIPath = expandAssetFilePath(mGUIFile);
|
mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mGUIPath))
|
if (Torque::FS::IsScriptFile(mGUIPath))
|
||||||
Con::executeFile(mGUIPath, false, false);
|
Con::executeFile(mGUIPath, false, false);
|
||||||
|
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
@ -130,12 +130,12 @@ void GUIAsset::initializeAsset()
|
||||||
|
|
||||||
void GUIAsset::onAssetRefresh()
|
void GUIAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mGUIPath = expandAssetFilePath(mGUIFile);
|
mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mGUIPath))
|
if (Torque::FS::IsScriptFile(mGUIPath))
|
||||||
Con::executeFile(mGUIPath, false, false);
|
Con::executeFile(mGUIPath, false, false);
|
||||||
|
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
@ -147,14 +147,14 @@ void GUIAsset::setGUIFile(const char* pScriptFile)
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL gui file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL gui file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pScriptFile == mGUIFile)
|
if (pScriptFile == mGUIFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mGUIFile = StringTable->insert(pScriptFile);
|
mGUIFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -166,14 +166,14 @@ void GUIAsset::setScriptFile(const char* pScriptFile)
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pScriptFile == mScriptFile)
|
if (pScriptFile == mScriptFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mScriptFile = StringTable->insert(pScriptFile);
|
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -156,10 +156,10 @@ void GameObjectAsset::setScriptFile(const char* pScriptFile)
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pScriptFile == mScriptFile)
|
if (pScriptFile == mTAMLFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
|
|
@ -176,7 +176,7 @@ void GameObjectAsset::setTAMLFile(const char* pTAMLFile)
|
||||||
AssertFatal(pTAMLFile != NULL, "Cannot use a NULL TAML file.");
|
AssertFatal(pTAMLFile != NULL, "Cannot use a NULL TAML file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pTAMLFile = StringTable->insert(pTAMLFile);
|
pTAMLFile = StringTable->insert(pTAMLFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pTAMLFile == mTAMLFile)
|
if (pTAMLFile == mTAMLFile)
|
||||||
|
|
|
||||||
|
|
@ -296,21 +296,15 @@ void ImageAsset::loadImage()
|
||||||
|
|
||||||
void ImageAsset::initializeAsset()
|
void ImageAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
if (mImageFileName == StringTable->insert("z.png"))
|
|
||||||
{
|
|
||||||
Con::printf("Loaded z");
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceManager::get().getChangedSignal().notify(this, &ImageAsset::_onResourceChanged);
|
ResourceManager::get().getChangedSignal().notify(this, &ImageAsset::_onResourceChanged);
|
||||||
|
|
||||||
mImagePath = expandAssetFilePath(mImageFileName);
|
mImagePath = getOwned() ? expandAssetFilePath(mImageFileName) : mImagePath;
|
||||||
loadImage();
|
loadImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageAsset::onAssetRefresh()
|
void ImageAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mImagePath = expandAssetFilePath(mImageFileName);
|
mImagePath = getOwned() ? expandAssetFilePath(mImageFileName) : mImagePath;
|
||||||
|
|
||||||
loadImage();
|
loadImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -321,7 +315,7 @@ void ImageAsset::_onResourceChanged(const Torque::Path& path)
|
||||||
|
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
||||||
loadImage();
|
//loadImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageAsset::setImageFileName(const char* pScriptFile)
|
void ImageAsset::setImageFileName(const char* pScriptFile)
|
||||||
|
|
@ -330,7 +324,10 @@ void ImageAsset::setImageFileName(const char* pScriptFile)
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL image file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL image file.");
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mImageFileName = StringTable->insert(pScriptFile);
|
mImageFileName = StringTable->insert(pScriptFile, true);
|
||||||
|
|
||||||
|
// Refresh the asset.
|
||||||
|
refreshAsset();
|
||||||
}
|
}
|
||||||
|
|
||||||
const GBitmap& ImageAsset::getImage()
|
const GBitmap& ImageAsset::getImage()
|
||||||
|
|
|
||||||
|
|
@ -161,11 +161,11 @@ void LevelAsset::onAssetRefresh(void)
|
||||||
void LevelAsset::loadAsset()
|
void LevelAsset::loadAsset()
|
||||||
{
|
{
|
||||||
// Ensure the image-file is expanded.
|
// Ensure the image-file is expanded.
|
||||||
mLevelPath = expandAssetFilePath(mLevelFile);
|
mLevelPath = getOwned() ? expandAssetFilePath(mLevelFile) : mLevelPath;
|
||||||
mPostFXPresetPath = expandAssetFilePath(mPostFXPresetFile);
|
mPostFXPresetPath = getOwned() ? expandAssetFilePath(mPostFXPresetFile) : mPostFXPresetPath;
|
||||||
mDecalsPath = expandAssetFilePath(mDecalsFile);
|
mDecalsPath = getOwned() ? expandAssetFilePath(mDecalsFile) : mDecalsPath;
|
||||||
mForestPath = expandAssetFilePath(mForestFile);
|
mForestPath = getOwned() ? expandAssetFilePath(mForestFile) : mForestPath;
|
||||||
mNavmeshPath = expandAssetFilePath(mNavmeshFile);
|
mNavmeshPath = getOwned() ? expandAssetFilePath(mNavmeshFile) : mNavmeshPath;
|
||||||
|
|
||||||
StringTableEntry previewImageAssetId = getAssetDependencyField("previewImageAsset");
|
StringTableEntry previewImageAssetId = getAssetDependencyField("previewImageAsset");
|
||||||
|
|
||||||
|
|
@ -183,14 +183,14 @@ void LevelAsset::setLevelFile(const char* pLevelFile)
|
||||||
AssertFatal(pLevelFile != NULL, "Cannot use a NULL level file.");
|
AssertFatal(pLevelFile != NULL, "Cannot use a NULL level file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pLevelFile = StringTable->insert(pLevelFile);
|
pLevelFile = StringTable->insert(pLevelFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pLevelFile == mLevelFile)
|
if (pLevelFile == mLevelFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mLevelFile = pLevelFile;
|
mLevelFile = getOwned() ? expandAssetFilePath(pLevelFile) : pLevelFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -217,14 +217,14 @@ void LevelAsset::setEditorFile(const char* pEditorFile)
|
||||||
AssertFatal(pEditorFile != NULL, "Cannot use a NULL level file.");
|
AssertFatal(pEditorFile != NULL, "Cannot use a NULL level file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pEditorFile = StringTable->insert(pEditorFile);
|
pEditorFile = StringTable->insert(pEditorFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pEditorFile == mEditorFile)
|
if (pEditorFile == mEditorFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mEditorFile = pEditorFile;
|
mEditorFile = getOwned() ? expandAssetFilePath(pEditorFile) : pEditorFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -236,14 +236,14 @@ void LevelAsset::setBakedSceneFile(const char* pBakedSceneFile)
|
||||||
AssertFatal(pBakedSceneFile != NULL, "Cannot use a NULL level file.");
|
AssertFatal(pBakedSceneFile != NULL, "Cannot use a NULL level file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pBakedSceneFile = StringTable->insert(pBakedSceneFile);
|
pBakedSceneFile = StringTable->insert(pBakedSceneFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pBakedSceneFile == mBakedSceneFile)
|
if (pBakedSceneFile == mBakedSceneFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mBakedSceneFile = pBakedSceneFile;
|
mBakedSceneFile = getOwned() ? expandAssetFilePath(pBakedSceneFile) : pBakedSceneFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -255,14 +255,14 @@ void LevelAsset::setPostFXPresetFile(const char* pPostFXPresetFile)
|
||||||
AssertFatal(pPostFXPresetFile != NULL, "Cannot use a NULL postFX preset file.");
|
AssertFatal(pPostFXPresetFile != NULL, "Cannot use a NULL postFX preset file.");
|
||||||
|
|
||||||
// Fetch file.
|
// Fetch file.
|
||||||
pPostFXPresetFile = StringTable->insert(pPostFXPresetFile);
|
pPostFXPresetFile = StringTable->insert(pPostFXPresetFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pPostFXPresetFile == mPostFXPresetFile)
|
if (pPostFXPresetFile == mPostFXPresetFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mPostFXPresetFile = pPostFXPresetFile;
|
mPostFXPresetFile = getOwned() ? expandAssetFilePath(pPostFXPresetFile) : pPostFXPresetFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -274,14 +274,14 @@ void LevelAsset::setDecalsFile(const char* pDecalsFile)
|
||||||
AssertFatal(pDecalsFile != NULL, "Cannot use a NULL decals file.");
|
AssertFatal(pDecalsFile != NULL, "Cannot use a NULL decals file.");
|
||||||
|
|
||||||
// Fetch file.
|
// Fetch file.
|
||||||
pDecalsFile = StringTable->insert(pDecalsFile);
|
pDecalsFile = StringTable->insert(pDecalsFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pDecalsFile == mDecalsFile)
|
if (pDecalsFile == mDecalsFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mDecalsFile = pDecalsFile;
|
mDecalsFile = getOwned() ? expandAssetFilePath(pDecalsFile) : pDecalsFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -293,14 +293,14 @@ void LevelAsset::setForestFile(const char* pForestFile)
|
||||||
AssertFatal(pForestFile != NULL, "Cannot use a NULL decals file.");
|
AssertFatal(pForestFile != NULL, "Cannot use a NULL decals file.");
|
||||||
|
|
||||||
// Fetch file.
|
// Fetch file.
|
||||||
pForestFile = StringTable->insert(pForestFile);
|
pForestFile = StringTable->insert(pForestFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pForestFile == mForestFile)
|
if (pForestFile == mForestFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mForestFile = pForestFile;
|
mForestFile = getOwned() ? expandAssetFilePath(pForestFile) : pForestFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -312,14 +312,14 @@ void LevelAsset::setNavmeshFile(const char* pNavmeshFile)
|
||||||
AssertFatal(pNavmeshFile != NULL, "Cannot use a NULL Navmesh file.");
|
AssertFatal(pNavmeshFile != NULL, "Cannot use a NULL Navmesh file.");
|
||||||
|
|
||||||
// Fetch file.
|
// Fetch file.
|
||||||
pNavmeshFile = StringTable->insert(pNavmeshFile);
|
pNavmeshFile = StringTable->insert(pNavmeshFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pNavmeshFile == mNavmeshFile)
|
if (pNavmeshFile == mNavmeshFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mNavmeshFile = pNavmeshFile;
|
mNavmeshFile = getOwned() ? expandAssetFilePath(pNavmeshFile) : pNavmeshFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ void MaterialAsset::setScriptFile(const char* pScriptFile)
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,11 @@ protected:
|
||||||
virtual void initializeAsset();
|
virtual void initializeAsset();
|
||||||
virtual void onAssetRefresh(void);
|
virtual void onAssetRefresh(void);
|
||||||
|
|
||||||
static bool setScriptFile(void *obj, const char *index, const char *data) { static_cast<MaterialAsset*>(obj)->setScriptFile(data); return false; }
|
static bool setScriptFile(void *obj, const char *index, const char *data)
|
||||||
|
{
|
||||||
|
static_cast<MaterialAsset*>(obj)->setScriptFile(data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
static const char* getScriptFile(void* obj, const char* data) { return static_cast<MaterialAsset*>(obj)->getScriptFile(); }
|
static const char* getScriptFile(void* obj, const char* data) { return static_cast<MaterialAsset*>(obj)->getScriptFile(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,9 +132,9 @@ void PostEffectAsset::copyTo(SimObject* object)
|
||||||
|
|
||||||
void PostEffectAsset::initializeAsset()
|
void PostEffectAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
mHLSLShaderPath = expandAssetFilePath(mHLSLShaderFile);
|
mHLSLShaderPath = getOwned() ? expandAssetFilePath(mHLSLShaderFile) : mHLSLShaderPath;
|
||||||
mGLSLShaderPath = expandAssetFilePath(mGLSLShaderFile);
|
mGLSLShaderPath = getOwned() ? expandAssetFilePath(mGLSLShaderFile) : mGLSLShaderPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
@ -142,9 +142,9 @@ void PostEffectAsset::initializeAsset()
|
||||||
|
|
||||||
void PostEffectAsset::onAssetRefresh()
|
void PostEffectAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
mHLSLShaderPath = expandAssetFilePath(mHLSLShaderFile);
|
mHLSLShaderPath = getOwned() ? expandAssetFilePath(mHLSLShaderFile) : mHLSLShaderPath;
|
||||||
mGLSLShaderPath = expandAssetFilePath(mGLSLShaderFile);
|
mGLSLShaderPath = getOwned() ? expandAssetFilePath(mGLSLShaderFile) : mGLSLShaderPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
@ -156,14 +156,14 @@ void PostEffectAsset::setScriptFile(const char* pScriptFile)
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pScriptFile == mScriptFile)
|
if (pScriptFile == mScriptFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mScriptFile = pScriptFile;
|
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -175,14 +175,14 @@ void PostEffectAsset::setHLSLShaderFile(const char* pShaderFile)
|
||||||
AssertFatal(pShaderFile != NULL, "Cannot use a NULL shader file.");
|
AssertFatal(pShaderFile != NULL, "Cannot use a NULL shader file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pShaderFile = StringTable->insert(pShaderFile);
|
pShaderFile = StringTable->insert(pShaderFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pShaderFile == mHLSLShaderFile)
|
if (pShaderFile == mHLSLShaderFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mHLSLShaderFile = pShaderFile;
|
mHLSLShaderFile = getOwned() ? expandAssetFilePath(pShaderFile) : pShaderFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -194,14 +194,14 @@ void PostEffectAsset::setGLSLShaderFile(const char* pShaderFile)
|
||||||
AssertFatal(pShaderFile != NULL, "Cannot use a NULL shader file.");
|
AssertFatal(pShaderFile != NULL, "Cannot use a NULL shader file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pShaderFile = StringTable->insert(pShaderFile);
|
pShaderFile = StringTable->insert(pShaderFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pShaderFile == mGLSLShaderFile)
|
if (pShaderFile == mGLSLShaderFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mGLSLShaderFile = pShaderFile;
|
mGLSLShaderFile = getOwned() ? expandAssetFilePath(pShaderFile) : pShaderFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ void ScriptAsset::copyTo(SimObject* object)
|
||||||
|
|
||||||
void ScriptAsset::initializeAsset()
|
void ScriptAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
{
|
{
|
||||||
|
|
@ -150,7 +150,7 @@ void ScriptAsset::initializeAsset()
|
||||||
|
|
||||||
void ScriptAsset::onAssetRefresh()
|
void ScriptAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
{
|
{
|
||||||
|
|
@ -170,14 +170,14 @@ void ScriptAsset::setScriptFile(const char* pScriptFile)
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pScriptFile == mScriptFile)
|
if (pScriptFile == mScriptFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mScriptFile = StringTable->insert(pScriptFile);
|
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ void ShapeAnimationAsset::initializeAsset(void)
|
||||||
if (!mIsEmbedded)
|
if (!mIsEmbedded)
|
||||||
{
|
{
|
||||||
//If we're not embedded, we need to load in our initial shape and do some prepwork
|
//If we're not embedded, we need to load in our initial shape and do some prepwork
|
||||||
mFilePath = expandAssetFilePath(mFileName);
|
mFilePath = getOwned() ? expandAssetFilePath(mFileName) : mFilePath;
|
||||||
|
|
||||||
mSourceShape = ResourceManager::get().load(mFilePath);
|
mSourceShape = ResourceManager::get().load(mFilePath);
|
||||||
|
|
||||||
|
|
@ -177,14 +177,14 @@ void ShapeAnimationAsset::setAnimationFile(const char* pAnimationFile)
|
||||||
AssertFatal(pAnimationFile != NULL, "Cannot use a NULL animation file.");
|
AssertFatal(pAnimationFile != NULL, "Cannot use a NULL animation file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pAnimationFile = StringTable->insert(pAnimationFile);
|
pAnimationFile = StringTable->insert(pAnimationFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pAnimationFile == mFileName)
|
if (pAnimationFile == mFileName)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mFileName = StringTable->insert(pAnimationFile);
|
mFileName = getOwned() ? expandAssetFilePath(pAnimationFile) : pAnimationFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -186,10 +186,9 @@ void ShapeAsset::initializeAsset()
|
||||||
ResourceManager::get().getChangedSignal().notify(this, &ShapeAsset::_onResourceChanged);
|
ResourceManager::get().getChangedSignal().notify(this, &ShapeAsset::_onResourceChanged);
|
||||||
|
|
||||||
//Ensure our path is expando'd if it isn't already
|
//Ensure our path is expando'd if it isn't already
|
||||||
if (!Platform::isFullPath(mFilePath))
|
mFilePath = getOwned() ? expandAssetFilePath(mFileName) : mFilePath;
|
||||||
mFilePath = getOwned() ? expandAssetFilePath(mFileName) : mFilePath;
|
|
||||||
|
|
||||||
mConstructorFilePath = expandAssetFilePath(mConstructorFilePath);
|
mConstructorFilePath = getOwned() ? expandAssetFilePath(mConstructorFilePath) : mConstructorFilePath;
|
||||||
|
|
||||||
loadShape();
|
loadShape();
|
||||||
}
|
}
|
||||||
|
|
@ -200,13 +199,13 @@ void ShapeAsset::setShapeFile(const char* pShapeFile)
|
||||||
AssertFatal(pShapeFile != NULL, "Cannot use a NULL shape file.");
|
AssertFatal(pShapeFile != NULL, "Cannot use a NULL shape file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pShapeFile = StringTable->insert(pShapeFile);
|
pShapeFile = StringTable->insert(pShapeFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pShapeFile == mFileName)
|
if (pShapeFile == mFileName)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mFileName = pShapeFile;
|
mFileName = getOwned() ? expandAssetFilePath(pShapeFile) : pShapeFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -218,13 +217,13 @@ void ShapeAsset::setShapeConstructorFile(const char* pShapeConstructorFile)
|
||||||
AssertFatal(pShapeConstructorFile != NULL, "Cannot use a NULL shape constructor file.");
|
AssertFatal(pShapeConstructorFile != NULL, "Cannot use a NULL shape constructor file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch image file.
|
||||||
pShapeConstructorFile = StringTable->insert(pShapeConstructorFile);
|
pShapeConstructorFile = StringTable->insert(pShapeConstructorFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pShapeConstructorFile == mConstructorFileName)
|
if (pShapeConstructorFile == mConstructorFileName)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mConstructorFileName = pShapeConstructorFile;
|
mConstructorFileName = getOwned() ? expandAssetFilePath(pShapeConstructorFile) : pShapeConstructorFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -184,8 +184,7 @@ void SoundAsset::initializeAsset(void)
|
||||||
//ResourceManager::get().getChangedSignal.notify(this, &SoundAsset::_onResourceChanged);
|
//ResourceManager::get().getChangedSignal.notify(this, &SoundAsset::_onResourceChanged);
|
||||||
|
|
||||||
//Ensure our path is expando'd if it isn't already
|
//Ensure our path is expando'd if it isn't already
|
||||||
if (!Platform::isFullPath(mSoundPath))
|
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
||||||
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
|
||||||
|
|
||||||
mSoundPath = expandAssetFilePath(mSoundPath);
|
mSoundPath = expandAssetFilePath(mSoundPath);
|
||||||
|
|
||||||
|
|
@ -208,8 +207,7 @@ void SoundAsset::onAssetRefresh(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Update
|
//Update
|
||||||
if (!Platform::isFullPath(mSoundFile))
|
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
||||||
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
|
||||||
|
|
||||||
loadSound();
|
loadSound();
|
||||||
}
|
}
|
||||||
|
|
@ -243,14 +241,14 @@ void SoundAsset::setSoundFile(const char* pSoundFile)
|
||||||
AssertFatal(pSoundFile != NULL, "Cannot use a NULL sound file.");
|
AssertFatal(pSoundFile != NULL, "Cannot use a NULL sound file.");
|
||||||
|
|
||||||
// Fetch sound file.
|
// Fetch sound file.
|
||||||
pSoundFile = StringTable->insert(pSoundFile);
|
pSoundFile = StringTable->insert(pSoundFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pSoundFile == mSoundFile)
|
if (pSoundFile == mSoundFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mSoundFile = pSoundFile;
|
mSoundFile = getOwned() ? expandAssetFilePath(pSoundFile) : pSoundFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -161,14 +161,14 @@ void TerrainAsset::initializeAsset()
|
||||||
// Call parent.
|
// Call parent.
|
||||||
Parent::initializeAsset();
|
Parent::initializeAsset();
|
||||||
|
|
||||||
mTerrainFilePath = expandAssetFilePath(mTerrainFileName);
|
mTerrainFilePath = getOwned() ? expandAssetFilePath(mTerrainFileName) : mTerrainFilePath;
|
||||||
|
|
||||||
loadTerrain();
|
loadTerrain();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerrainAsset::onAssetRefresh()
|
void TerrainAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mTerrainFilePath = expandAssetFilePath(mTerrainFileName);
|
mTerrainFilePath = getOwned() ? expandAssetFilePath(mTerrainFileName) : mTerrainFilePath;
|
||||||
|
|
||||||
loadTerrain();
|
loadTerrain();
|
||||||
}
|
}
|
||||||
|
|
@ -176,13 +176,16 @@ void TerrainAsset::onAssetRefresh()
|
||||||
void TerrainAsset::setTerrainFileName(const char* pScriptFile)
|
void TerrainAsset::setTerrainFileName(const char* pScriptFile)
|
||||||
{
|
{
|
||||||
// Sanity!
|
// Sanity!
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL terrain file.");
|
||||||
|
|
||||||
// Fetch image file.
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
|
||||||
|
// Ignore no change,
|
||||||
|
if (pScriptFile == mTerrainFileName)
|
||||||
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mTerrainFileName = pScriptFile;
|
mTerrainFileName = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ void TerrainMaterialAsset::initializeAsset()
|
||||||
// Call parent.
|
// Call parent.
|
||||||
Parent::initializeAsset();
|
Parent::initializeAsset();
|
||||||
|
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
@ -127,7 +127,7 @@ void TerrainMaterialAsset::initializeAsset()
|
||||||
|
|
||||||
void TerrainMaterialAsset::onAssetRefresh()
|
void TerrainMaterialAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
@ -150,11 +150,14 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile)
|
||||||
// Sanity!
|
// Sanity!
|
||||||
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
|
||||||
|
|
||||||
// Fetch image file.
|
pScriptFile = StringTable->insert(pScriptFile, true);
|
||||||
pScriptFile = StringTable->insert(pScriptFile);
|
|
||||||
|
// Ignore no change,
|
||||||
|
if (pScriptFile == mScriptFile)
|
||||||
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mScriptFile = pScriptFile;
|
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
|
||||||
|
|
@ -126,15 +126,14 @@ void StateMachineAsset::setStateMachineFile(const char* pStateMachineFile)
|
||||||
// Sanity!
|
// Sanity!
|
||||||
AssertFatal(pStateMachineFile != NULL, "Cannot use a NULL state machine file.");
|
AssertFatal(pStateMachineFile != NULL, "Cannot use a NULL state machine file.");
|
||||||
|
|
||||||
// Fetch image file.
|
pStateMachineFile = StringTable->insert(pStateMachineFile, true);
|
||||||
pStateMachineFile = StringTable->insert(pStateMachineFile);
|
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
if (pStateMachineFile == mStateMachineFile)
|
if (pStateMachineFile == mStateMachineFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mStateMachineFile = StringTable->insert(pStateMachineFile);
|
mStateMachineFile = getOwned() ? expandAssetFilePath(pStateMachineFile) : pStateMachineFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -142,12 +141,12 @@ void StateMachineAsset::setStateMachineFile(const char* pStateMachineFile)
|
||||||
|
|
||||||
void StateMachineAsset::initializeAsset()
|
void StateMachineAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mStateMachinePath = expandAssetFilePath(mStateMachineFile);
|
mStateMachinePath = getOwned() ? expandAssetFilePath(mStateMachineFile) : mStateMachinePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateMachineAsset::onAssetRefresh()
|
void StateMachineAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mStateMachinePath = expandAssetFilePath(mStateMachineFile);
|
mStateMachinePath = getOwned() ? expandAssetFilePath(mStateMachineFile) : mStateMachinePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ ConsoleSetType( TypeAssetLooseFilePath )
|
||||||
StringTableEntry* assetLooseFilePath = (StringTableEntry*)(dptr);
|
StringTableEntry* assetLooseFilePath = (StringTableEntry*)(dptr);
|
||||||
|
|
||||||
// Update asset loose file-path value.
|
// Update asset loose file-path value.
|
||||||
*assetLooseFilePath = StringTable->insert(pFieldValue);
|
*assetLooseFilePath = StringTable->insert(pFieldValue, true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue