mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 16:20:21 +00:00
Merge branch 'vfs_normalized_path_7' into 'master'
Use normalized path for RetrieveAnimationsVisitor See merge request OpenMW/openmw!4271
This commit is contained in:
commit
9bbd448f29
@ -1,18 +1,18 @@
|
||||
#ifndef OPENMW_COMPONENTS_MISC_PATHHELPERS_H
|
||||
#define OPENMW_COMPONENTS_MISC_PATHHELPERS_H
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace Misc
|
||||
{
|
||||
inline size_t findExtension(std::string_view file)
|
||||
inline constexpr std::size_t findExtension(std::string_view file) noexcept
|
||||
{
|
||||
return file.find_last_of('.');
|
||||
}
|
||||
|
||||
inline std::string_view getFileExtension(std::string_view file)
|
||||
inline constexpr std::string_view getFileExtension(std::string_view file) noexcept
|
||||
{
|
||||
if (auto extPos = findExtension(file); extPos != std::string::npos)
|
||||
if (auto extPos = findExtension(file); extPos != std::string_view::npos)
|
||||
{
|
||||
file.remove_prefix(extPos + 1);
|
||||
return file;
|
||||
@ -20,9 +20,9 @@ namespace Misc
|
||||
return {};
|
||||
}
|
||||
|
||||
inline std::string_view getFileName(std::string_view path)
|
||||
inline constexpr std::string_view getFileName(std::string_view path) noexcept
|
||||
{
|
||||
if (auto namePos = path.find_last_of("/\\"); namePos != std::string::npos)
|
||||
if (auto namePos = path.find_last_of("/\\"); namePos != std::string_view::npos)
|
||||
{
|
||||
path.remove_prefix(namePos + 1);
|
||||
}
|
||||
@ -30,11 +30,11 @@ namespace Misc
|
||||
return path;
|
||||
}
|
||||
|
||||
inline std::string_view stemFile(std::string_view path)
|
||||
inline constexpr std::string_view stemFile(std::string_view path) noexcept
|
||||
{
|
||||
path = getFileName(path);
|
||||
|
||||
if (auto extPos = path.find_last_of("."); extPos != std::string::npos)
|
||||
if (auto extPos = path.find_last_of('.'); extPos != std::string_view::npos)
|
||||
{
|
||||
path.remove_suffix(path.size() - extPos);
|
||||
}
|
||||
|
@ -23,16 +23,36 @@
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::string parseTextKey(const std::string& line)
|
||||
{
|
||||
const std::size_t spacePos = line.find_last_of(' ');
|
||||
if (spacePos != std::string::npos)
|
||||
return line.substr(0, spacePos);
|
||||
return {};
|
||||
}
|
||||
|
||||
double parseTimeSignature(std::string_view line)
|
||||
{
|
||||
const std::size_t spacePos = line.find_last_of(' ');
|
||||
double time = 0.0;
|
||||
if (spacePos != std::string_view::npos && spacePos + 1 < line.size())
|
||||
time = Misc::StringUtils::toNumeric<double>(line.substr(spacePos + 1), time);
|
||||
return time;
|
||||
}
|
||||
}
|
||||
|
||||
RetrieveAnimationsVisitor::RetrieveAnimationsVisitor(SceneUtil::KeyframeHolder& target,
|
||||
osg::ref_ptr<osgAnimation::BasicAnimationManager> animationManager, const std::string& normalized,
|
||||
const VFS::Manager* vfs)
|
||||
osg::ref_ptr<osgAnimation::BasicAnimationManager> animationManager, VFS::Path::NormalizedView path,
|
||||
const VFS::Manager& vfs)
|
||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||
, mTarget(target)
|
||||
, mAnimationManager(std::move(animationManager))
|
||||
, mNormalized(normalized)
|
||||
, mVFS(vfs)
|
||||
, mPath(path)
|
||||
, mVFS(&vfs)
|
||||
{
|
||||
mPath.changeExtension("txt");
|
||||
}
|
||||
|
||||
bool RetrieveAnimationsVisitor::belongsToLeftUpperExtremity(const std::string& name)
|
||||
@ -142,18 +162,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);
|
||||
@ -174,38 +198,6 @@ namespace Resource
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
std::string RetrieveAnimationsVisitor::parseTextKey(const std::string& line)
|
||||
{
|
||||
size_t spacePos = line.find_last_of(' ');
|
||||
if (spacePos != std::string::npos)
|
||||
return line.substr(0, spacePos);
|
||||
return "";
|
||||
}
|
||||
|
||||
double RetrieveAnimationsVisitor::parseTimeSignature(const std::string& line)
|
||||
{
|
||||
size_t spacePos = line.find_last_of(' ');
|
||||
double time = 0.0;
|
||||
if (spacePos != std::string::npos && spacePos + 1 < line.size())
|
||||
time = Misc::StringUtils::toNumeric<double>(line.substr(spacePos + 1), time);
|
||||
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)
|
||||
@ -216,7 +208,7 @@ namespace Resource
|
||||
|
||||
osg::ref_ptr<const SceneUtil::KeyframeHolder> KeyframeManager::get(const std::string& name)
|
||||
{
|
||||
const std::string normalized = VFS::Path::normalizeFilename(name);
|
||||
const VFS::Path::Normalized normalized(name);
|
||||
|
||||
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(normalized);
|
||||
if (obj)
|
||||
@ -228,7 +220,7 @@ namespace Resource
|
||||
{
|
||||
auto file = std::make_shared<Nif::NIFFile>(normalized);
|
||||
Nif::Reader reader(*file, mEncoder);
|
||||
reader.parse(mVFS->getNormalized(normalized));
|
||||
reader.parse(mVFS->get(normalized));
|
||||
NifOsg::Loader::loadKf(*file, *loaded.get());
|
||||
}
|
||||
else
|
||||
@ -238,7 +230,7 @@ namespace Resource
|
||||
= dynamic_cast<osgAnimation::BasicAnimationManager*>(scene->getUpdateCallback());
|
||||
if (bam)
|
||||
{
|
||||
Resource::RetrieveAnimationsVisitor rav(*loaded.get(), std::move(bam), normalized, mVFS);
|
||||
Resource::RetrieveAnimationsVisitor rav(*loaded.get(), std::move(bam), normalized, *mVFS);
|
||||
scene->accept(rav);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef OPENMW_COMPONENTS_KEYFRAMEMANAGER_H
|
||||
#define OPENMW_COMPONENTS_KEYFRAMEMANAGER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osgAnimation/BasicAnimationManager>
|
||||
#include <string>
|
||||
|
||||
#include <components/sceneutil/keyframe.hpp>
|
||||
|
||||
@ -20,9 +21,9 @@ namespace Resource
|
||||
class RetrieveAnimationsVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
RetrieveAnimationsVisitor(SceneUtil::KeyframeHolder& target,
|
||||
osg::ref_ptr<osgAnimation::BasicAnimationManager> animationManager, const std::string& normalized,
|
||||
const VFS::Manager* vfs);
|
||||
explicit RetrieveAnimationsVisitor(SceneUtil::KeyframeHolder& target,
|
||||
osg::ref_ptr<osgAnimation::BasicAnimationManager> animationManager, VFS::Path::NormalizedView path,
|
||||
const VFS::Manager& vfs);
|
||||
|
||||
bool belongsToLeftUpperExtremity(const std::string& name);
|
||||
bool belongsToRightUpperExtremity(const std::string& name);
|
||||
@ -32,13 +33,9 @@ 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<osgAnimation::BasicAnimationManager> mAnimationManager;
|
||||
std::string mNormalized;
|
||||
VFS::Path::Normalized mPath;
|
||||
const VFS::Manager* mVFS;
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "manager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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<std::unique_ptr<Archive>> mArchives;
|
||||
|
||||
FileMap mIndex;
|
||||
|
||||
inline Files::IStreamPtr findNormalized(std::string_view normalizedPath) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user