From 6e97deb3f7a584822672477e1eea40d8d9b3c5cb Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 3 May 2024 01:07:47 +0200 Subject: [PATCH] Use normalized path for text key files --- components/resource/keyframemanager.cpp | 36 +++++++++---------------- components/resource/keyframemanager.hpp | 6 ++--- components/vfs/manager.cpp | 23 ++++++++++++---- components/vfs/manager.hpp | 5 ++++ 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/components/resource/keyframemanager.cpp b/components/resource/keyframemanager.cpp index c4d3da2938..beef689e85 100644 --- a/components/resource/keyframemanager.cpp +++ b/components/resource/keyframemanager.cpp @@ -30,9 +30,10 @@ namespace Resource : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) , mTarget(target) , mAnimationManager(std::move(animationManager)) - , mNormalized(normalized) + , mPath(normalized) , mVFS(vfs) { + mPath.changeExtension("txt"); } bool RetrieveAnimationsVisitor::belongsToLeftUpperExtremity(const std::string& name) @@ -142,18 +143,22 @@ namespace Resource // InventoryWeaponOneHand, PickProbe, Slash, Thrust, Chop... even "Slash Small Follow" osgAnimation formats // should have a .txt file with the same name, each line holding a textkey and whitespace separated time // value e.g. idle: start 0.0333 - try + if (const Files::IStreamPtr textKeysFile = mVFS->find(mPath)) { - Files::IStreamPtr textKeysFile = mVFS->get(changeFileExtension(mNormalized, "txt")); - std::string line; - while (getline(*textKeysFile, line)) + try { - mTarget.mTextKeys.emplace(parseTimeSignature(line), parseTextKey(line)); + std::string line; + while (getline(*textKeysFile, line)) + mTarget.mTextKeys.emplace(parseTimeSignature(line), parseTextKey(line)); + } + catch (const std::exception& e) + { + Log(Debug::Warning) << "Failed to read text key file \"" << mPath << "\": " << e.what(); } } - catch (const std::exception& e) + else { - Log(Debug::Warning) << "Failed to use textkey file " << mNormalized << ": " << e.what(); + Log(Debug::Warning) << "Text key file is not found: " << mPath; } callback->setEmulatedAnimations(emulatedAnimations); @@ -191,21 +196,6 @@ namespace Resource return time; } - std::string RetrieveAnimationsVisitor::changeFileExtension(const std::string& file, const std::string& ext) - { - size_t extPos = file.find_last_of('.'); - if (extPos != std::string::npos && extPos + 1 < file.size()) - { - return file.substr(0, extPos + 1) + ext; - } - return file; - } - -} - -namespace Resource -{ - KeyframeManager::KeyframeManager(const VFS::Manager* vfs, SceneManager* sceneManager, double expiryDelay, const ToUTF8::StatelessUtf8Encoder* encoder) : ResourceManager(vfs, expiryDelay) diff --git a/components/resource/keyframemanager.hpp b/components/resource/keyframemanager.hpp index ed8d4a04ab..e5dc1af1cc 100644 --- a/components/resource/keyframemanager.hpp +++ b/components/resource/keyframemanager.hpp @@ -1,9 +1,10 @@ #ifndef OPENMW_COMPONENTS_KEYFRAMEMANAGER_H #define OPENMW_COMPONENTS_KEYFRAMEMANAGER_H +#include + #include #include -#include #include @@ -32,13 +33,12 @@ namespace Resource virtual void apply(osg::Node& node) override; private: - std::string changeFileExtension(const std::string& file, const std::string& ext); std::string parseTextKey(const std::string& line); double parseTimeSignature(const std::string& line); SceneUtil::KeyframeHolder& mTarget; osg::ref_ptr mAnimationManager; - std::string mNormalized; + VFS::Path::Normalized mPath; const VFS::Manager* mVFS; }; } diff --git a/components/vfs/manager.cpp b/components/vfs/manager.cpp index dfbde8299f..12ef378017 100644 --- a/components/vfs/manager.cpp +++ b/components/vfs/manager.cpp @@ -1,6 +1,5 @@ #include "manager.hpp" -#include #include #include @@ -38,6 +37,11 @@ namespace VFS archive->listResources(mIndex); } + Files::IStreamPtr Manager::find(Path::NormalizedView name) const + { + return findNormalized(name.value()); + } + Files::IStreamPtr Manager::get(const Path::Normalized& name) const { return getNormalized(name); @@ -51,10 +55,10 @@ namespace VFS Files::IStreamPtr Manager::getNormalized(std::string_view normalizedName) const { assert(Path::isNormalized(normalizedName)); - const auto found = mIndex.find(normalizedName); - if (found == mIndex.end()) - throw std::runtime_error("Resource '" + std::string(normalizedName) + "' is not found"); - return found->second->open(); + auto ptr = findNormalized(normalizedName); + if (ptr == nullptr) + throw std::runtime_error("Resource '" + std::string(normalizedName) + "' not found"); + return ptr; } bool Manager::exists(const Path::Normalized& name) const @@ -116,4 +120,13 @@ namespace VFS { return { mIndex.begin(), mIndex.end() }; } + + Files::IStreamPtr Manager::findNormalized(std::string_view normalizedPath) const + { + assert(Path::isNormalized(normalizedPath)); + const auto it = mIndex.find(normalizedPath); + if (it == mIndex.end()) + return nullptr; + return it->second->open(); + } } diff --git a/components/vfs/manager.hpp b/components/vfs/manager.hpp index d64be1d1d1..b6a9d796cc 100644 --- a/components/vfs/manager.hpp +++ b/components/vfs/manager.hpp @@ -45,6 +45,9 @@ namespace VFS bool exists(Path::NormalizedView name) const; + // Returns open file if exists or nullptr. + Files::IStreamPtr find(Path::NormalizedView name) const; + /// Retrieve a file by name. /// @note Throws an exception if the file can not be found. /// @note May be called from any thread once the index has been built. @@ -78,6 +81,8 @@ namespace VFS std::vector> mArchives; FileMap mIndex; + + inline Files::IStreamPtr findNormalized(std::string_view normalizedPath) const; }; }