mirror of
https://github.com/OpenMW/openmw.git
synced 2025-07-01 22:41:34 +00:00
Use recurse subdirectory iterator to iterate over the VFS without exposing internal details
This commit is contained in:
parent
b6f572578e
commit
d4e26746a3
8 changed files with 82 additions and 88 deletions
|
@ -52,11 +52,8 @@ void readVFS(VFS::Archive* anArchive,std::string archivePath = "")
|
||||||
myManager.addArchive(anArchive);
|
myManager.addArchive(anArchive);
|
||||||
myManager.buildIndex();
|
myManager.buildIndex();
|
||||||
|
|
||||||
std::map<std::string, VFS::File*> files=myManager.getIndex();
|
for(const auto& name : myManager.getRecursiveDirectoryIterator(""))
|
||||||
for(auto it=files.begin(); it!=files.end(); ++it)
|
|
||||||
{
|
{
|
||||||
std::string name = it->first;
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
if(isNIF(name))
|
if(isNIF(name))
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,10 +23,8 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const *
|
||||||
|
|
||||||
size_t baseSize = mBaseDirectory.size();
|
size_t baseSize = mBaseDirectory.size();
|
||||||
|
|
||||||
const std::map<std::string, VFS::File*>& index = vfs->getIndex();
|
for (const auto& filepath : vfs->getRecursiveDirectoryIterator(""))
|
||||||
for (std::map<std::string, VFS::File*>::const_iterator it = index.begin(); it != index.end(); ++it)
|
|
||||||
{
|
{
|
||||||
std::string filepath = it->first;
|
|
||||||
if (filepath.size()<baseSize+1 ||
|
if (filepath.size()<baseSize+1 ||
|
||||||
filepath.substr (0, baseSize)!=mBaseDirectory ||
|
filepath.substr (0, baseSize)!=mBaseDirectory ||
|
||||||
(filepath[baseSize]!='/' && filepath[baseSize]!='\\'))
|
(filepath[baseSize]!='/' && filepath[baseSize]!='\\'))
|
||||||
|
|
|
@ -66,35 +66,26 @@ namespace MWGui
|
||||||
|
|
||||||
void LoadingScreen::findSplashScreens()
|
void LoadingScreen::findSplashScreens()
|
||||||
{
|
{
|
||||||
const std::map<std::string, VFS::File*>& index = mResourceSystem->getVFS()->getIndex();
|
|
||||||
std::string pattern = "Splash/";
|
std::string pattern = "Splash/";
|
||||||
mResourceSystem->getVFS()->normalizeFilename(pattern);
|
mResourceSystem->getVFS()->normalizeFilename(pattern);
|
||||||
|
|
||||||
/* priority given to the left */
|
/* priority given to the left */
|
||||||
const std::array<std::string, 7> supported_extensions {{".tga", ".dds", ".ktx", ".png", ".bmp", ".jpeg", ".jpg"}};
|
const std::array<std::string, 7> supported_extensions {{".tga", ".dds", ".ktx", ".png", ".bmp", ".jpeg", ".jpg"}};
|
||||||
|
|
||||||
auto found = index.lower_bound(pattern);
|
for (const auto& name : mResourceSystem->getVFS()->getRecursiveDirectoryIterator(pattern))
|
||||||
while (found != index.end())
|
|
||||||
{
|
{
|
||||||
const std::string& name = found->first;
|
size_t pos = name.find_last_of('.');
|
||||||
if (name.size() >= pattern.size() && name.substr(0, pattern.size()) == pattern)
|
if (pos != std::string::npos)
|
||||||
{
|
{
|
||||||
size_t pos = name.find_last_of('.');
|
for (auto const& extension : supported_extensions)
|
||||||
if (pos != std::string::npos)
|
|
||||||
{
|
{
|
||||||
for(auto const& extension: supported_extensions)
|
if (name.compare(pos, name.size() - pos, extension) == 0)
|
||||||
{
|
{
|
||||||
if (name.compare(pos, name.size() - pos, extension) == 0)
|
mSplashScreens.push_back(name);
|
||||||
{
|
break; /* based on priority */
|
||||||
mSplashScreens.push_back(found->first);
|
|
||||||
break; /* based on priority */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
++found;
|
|
||||||
}
|
}
|
||||||
if (mSplashScreens.empty())
|
if (mSplashScreens.empty())
|
||||||
Log(Debug::Warning) << "Warning: no splash screens found!";
|
Log(Debug::Warning) << "Warning: no splash screens found!";
|
||||||
|
|
|
@ -591,8 +591,6 @@ namespace MWRender
|
||||||
|
|
||||||
void Animation::loadAllAnimationsInFolder(const std::string &model, const std::string &baseModel)
|
void Animation::loadAllAnimationsInFolder(const std::string &model, const std::string &baseModel)
|
||||||
{
|
{
|
||||||
const std::map<std::string, VFS::File*>& index = mResourceSystem->getVFS()->getIndex();
|
|
||||||
|
|
||||||
std::string animationPath = model;
|
std::string animationPath = model;
|
||||||
if (animationPath.find("meshes") == 0)
|
if (animationPath.find("meshes") == 0)
|
||||||
{
|
{
|
||||||
|
@ -602,19 +600,11 @@ namespace MWRender
|
||||||
|
|
||||||
mResourceSystem->getVFS()->normalizeFilename(animationPath);
|
mResourceSystem->getVFS()->normalizeFilename(animationPath);
|
||||||
|
|
||||||
std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(animationPath);
|
for (const auto& name : mResourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath))
|
||||||
while (found != index.end())
|
|
||||||
{
|
{
|
||||||
const std::string& name = found->first;
|
size_t pos = name.find_last_of('.');
|
||||||
if (name.size() >= animationPath.size() && name.substr(0, animationPath.size()) == animationPath)
|
if (pos != std::string::npos && name.compare(pos, name.size() - pos, ".kf") == 0)
|
||||||
{
|
addSingleAnimSource(name, baseModel);
|
||||||
size_t pos = name.find_last_of('.');
|
|
||||||
if (pos != std::string::npos && name.compare(pos, name.size()-pos, ".kf") == 0)
|
|
||||||
addSingleAnimSource(name, baseModel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
++found;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1295,8 +1285,6 @@ namespace MWRender
|
||||||
if (model.empty())
|
if (model.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::map<std::string, VFS::File*>& index = resourceSystem->getVFS()->getIndex();
|
|
||||||
|
|
||||||
std::string animationPath = model;
|
std::string animationPath = model;
|
||||||
if (animationPath.find("meshes") == 0)
|
if (animationPath.find("meshes") == 0)
|
||||||
{
|
{
|
||||||
|
@ -1306,19 +1294,11 @@ namespace MWRender
|
||||||
|
|
||||||
resourceSystem->getVFS()->normalizeFilename(animationPath);
|
resourceSystem->getVFS()->normalizeFilename(animationPath);
|
||||||
|
|
||||||
std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(animationPath);
|
for (const auto& name : resourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath))
|
||||||
while (found != index.end())
|
|
||||||
{
|
{
|
||||||
const std::string& name = found->first;
|
size_t pos = name.find_last_of('.');
|
||||||
if (name.size() >= animationPath.size() && name.substr(0, animationPath.size()) == animationPath)
|
if (pos != std::string::npos && name.compare(pos, name.size() - pos, ".nif") == 0)
|
||||||
{
|
loadBonesFromFile(node, name, resourceSystem);
|
||||||
size_t pos = name.find_last_of('.');
|
|
||||||
if (pos != std::string::npos && name.compare(pos, name.size()-pos, ".nif") == 0)
|
|
||||||
loadBonesFromFile(node, name, resourceSystem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
++found;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -294,20 +294,12 @@ namespace MWSound
|
||||||
if (mMusicFiles.find(playlist) == mMusicFiles.end())
|
if (mMusicFiles.find(playlist) == mMusicFiles.end())
|
||||||
{
|
{
|
||||||
std::vector<std::string> filelist;
|
std::vector<std::string> filelist;
|
||||||
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();
|
|
||||||
|
|
||||||
std::string pattern = "Music/" + playlist;
|
std::string pattern = "Music/" + playlist;
|
||||||
mVFS->normalizeFilename(pattern);
|
mVFS->normalizeFilename(pattern);
|
||||||
|
|
||||||
std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern);
|
for (const auto& name : mVFS->getRecursiveDirectoryIterator(pattern))
|
||||||
while (found != index.end())
|
filelist.push_back(name);
|
||||||
{
|
|
||||||
if (found->first.size() >= pattern.size() && found->first.substr(0, pattern.size()) == pattern)
|
|
||||||
filelist.push_back(found->first);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
++found;
|
|
||||||
}
|
|
||||||
|
|
||||||
mMusicFiles[playlist] = filelist;
|
mMusicFiles[playlist] = filelist;
|
||||||
}
|
}
|
||||||
|
@ -327,13 +319,11 @@ namespace MWSound
|
||||||
if (mMusicFiles.find("Title") == mMusicFiles.end())
|
if (mMusicFiles.find("Title") == mMusicFiles.end())
|
||||||
{
|
{
|
||||||
std::vector<std::string> filelist;
|
std::vector<std::string> filelist;
|
||||||
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();
|
|
||||||
// Is there an ini setting for this filename or something?
|
// Is there an ini setting for this filename or something?
|
||||||
std::string filename = "music/special/morrowind title.mp3";
|
std::string filename = "music/special/morrowind title.mp3";
|
||||||
auto found = index.find(filename);
|
if (mVFS->exists(filename))
|
||||||
if (found != index.end())
|
|
||||||
{
|
{
|
||||||
filelist.emplace_back(found->first);
|
filelist.emplace_back(filename);
|
||||||
mMusicFiles["Title"] = filelist;
|
mMusicFiles["Title"] = filelist;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -191,24 +191,14 @@ namespace Gui
|
||||||
|
|
||||||
void FontLoader::loadBitmapFonts(bool exportToFile)
|
void FontLoader::loadBitmapFonts(bool exportToFile)
|
||||||
{
|
{
|
||||||
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();
|
|
||||||
|
|
||||||
std::string pattern = "Fonts/";
|
std::string pattern = "Fonts/";
|
||||||
mVFS->normalizeFilename(pattern);
|
mVFS->normalizeFilename(pattern);
|
||||||
|
|
||||||
std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern);
|
for (const auto& name : mVFS->getRecursiveDirectoryIterator(pattern))
|
||||||
while (found != index.end())
|
|
||||||
{
|
{
|
||||||
const std::string& name = found->first;
|
size_t pos = name.find_last_of('.');
|
||||||
if (name.size() >= pattern.size() && name.substr(0, pattern.size()) == pattern)
|
if (pos != std::string::npos && name.compare(pos, name.size() - pos, ".fnt") == 0)
|
||||||
{
|
loadBitmapFont(name, exportToFile);
|
||||||
size_t pos = name.find_last_of('.');
|
|
||||||
if (pos != std::string::npos && name.compare(pos, name.size()-pos, ".fnt") == 0)
|
|
||||||
loadBitmapFont(name, exportToFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
++found;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,11 +86,6 @@ namespace VFS
|
||||||
return mIndex.find(normalized) != mIndex.end();
|
return mIndex.find(normalized) != mIndex.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::string, File*>& Manager::getIndex() const
|
|
||||||
{
|
|
||||||
return mIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::normalizeFilename(std::string &name) const
|
void Manager::normalizeFilename(std::string &name) const
|
||||||
{
|
{
|
||||||
normalize_path(name, mStrict);
|
normalize_path(name, mStrict);
|
||||||
|
@ -107,4 +102,9 @@ namespace VFS
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecursiveDirectoryIterator Manager::getRecursiveDirectoryIterator(const std::string& path) const
|
||||||
|
{
|
||||||
|
return RecursiveDirectoryIterator(mIndex, path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,51 @@ namespace VFS
|
||||||
class Archive;
|
class Archive;
|
||||||
class File;
|
class File;
|
||||||
|
|
||||||
|
class RecursiveDirectoryIterator;
|
||||||
|
RecursiveDirectoryIterator end(const RecursiveDirectoryIterator& iter);
|
||||||
|
|
||||||
|
class RecursiveDirectoryIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RecursiveDirectoryIterator(const std::map<std::string, File*>& index, const std::string& path)
|
||||||
|
: mPath(path)
|
||||||
|
, mIndex(&index)
|
||||||
|
, mIt(index.lower_bound(path))
|
||||||
|
{}
|
||||||
|
|
||||||
|
RecursiveDirectoryIterator(const RecursiveDirectoryIterator&) = default;
|
||||||
|
|
||||||
|
const std::string& operator*() const { return mIt->first; }
|
||||||
|
const std::string* operator->() const { return &mIt->first; }
|
||||||
|
|
||||||
|
bool operator!=(const RecursiveDirectoryIterator& other) { return mPath != other.mPath || mIt != other.mIt; }
|
||||||
|
|
||||||
|
RecursiveDirectoryIterator& operator++()
|
||||||
|
{
|
||||||
|
if (++mIt == mIndex->end() || !starts_with(mIt->first, mPath))
|
||||||
|
*this = end(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend RecursiveDirectoryIterator end(const RecursiveDirectoryIterator& iter);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool starts_with(const std::string& text, const std::string& start) { return text.rfind(start, 0) == 0; }
|
||||||
|
|
||||||
|
std::string mPath;
|
||||||
|
const std::map<std::string, File*>* mIndex;
|
||||||
|
std::map<std::string, File*>::const_iterator mIt;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline RecursiveDirectoryIterator begin(RecursiveDirectoryIterator iter) { return iter; }
|
||||||
|
|
||||||
|
inline RecursiveDirectoryIterator end(const RecursiveDirectoryIterator& iter)
|
||||||
|
{
|
||||||
|
RecursiveDirectoryIterator result(iter);
|
||||||
|
result.mIt = result.mIndex->end();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief The main class responsible for loading files from a virtual file system.
|
/// @brief The main class responsible for loading files from a virtual file system.
|
||||||
/// @par Various archive types (e.g. directories on the filesystem, or compressed archives)
|
/// @par Various archive types (e.g. directories on the filesystem, or compressed archives)
|
||||||
/// can be registered, and will be merged into a single file tree. If the same filename is
|
/// can be registered, and will be merged into a single file tree. If the same filename is
|
||||||
|
@ -40,10 +85,6 @@ namespace VFS
|
||||||
/// @note May be called from any thread once the index has been built.
|
/// @note May be called from any thread once the index has been built.
|
||||||
bool exists(const std::string& name) const;
|
bool exists(const std::string& name) const;
|
||||||
|
|
||||||
/// Get a complete list of files from all archives
|
|
||||||
/// @note May be called from any thread once the index has been built.
|
|
||||||
const std::map<std::string, File*>& getIndex() const;
|
|
||||||
|
|
||||||
/// Normalize the given filename, making slashes/backslashes consistent, and lower-casing if mStrict is false.
|
/// Normalize the given filename, making slashes/backslashes consistent, and lower-casing if mStrict is false.
|
||||||
/// @note May be called from any thread once the index has been built.
|
/// @note May be called from any thread once the index has been built.
|
||||||
void normalizeFilename(std::string& name) const;
|
void normalizeFilename(std::string& name) const;
|
||||||
|
@ -59,6 +100,13 @@ namespace VFS
|
||||||
Files::IStreamPtr getNormalized(const std::string& normalizedName) const;
|
Files::IStreamPtr getNormalized(const std::string& normalizedName) const;
|
||||||
|
|
||||||
std::string getArchive(const std::string& name) const;
|
std::string getArchive(const std::string& name) const;
|
||||||
|
|
||||||
|
/// Recursivly iterate over the elements of the given path
|
||||||
|
/// In practice it return all files of the VFS starting with the given path
|
||||||
|
/// @note the path is normalized
|
||||||
|
/// @note May be called from any thread once the index has been built.
|
||||||
|
RecursiveDirectoryIterator getRecursiveDirectoryIterator(const std::string& path) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mStrict;
|
bool mStrict;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue