Skip to content

Commit

Permalink
Use recurse subdirectory iterator to iterate over the VFS without exp…
Browse files Browse the repository at this point in the history
…osing internal details
  • Loading branch information
MocquillonCedric committed Sep 14, 2021
1 parent b6f5725 commit d4e2674
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 88 deletions.
5 changes: 1 addition & 4 deletions apps/niftest/niftest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,8 @@ void readVFS(VFS::Archive* anArchive,std::string archivePath = "")
myManager.addArchive(anArchive);
myManager.buildIndex();

std::map<std::string, VFS::File*> files=myManager.getIndex();
for(auto it=files.begin(); it!=files.end(); ++it)
for(const auto& name : myManager.getRecursiveDirectoryIterator(""))
{
std::string name = it->first;

try{
if(isNIF(name))
{
Expand Down
4 changes: 1 addition & 3 deletions apps/opencs/model/world/resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const *

size_t baseSize = mBaseDirectory.size();

const std::map<std::string, VFS::File*>& index = vfs->getIndex();
for (std::map<std::string, VFS::File*>::const_iterator it = index.begin(); it != index.end(); ++it)
for (const auto& filepath : vfs->getRecursiveDirectoryIterator(""))
{
std::string filepath = it->first;
if (filepath.size()<baseSize+1 ||
filepath.substr (0, baseSize)!=mBaseDirectory ||
(filepath[baseSize]!='/' && filepath[baseSize]!='\\'))
Expand Down
23 changes: 7 additions & 16 deletions apps/openmw/mwgui/loadingscreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,35 +66,26 @@ namespace MWGui

void LoadingScreen::findSplashScreens()
{
const std::map<std::string, VFS::File*>& index = mResourceSystem->getVFS()->getIndex();
std::string pattern = "Splash/";
mResourceSystem->getVFS()->normalizeFilename(pattern);

/* priority given to the left */
const std::array<std::string, 7> supported_extensions {{".tga", ".dds", ".ktx", ".png", ".bmp", ".jpeg", ".jpg"}};

auto found = index.lower_bound(pattern);
while (found != index.end())
for (const auto& name : mResourceSystem->getVFS()->getRecursiveDirectoryIterator(pattern))
{
const std::string& name = found->first;
if (name.size() >= pattern.size() && name.substr(0, pattern.size()) == pattern)
size_t pos = name.find_last_of('.');
if (pos != std::string::npos)
{
size_t pos = name.find_last_of('.');
if (pos != std::string::npos)
for (auto const& extension : supported_extensions)
{
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(found->first);
break; /* based on priority */
}
mSplashScreens.push_back(name);
break; /* based on priority */
}
}
}
else
break;
++found;
}
if (mSplashScreens.empty())
Log(Debug::Warning) << "Warning: no splash screens found!";
Expand Down
36 changes: 8 additions & 28 deletions apps/openmw/mwrender/animation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,6 @@ namespace MWRender

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;
if (animationPath.find("meshes") == 0)
{
Expand All @@ -602,19 +600,11 @@ namespace MWRender

mResourceSystem->getVFS()->normalizeFilename(animationPath);

std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(animationPath);
while (found != index.end())
for (const auto& name : mResourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath))
{
const std::string& name = found->first;
if (name.size() >= animationPath.size() && name.substr(0, animationPath.size()) == animationPath)
{
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;
size_t pos = name.find_last_of('.');
if (pos != std::string::npos && name.compare(pos, name.size() - pos, ".kf") == 0)
addSingleAnimSource(name, baseModel);
}
}

Expand Down Expand Up @@ -1295,8 +1285,6 @@ namespace MWRender
if (model.empty())
return;

const std::map<std::string, VFS::File*>& index = resourceSystem->getVFS()->getIndex();

std::string animationPath = model;
if (animationPath.find("meshes") == 0)
{
Expand All @@ -1306,19 +1294,11 @@ namespace MWRender

resourceSystem->getVFS()->normalizeFilename(animationPath);

std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(animationPath);
while (found != index.end())
for (const auto& name : resourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath))
{
const std::string& name = found->first;
if (name.size() >= animationPath.size() && name.substr(0, animationPath.size()) == animationPath)
{
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;
size_t pos = name.find_last_of('.');
if (pos != std::string::npos && name.compare(pos, name.size() - pos, ".nif") == 0)
loadBonesFromFile(node, name, resourceSystem);
}
}

Expand Down
18 changes: 4 additions & 14 deletions apps/openmw/mwsound/soundmanagerimp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,20 +294,12 @@ namespace MWSound
if (mMusicFiles.find(playlist) == mMusicFiles.end())
{
std::vector<std::string> filelist;
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();

std::string pattern = "Music/" + playlist;
mVFS->normalizeFilename(pattern);

std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern);
while (found != index.end())
{
if (found->first.size() >= pattern.size() && found->first.substr(0, pattern.size()) == pattern)
filelist.push_back(found->first);
else
break;
++found;
}
for (const auto& name : mVFS->getRecursiveDirectoryIterator(pattern))
filelist.push_back(name);

mMusicFiles[playlist] = filelist;
}
Expand All @@ -327,13 +319,11 @@ namespace MWSound
if (mMusicFiles.find("Title") == mMusicFiles.end())
{
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?
std::string filename = "music/special/morrowind title.mp3";
auto found = index.find(filename);
if (found != index.end())
if (mVFS->exists(filename))
{
filelist.emplace_back(found->first);
filelist.emplace_back(filename);
mMusicFiles["Title"] = filelist;
}
else
Expand Down
18 changes: 4 additions & 14 deletions components/fontloader/fontloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,24 +191,14 @@ namespace Gui

void FontLoader::loadBitmapFonts(bool exportToFile)
{
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();

std::string pattern = "Fonts/";
mVFS->normalizeFilename(pattern);

std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern);
while (found != index.end())
for (const auto& name : mVFS->getRecursiveDirectoryIterator(pattern))
{
const std::string& name = found->first;
if (name.size() >= pattern.size() && name.substr(0, pattern.size()) == pattern)
{
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;
size_t pos = name.find_last_of('.');
if (pos != std::string::npos && name.compare(pos, name.size() - pos, ".fnt") == 0)
loadBitmapFont(name, exportToFile);
}
}

Expand Down
10 changes: 5 additions & 5 deletions components/vfs/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,6 @@ namespace VFS
return mIndex.find(normalized) != mIndex.end();
}

const std::map<std::string, File*>& Manager::getIndex() const
{
return mIndex;
}

void Manager::normalizeFilename(std::string &name) const
{
normalize_path(name, mStrict);
Expand All @@ -107,4 +102,9 @@ namespace VFS
}
return {};
}

RecursiveDirectoryIterator Manager::getRecursiveDirectoryIterator(const std::string& path) const
{
return RecursiveDirectoryIterator(mIndex, path);
}
}
56 changes: 52 additions & 4 deletions components/vfs/manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,51 @@ namespace VFS
class Archive;
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.
/// @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
Expand Down Expand Up @@ -40,10 +85,6 @@ namespace VFS
/// @note May be called from any thread once the index has been built.
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.
/// @note May be called from any thread once the index has been built.
void normalizeFilename(std::string& name) const;
Expand All @@ -59,6 +100,13 @@ namespace VFS
Files::IStreamPtr getNormalized(const std::string& normalizedName) 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:
bool mStrict;

Expand Down

0 comments on commit d4e2674

Please sign in to comment.