forked from mirror/openmw-tes3mp
Add SceneManager and clone utility
This commit is contained in:
parent
60f288195f
commit
99e1720980
13 changed files with 327 additions and 15 deletions
|
@ -60,7 +60,7 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
|
||||||
|
|
||||||
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
|
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
|
||||||
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
||||||
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0)
|
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0), mResourceSystem(resourcesManager.getVFS())
|
||||||
{
|
{
|
||||||
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
||||||
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
||||||
|
@ -354,6 +354,11 @@ CSMWorld::Data::~Data()
|
||||||
delete mReader;
|
delete mReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Resource::ResourceSystem* CSMWorld::Data::getResourceSystem()
|
||||||
|
{
|
||||||
|
return &mResourceSystem;
|
||||||
|
}
|
||||||
|
|
||||||
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
|
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
|
||||||
{
|
{
|
||||||
return mGlobals;
|
return mGlobals;
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <components/esm/debugprofile.hpp>
|
#include <components/esm/debugprofile.hpp>
|
||||||
#include <components/esm/filter.hpp>
|
#include <components/esm/filter.hpp>
|
||||||
|
|
||||||
|
#include <components/resource/resourcesystem.hpp>
|
||||||
|
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/to_utf8/to_utf8.hpp>
|
||||||
|
|
||||||
#include "../doc/stage.hpp"
|
#include "../doc/stage.hpp"
|
||||||
|
@ -105,6 +107,8 @@ namespace CSMWorld
|
||||||
std::map<std::string, std::map<ESM::RefNum, std::string> > mRefLoadCache;
|
std::map<std::string, std::map<ESM::RefNum, std::string> > mRefLoadCache;
|
||||||
int mReaderIndex;
|
int mReaderIndex;
|
||||||
|
|
||||||
|
Resource::ResourceSystem mResourceSystem;
|
||||||
|
|
||||||
std::vector<boost::shared_ptr<ESM::ESMReader> > mReaders;
|
std::vector<boost::shared_ptr<ESM::ESMReader> > mReaders;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
|
@ -128,6 +132,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
const VFS::Manager* getVFS() const;
|
const VFS::Manager* getVFS() const;
|
||||||
|
|
||||||
|
Resource::ResourceSystem* getResourceSystem();
|
||||||
|
|
||||||
const IdCollection<ESM::Global>& getGlobals() const;
|
const IdCollection<ESM::Global>& getGlobals() const;
|
||||||
|
|
||||||
IdCollection<ESM::Global>& getGlobals();
|
IdCollection<ESM::Global>& getGlobals();
|
||||||
|
|
|
@ -9,10 +9,12 @@
|
||||||
#include "../../model/world/ref.hpp"
|
#include "../../model/world/ref.hpp"
|
||||||
#include "../../model/world/refidcollection.hpp"
|
#include "../../model/world/refidcollection.hpp"
|
||||||
|
|
||||||
#include <components/nifosg/nifloader.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
|
#include <components/sceneutil/clone.hpp>
|
||||||
|
|
||||||
#include "elements.hpp"
|
#include "elements.hpp"
|
||||||
|
|
||||||
|
|
||||||
void CSVRender::Object::clear()
|
void CSVRender::Object::clear()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -56,15 +58,12 @@ void CSVRender::Object::update()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
NifOsg::Loader loader;
|
|
||||||
loader.resourceManager = mVFS;
|
|
||||||
|
|
||||||
std::string path = "meshes\\" + model;
|
std::string path = "meshes\\" + model;
|
||||||
|
|
||||||
Nif::NIFFilePtr file(new Nif::NIFFile(mVFS->get(path), path));
|
osg::ref_ptr<osg::Node> loaded = mResourceSystem->getSceneManager()->getInstance(path);
|
||||||
|
|
||||||
mBaseNode->removeChildren(0, mBaseNode->getNumChildren());
|
mBaseNode->removeChildren(0, mBaseNode->getNumChildren());
|
||||||
mBaseNode->addChild(loader.load(file));
|
mBaseNode->addChild(loaded);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -101,9 +100,9 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
||||||
return mData.getReferences().getRecord (mReferenceId).get();
|
return mData.getReferences().getRecord (mReferenceId).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::Object::Object (const CSMWorld::Data& data, osg::Group* parentNode,
|
CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
||||||
const std::string& id, bool referenceable, bool forceBaseToZero)
|
const std::string& id, bool referenceable, bool forceBaseToZero)
|
||||||
: mVFS(data.getVFS()), mData (data), mBaseNode(0), mParentNode(parentNode), mForceBaseToZero (forceBaseToZero)
|
: mResourceSystem(data.getResourceSystem()), mData (data), mBaseNode(0), mParentNode(parentNode), mForceBaseToZero (forceBaseToZero)
|
||||||
{
|
{
|
||||||
mBaseNode = new osg::PositionAttitudeTransform;
|
mBaseNode = new osg::PositionAttitudeTransform;
|
||||||
parentNode->addChild(mBaseNode);
|
parentNode->addChild(mBaseNode);
|
||||||
|
|
|
@ -14,9 +14,9 @@ namespace osg
|
||||||
class Group;
|
class Group;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace VFS
|
namespace Resource
|
||||||
{
|
{
|
||||||
class Manager;
|
class ResourceSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
|
@ -39,7 +39,7 @@ namespace CSVRender
|
||||||
std::string mReferenceableId;
|
std::string mReferenceableId;
|
||||||
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||||
osg::Group* mParentNode;
|
osg::Group* mParentNode;
|
||||||
const VFS::Manager* mVFS;
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
bool mForceBaseToZero;
|
bool mForceBaseToZero;
|
||||||
|
|
||||||
/// Not implemented
|
/// Not implemented
|
||||||
|
@ -62,7 +62,7 @@ namespace CSVRender
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Object (const CSMWorld::Data& data, osg::Group *cellNode,
|
Object (CSMWorld::Data& data, osg::Group *cellNode,
|
||||||
const std::string& id, bool referenceable,
|
const std::string& id, bool referenceable,
|
||||||
bool forceBaseToZero = false);
|
bool forceBaseToZero = false);
|
||||||
/// \param forceBaseToZero If this is a reference ignore the coordinates and place
|
/// \param forceBaseToZero If this is a reference ignore the coordinates and place
|
||||||
|
|
|
@ -38,6 +38,14 @@ add_component_dir (vfs
|
||||||
manager archive bsaarchive filesystemarchive registerarchives
|
manager archive bsaarchive filesystemarchive registerarchives
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_component_dir (resource
|
||||||
|
scenemanager resourcesystem
|
||||||
|
)
|
||||||
|
|
||||||
|
add_component_dir (sceneutil
|
||||||
|
clone
|
||||||
|
)
|
||||||
|
|
||||||
add_component_dir (nif
|
add_component_dir (nif
|
||||||
controlled effect niftypes record controller extra node record_ptr data niffile property nifkey data node base nifstream
|
controlled effect niftypes record controller extra node record_ptr data niffile property nifkey data node base nifstream
|
||||||
)
|
)
|
||||||
|
|
24
components/resource/resourcesystem.cpp
Normal file
24
components/resource/resourcesystem.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include "resourcesystem.hpp"
|
||||||
|
|
||||||
|
#include "scenemanager.hpp"
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
ResourceSystem::ResourceSystem(const VFS::Manager *vfs)
|
||||||
|
: mVFS(vfs)
|
||||||
|
{
|
||||||
|
mSceneManager.reset(new SceneManager(vfs));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneManager* ResourceSystem::getSceneManager()
|
||||||
|
{
|
||||||
|
return mSceneManager.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const VFS::Manager* ResourceSystem::getVFS() const
|
||||||
|
{
|
||||||
|
return mVFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
components/resource/resourcesystem.hpp
Normal file
34
components/resource/resourcesystem.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_RESOURCE_RESOURCESYSTEM_H
|
||||||
|
#define OPENMW_COMPONENTS_RESOURCE_RESOURCESYSTEM_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace VFS
|
||||||
|
{
|
||||||
|
class Manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
class SceneManager;
|
||||||
|
|
||||||
|
/// @brief Wrapper class that constructs and provides access to the various resource subsystems.
|
||||||
|
class ResourceSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ResourceSystem(const VFS::Manager* vfs);
|
||||||
|
|
||||||
|
SceneManager* getSceneManager();
|
||||||
|
|
||||||
|
const VFS::Manager* getVFS() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::auto_ptr<SceneManager> mSceneManager;
|
||||||
|
|
||||||
|
const VFS::Manager* mVFS;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
49
components/resource/scenemanager.cpp
Normal file
49
components/resource/scenemanager.cpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include "scenemanager.hpp"
|
||||||
|
|
||||||
|
#include <osg/Node>
|
||||||
|
|
||||||
|
#include <components/nifosg/nifloader.hpp>
|
||||||
|
#include <components/nif/niffile.hpp>
|
||||||
|
|
||||||
|
#include <components/sceneutil/clone.hpp>
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
SceneManager::SceneManager(const VFS::Manager *vfs)
|
||||||
|
: mVFS(vfs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<const osg::Node> SceneManager::getTemplate(const std::string &name)
|
||||||
|
{
|
||||||
|
std::string normalized = name;
|
||||||
|
mVFS->normalizeFilename(normalized);
|
||||||
|
|
||||||
|
Index::iterator it = mIndex.find(normalized);
|
||||||
|
if (it == mIndex.end())
|
||||||
|
{
|
||||||
|
Files::IStreamPtr file = mVFS->get(normalized);
|
||||||
|
|
||||||
|
// TODO: add support for non-NIF formats
|
||||||
|
|
||||||
|
NifOsg::Loader loader;
|
||||||
|
loader.resourceManager = mVFS;
|
||||||
|
osg::ref_ptr<const osg::Node> loaded = loader.load(Nif::NIFFilePtr(new Nif::NIFFile(file, normalized)));
|
||||||
|
|
||||||
|
// TODO: provide way for the user to get textKeys (attach to the node?)
|
||||||
|
|
||||||
|
mIndex[normalized] = loaded;
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Node> SceneManager::getInstance(const std::string &name)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<const osg::Node> scene = getTemplate(name);
|
||||||
|
return osg::clone(scene.get(), SceneUtil::CopyOp());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
components/resource/scenemanager.hpp
Normal file
40
components/resource/scenemanager.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_RESOURCE_SCENEMANAGER_H
|
||||||
|
#define OPENMW_COMPONENTS_RESOURCE_SCENEMANAGER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
#include <osg/Node>
|
||||||
|
|
||||||
|
namespace VFS
|
||||||
|
{
|
||||||
|
class Manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
/// @brief Handles loading and caching of scenes, e.g. NIF files
|
||||||
|
class SceneManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SceneManager(const VFS::Manager* vfs);
|
||||||
|
|
||||||
|
/// Get a read-only copy of this scene "template"
|
||||||
|
osg::ref_ptr<const osg::Node> getTemplate(const std::string& name);
|
||||||
|
|
||||||
|
/// Create an instance of the given scene template
|
||||||
|
osg::ref_ptr<osg::Node> getInstance(const std::string& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const VFS::Manager* mVFS;
|
||||||
|
|
||||||
|
// observer_ptr?
|
||||||
|
typedef std::map<std::string, osg::ref_ptr<const osg::Node> > Index;
|
||||||
|
Index mIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
85
components/sceneutil/clone.cpp
Normal file
85
components/sceneutil/clone.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include "clone.hpp"
|
||||||
|
|
||||||
|
#include <osg/StateSet>
|
||||||
|
|
||||||
|
#include <osgParticle/ParticleProcessor>
|
||||||
|
#include <osgParticle/ParticleSystemUpdater>
|
||||||
|
#include <osgParticle/Emitter>
|
||||||
|
#include <osgParticle/Program>
|
||||||
|
#include <osgAnimation/RigGeometry>
|
||||||
|
#include <osgAnimation/MorphGeometry>
|
||||||
|
|
||||||
|
namespace SceneUtil
|
||||||
|
{
|
||||||
|
|
||||||
|
CopyOp::CopyOp()
|
||||||
|
{
|
||||||
|
setCopyFlags(osg::CopyOp::DEEP_COPY_NODES
|
||||||
|
// Controller might need different inputs per scene instance
|
||||||
|
| osg::CopyOp::DEEP_COPY_CALLBACKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::StateSet* CopyOp::operator ()(const osg::StateSet* stateset) const
|
||||||
|
{
|
||||||
|
if (!stateset)
|
||||||
|
return NULL;
|
||||||
|
if (stateset->getDataVariance() == osg::StateSet::DYNAMIC)
|
||||||
|
return osg::clone(stateset, osg::CopyOp::DEEP_COPY_STATESETS);
|
||||||
|
return const_cast<osg::StateSet*>(stateset);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Node* CopyOp::operator ()(const osg::Node* node) const
|
||||||
|
{
|
||||||
|
if (const osgParticle::ParticleProcessor* processor = dynamic_cast<const osgParticle::ParticleProcessor*>(node))
|
||||||
|
return operator()(processor);
|
||||||
|
if (const osgParticle::ParticleSystemUpdater* updater = dynamic_cast<const osgParticle::ParticleSystemUpdater*>(node))
|
||||||
|
{
|
||||||
|
osgParticle::ParticleSystemUpdater* cloned = osg::clone(updater, osg::CopyOp::DEEP_COPY_NODES);
|
||||||
|
mMap2[cloned] = updater->getParticleSystem(0);
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
return osg::CopyOp::operator()(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Drawable* CopyOp::operator ()(const osg::Drawable* drawable) const
|
||||||
|
{
|
||||||
|
if (const osgParticle::ParticleSystem* partsys = dynamic_cast<const osgParticle::ParticleSystem*>(drawable))
|
||||||
|
return operator()(partsys);
|
||||||
|
if (dynamic_cast<const osgAnimation::RigGeometry*>(drawable)
|
||||||
|
|| dynamic_cast<const osgAnimation::MorphGeometry*>(drawable))
|
||||||
|
return osg::clone(drawable, osg::CopyOp::DEEP_COPY_DRAWABLES);
|
||||||
|
|
||||||
|
return osg::CopyOp::operator()(drawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
osgParticle::ParticleProcessor* CopyOp::operator() (const osgParticle::ParticleProcessor* processor) const
|
||||||
|
{
|
||||||
|
osgParticle::ParticleProcessor* cloned = osg::clone(processor, osg::CopyOp::DEEP_COPY_NODES);
|
||||||
|
mMap[cloned] = processor->getParticleSystem();
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
osgParticle::ParticleSystem* CopyOp::operator ()(const osgParticle::ParticleSystem* partsys) const
|
||||||
|
{
|
||||||
|
osgParticle::ParticleSystem* cloned = osg::clone(partsys, osg::CopyOp::DEEP_COPY_DRAWABLES);
|
||||||
|
|
||||||
|
for (std::map<osgParticle::ParticleProcessor*, const osgParticle::ParticleSystem*>::const_iterator it = mMap.begin(); it != mMap.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->second == partsys)
|
||||||
|
{
|
||||||
|
it->first->setParticleSystem(cloned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (std::map<osgParticle::ParticleSystemUpdater*, const osgParticle::ParticleSystem*>::const_iterator it = mMap2.begin(); it != mMap2.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->second == partsys)
|
||||||
|
{
|
||||||
|
osgParticle::ParticleSystemUpdater* updater = it->first;
|
||||||
|
updater->removeParticleSystem(updater->getParticleSystem(0));
|
||||||
|
updater->addParticleSystem(cloned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
components/sceneutil/clone.hpp
Normal file
45
components/sceneutil/clone.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_SCENEUTIL_CLONE_H
|
||||||
|
#define OPENMW_COMPONENTS_SCENEUTIL_CLONE_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <osg/CopyOp>
|
||||||
|
|
||||||
|
namespace osgParticle
|
||||||
|
{
|
||||||
|
class ParticleProcessor;
|
||||||
|
class ParticleSystem;
|
||||||
|
class ParticleSystemUpdater;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SceneUtil
|
||||||
|
{
|
||||||
|
|
||||||
|
/// @par Defines the cloning behaviour we need:
|
||||||
|
/// * Assigns updated ParticleSystem pointers on cloned emitters and programs.
|
||||||
|
/// * Creates deep copy of StateSets if they have a DYNAMIC data variance.
|
||||||
|
/// * Deep copies RigGeometry and MorphGeometry so they can animate without affecting clones.
|
||||||
|
/// @warning Do not use an object of this class for more than one copy operation.
|
||||||
|
class CopyOp : public osg::CopyOp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CopyOp();
|
||||||
|
|
||||||
|
virtual osgParticle::ParticleSystem* operator() (const osgParticle::ParticleSystem* partsys) const;
|
||||||
|
virtual osgParticle::ParticleProcessor* operator() (const osgParticle::ParticleProcessor* processor) const;
|
||||||
|
|
||||||
|
virtual osg::Node* operator() (const osg::Node* node) const;
|
||||||
|
virtual osg::Drawable* operator() (const osg::Drawable* drawable) const;
|
||||||
|
|
||||||
|
virtual osg::StateSet* operator() (const osg::StateSet* stateset) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// maps new ParticleProcessor to their old ParticleSystem pointer
|
||||||
|
// a little messy, but I think this should be the most efficient way
|
||||||
|
mutable std::map<osgParticle::ParticleProcessor*, const osgParticle::ParticleSystem*> mMap;
|
||||||
|
mutable std::map<osgParticle::ParticleSystemUpdater*, const osgParticle::ParticleSystem*> mMap2;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -59,9 +59,14 @@ namespace VFS
|
||||||
std::string normalized = name;
|
std::string normalized = name;
|
||||||
normalize_path(normalized, mStrict);
|
normalize_path(normalized, mStrict);
|
||||||
|
|
||||||
std::map<std::string, File*>::const_iterator found = mIndex.find(normalized);
|
return getNormalized(normalized);
|
||||||
|
}
|
||||||
|
|
||||||
|
Files::IStreamPtr Manager::getNormalized(const std::string &normalizedName) const
|
||||||
|
{
|
||||||
|
std::map<std::string, File*>::const_iterator found = mIndex.find(normalizedName);
|
||||||
if (found == mIndex.end())
|
if (found == mIndex.end())
|
||||||
throw std::runtime_error("Resource '" + name + "' not found");
|
throw std::runtime_error("Resource '" + normalizedName + "' not found");
|
||||||
return found->second->open();
|
return found->second->open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,4 +83,9 @@ namespace VFS
|
||||||
return mIndex;
|
return mIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::normalizeFilename(std::string &name) const
|
||||||
|
{
|
||||||
|
normalize_path(name, mStrict);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,17 @@ namespace VFS
|
||||||
/// Get a complete list of files from all archives
|
/// Get a complete list of files from all archives
|
||||||
const std::map<std::string, File*>& getIndex() const;
|
const std::map<std::string, File*>& getIndex() const;
|
||||||
|
|
||||||
|
/// Normalize the given filename, making slashes/backslashes consistent, and lower-casing if mStrict is false.
|
||||||
|
void normalizeFilename(std::string& name) const;
|
||||||
|
|
||||||
/// Retrieve a file by name.
|
/// Retrieve a file by name.
|
||||||
/// @note Throws an exception if the file can not be found.
|
/// @note Throws an exception if the file can not be found.
|
||||||
Files::IStreamPtr get(const std::string& name) const;
|
Files::IStreamPtr get(const std::string& name) const;
|
||||||
|
|
||||||
|
/// Retrieve a file by name (name is already normalized).
|
||||||
|
/// @note Throws an exception if the file can not be found.
|
||||||
|
Files::IStreamPtr getNormalized(const std::string& normalizedName) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mStrict;
|
bool mStrict;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue