From c338c1e5d3f4ef4de107c7b42082cbb30390d498 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 18 Sep 2022 14:12:49 +0200 Subject: [PATCH] Add Nif::FileView as read only interface for Nif::NIFFile To make sure interface is scoped to what users require. --- components/nif/niffile.hpp | 28 ++++++++++++----- components/nifbullet/bulletnifloader.cpp | 2 +- components/nifbullet/bulletnifloader.hpp | 2 +- components/nifosg/nifloader.cpp | 38 ++++++++++++------------ components/nifosg/nifloader.hpp | 4 +-- components/resource/keyframemanager.cpp | 2 +- components/resource/scenemanager.cpp | 2 +- 7 files changed, 45 insertions(+), 33 deletions(-) diff --git a/components/nif/niffile.hpp b/components/nif/niffile.hpp index fe32cf53c1..5f5f112eaf 100644 --- a/components/nif/niffile.hpp +++ b/components/nif/niffile.hpp @@ -51,28 +51,40 @@ namespace Nif : mPath(path) { } + }; + + class FileView + { + public: + FileView(const NIFFile& file) + : mFile(&file) + { + } /// Get a given root - Record* getRoot(size_t index = 0) const { return mRoots.at(index); } + const Record* getRoot(std::size_t index) const { return mFile->mRoots.at(index); } /// Number of roots - std::size_t numRoots() const { return mRoots.size(); } + std::size_t numRoots() const { return mFile->mRoots.size(); } /// Get the name of the file - const std::filesystem::path& getFilename() const { return mPath; } + const std::filesystem::path& getFilename() const { return mFile->mPath; } - const std::string& getHash() const { return mHash; } + const std::string& getHash() const { return mFile->mHash; } /// Get the version of the NIF format used - unsigned int getVersion() const { return mVersion; } + unsigned int getVersion() const { return mFile->mVersion; } /// Get the user version of the NIF format used - unsigned int getUserVersion() const { return mUserVersion; } + unsigned int getUserVersion() const { return mFile->mUserVersion; } /// Get the Bethesda version of the NIF format used - unsigned int getBethVersion() const { return mBethVersion; } + unsigned int getBethVersion() const { return mFile->mBethVersion; } + + bool getUseSkinning() const { return mFile->mUseSkinning; } - bool getUseSkinning() const { return mUseSkinning; } + private: + const NIFFile* mFile; }; class Reader diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 3b35e3d2b5..7b6649f32a 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -160,7 +160,7 @@ namespace namespace NifBullet { - osg::ref_ptr BulletNifLoader::load(const Nif::NIFFile& nif) + osg::ref_ptr BulletNifLoader::load(Nif::FileView nif) { mShape = new Resource::BulletShape; diff --git a/components/nifbullet/bulletnifloader.hpp b/components/nifbullet/bulletnifloader.hpp index 1cdc0ec468..947f93eadf 100644 --- a/components/nifbullet/bulletnifloader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -48,7 +48,7 @@ namespace NifBullet abort(); } - osg::ref_ptr load(const Nif::NIFFile& file); + osg::ref_ptr load(Nif::FileView file); private: bool findBoundingBox(const Nif::Node& node, const std::string& filename); diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 5ce2281832..a295f3b280 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -250,13 +250,13 @@ namespace NifOsg // This is used to queue emitters that weren't attached to their node yet. std::vector>> mEmitterQueue; - void loadKf(Nif::NIFFilePtr nif, SceneUtil::KeyframeHolder& target) const + void loadKf(Nif::FileView nif, SceneUtil::KeyframeHolder& target) const { const Nif::NiSequenceStreamHelper* seq = nullptr; - const size_t numRoots = nif->numRoots(); + const size_t numRoots = nif.numRoots(); for (size_t i = 0; i < numRoots; ++i) { - const Nif::Record* r = nif->getRoot(i); + const Nif::Record* r = nif.getRoot(i); if (r && r->recType == Nif::RC_NiSequenceStreamHelper) { seq = static_cast(r); @@ -267,7 +267,7 @@ namespace NifOsg if (!seq) { Log(Debug::Warning) << "NIFFile Warning: Found no NiSequenceStreamHelper root record. File: " - << nif->getFilename(); + << nif.getFilename(); return; } @@ -276,7 +276,7 @@ namespace NifOsg { Log(Debug::Warning) << "NIFFile Warning: First extra data was not a NiTextKeyExtraData, but a " << (extra.empty() ? std::string_view("nil") : std::string_view(extra->recName)) - << ". File: " << nif->getFilename(); + << ". File: " << nif.getFilename(); return; } @@ -289,7 +289,7 @@ namespace NifOsg if (extra->recType != Nif::RC_NiStringExtraData || ctrl->recType != Nif::RC_NiKeyframeController) { Log(Debug::Warning) << "NIFFile Warning: Unexpected extra data " << extra->recName - << " with controller " << ctrl->recName << ". File: " << nif->getFilename(); + << " with controller " << ctrl->recName << ". File: " << nif.getFilename(); continue; } @@ -314,17 +314,17 @@ namespace NifOsg if (!target.mKeyframeControllers.emplace(strdata->string, callback).second) Log(Debug::Verbose) << "Controller " << strdata->string << " present more than once in " - << nif->getFilename() << ", ignoring later version"; + << nif.getFilename() << ", ignoring later version"; } } - osg::ref_ptr load(Nif::NIFFilePtr nif, Resource::ImageManager* imageManager) + osg::ref_ptr load(Nif::FileView nif, Resource::ImageManager* imageManager) { - const size_t numRoots = nif->numRoots(); + const size_t numRoots = nif.numRoots(); std::vector roots; for (size_t i = 0; i < numRoots; ++i) { - const Nif::Record* r = nif->getRoot(i); + const Nif::Record* r = nif.getRoot(i); if (!r) continue; const Nif::Node* nifNode = dynamic_cast(r); @@ -332,7 +332,7 @@ namespace NifOsg roots.emplace_back(nifNode); } if (roots.empty()) - throw Nif::Exception("Found no root nodes", nif->getFilename()); + throw Nif::Exception("Found no root nodes", nif.getFilename()); osg::ref_ptr textkeys(new SceneUtil::TextKeyMapHolder); @@ -352,7 +352,7 @@ namespace NifOsg // Attach particle emitters to their nodes which should all be loaded by now. handleQueuedParticleEmitters(created, nif); - if (nif->getUseSkinning()) + if (nif.getUseSkinning()) { osg::ref_ptr skel = new SceneUtil::Skeleton; skel->setStateSet(created->getStateSet()); @@ -366,7 +366,7 @@ namespace NifOsg if (!textkeys->mTextKeys.empty()) created->getOrCreateUserDataContainer()->addUserObject(textkeys); - created->setUserValue(Misc::OsgUserValues::sFileHash, nif->getHash()); + created->setUserValue(Misc::OsgUserValues::sFileHash, nif.getHash()); return created; } @@ -1192,7 +1192,7 @@ namespace NifOsg return emitter; } - void handleQueuedParticleEmitters(osg::Group* rootNode, Nif::NIFFilePtr nif) + void handleQueuedParticleEmitters(osg::Group* rootNode, Nif::FileView nif) { for (const auto& emitterPair : mEmitterQueue) { @@ -1204,7 +1204,7 @@ namespace NifOsg { Log(Debug::Warning) << "NIFFile Warning: Failed to find particle emitter emitter node (node record index " - << recIndex << "). File: " << nif->getFilename(); + << recIndex << "). File: " << nif.getFilename(); continue; } @@ -2500,15 +2500,15 @@ namespace NifOsg } }; - osg::ref_ptr Loader::load(Nif::NIFFilePtr file, Resource::ImageManager* imageManager) + osg::ref_ptr Loader::load(Nif::FileView file, Resource::ImageManager* imageManager) { - LoaderImpl impl(file->getFilename(), file->getVersion(), file->getUserVersion(), file->getBethVersion()); + LoaderImpl impl(file.getFilename(), file.getVersion(), file.getUserVersion(), file.getBethVersion()); return impl.load(file, imageManager); } - void Loader::loadKf(Nif::NIFFilePtr kf, SceneUtil::KeyframeHolder& target) + void Loader::loadKf(Nif::FileView kf, SceneUtil::KeyframeHolder& target) { - LoaderImpl impl(kf->getFilename(), kf->getVersion(), kf->getUserVersion(), kf->getBethVersion()); + LoaderImpl impl(kf.getFilename(), kf.getVersion(), kf.getUserVersion(), kf.getBethVersion()); impl.loadKf(kf, target); } diff --git a/components/nifosg/nifloader.hpp b/components/nifosg/nifloader.hpp index 99251e3da8..737c365c5e 100644 --- a/components/nifosg/nifloader.hpp +++ b/components/nifosg/nifloader.hpp @@ -28,10 +28,10 @@ namespace NifOsg public: /// Create a scene graph for the given NIF. Auto-detects when skinning is used and wraps the graph in a Skeleton /// if so. - static osg::ref_ptr load(Nif::NIFFilePtr file, Resource::ImageManager* imageManager); + static osg::ref_ptr load(Nif::FileView file, Resource::ImageManager* imageManager); /// Load keyframe controllers from the given kf file. - static void loadKf(Nif::NIFFilePtr kf, SceneUtil::KeyframeHolder& target); + static void loadKf(Nif::FileView kf, SceneUtil::KeyframeHolder& target); /// Set whether or not nodes marked as "MRK" should be shown. /// These should be hidden ingame, but visible in the editor. diff --git a/components/resource/keyframemanager.cpp b/components/resource/keyframemanager.cpp index 7c55373474..e87520caa9 100644 --- a/components/resource/keyframemanager.cpp +++ b/components/resource/keyframemanager.cpp @@ -159,7 +159,7 @@ namespace Resource auto file = std::make_shared(normalized); Nif::Reader reader(*file); reader.parse(mVFS->getNormalized(normalized)); - NifOsg::Loader::loadKf(std::move(file), *loaded.get()); + NifOsg::Loader::loadKf(*file, *loaded.get()); } else { diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index e686de79fa..037da7be4c 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -714,7 +714,7 @@ namespace Resource { auto ext = Misc::getFileExtension(normalizedFilename); if (ext == "nif") - return NifOsg::Loader::load(nifFileManager->get(normalizedFilename), imageManager); + return NifOsg::Loader::load(*nifFileManager->get(normalizedFilename), imageManager); else return loadNonNif(normalizedFilename, *vfs->get(normalizedFilename), imageManager); }