mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-25 16:43:33 +00:00
Simplify VFS index iteration
This commit is contained in:
parent
c04a0ca3a5
commit
65109b3822
@ -160,25 +160,6 @@ namespace MWLua
|
|||||||
|
|
||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
sol::usertype<VFS::Manager::StatefulIterator> vfsIterator
|
|
||||||
= context.mLua->sol().new_usertype<VFS::Manager::StatefulIterator>("VFSIterator");
|
|
||||||
vfsIterator[sol::meta_function::to_string] = [](const VFS::Manager::StatefulIterator& vfsIterator) {
|
|
||||||
return "VFSIterator{'" + vfsIterator.getPath() + "'}";
|
|
||||||
};
|
|
||||||
vfsIterator["path"] = sol::readonly_property(
|
|
||||||
[](const VFS::Manager::StatefulIterator& vfsIterator) { return vfsIterator.getPath(); });
|
|
||||||
|
|
||||||
auto createIter = [](VFS::Manager::StatefulIterator& vfsIterator) {
|
|
||||||
return sol::as_function([vfsIterator, i = 1]() mutable {
|
|
||||||
if (auto v = vfsIterator.next())
|
|
||||||
return std::tuple<sol::optional<int>, sol::optional<std::string_view>>(i++, *v);
|
|
||||||
else
|
|
||||||
return std::tuple<sol::optional<int>, sol::optional<std::string_view>>(sol::nullopt, sol::nullopt);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
vfsIterator["__pairs"] = createIter;
|
|
||||||
vfsIterator["__ipairs"] = createIter;
|
|
||||||
|
|
||||||
sol::usertype<FileHandle> handle = context.mLua->sol().new_usertype<FileHandle>("FileHandle");
|
sol::usertype<FileHandle> handle = context.mLua->sol().new_usertype<FileHandle>("FileHandle");
|
||||||
handle["fileName"] = sol::readonly_property([](const FileHandle& self) { return self.mFileName; });
|
handle["fileName"] = sol::readonly_property([](const FileHandle& self) { return self.mFileName; });
|
||||||
handle[sol::meta_function::to_string] = [](const FileHandle& self) {
|
handle[sol::meta_function::to_string] = [](const FileHandle& self) {
|
||||||
@ -346,8 +327,19 @@ namespace MWLua
|
|||||||
[](const sol::object&) -> sol::object { return sol::nil; });
|
[](const sol::object&) -> sol::object { return sol::nil; });
|
||||||
|
|
||||||
api["fileExists"] = [vfs](std::string_view fileName) -> bool { return vfs->exists(fileName); };
|
api["fileExists"] = [vfs](std::string_view fileName) -> bool { return vfs->exists(fileName); };
|
||||||
api["getIterator"]
|
api["pathsWithPrefix"] = [vfs](std::string_view prefix) {
|
||||||
= [vfs](std::string_view path) -> VFS::Manager::StatefulIterator { return vfs->getStatefulIterator(path); };
|
auto iterator = vfs->getRecursiveDirectoryIterator(prefix);
|
||||||
|
return sol::as_function([iterator, current = iterator.begin()]() mutable -> sol::optional<std::string> {
|
||||||
|
if (current != iterator.end())
|
||||||
|
{
|
||||||
|
const std::string& result = *current;
|
||||||
|
++current;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sol::nullopt;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return LuaUtil::makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
@ -89,17 +89,4 @@ namespace VFS
|
|||||||
++normalized.back();
|
++normalized.back();
|
||||||
return { it, mIndex.lower_bound(normalized) };
|
return { it, mIndex.lower_bound(normalized) };
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::StatefulIterator Manager::getStatefulIterator(std::string_view path) const
|
|
||||||
{
|
|
||||||
if (path.empty())
|
|
||||||
return { mIndex.begin(), mIndex.end(), std::string() };
|
|
||||||
std::string normalized = Path::normalizeFilename(path);
|
|
||||||
const auto it = mIndex.lower_bound(normalized);
|
|
||||||
if (it == mIndex.end() || !startsWith(it->first, normalized))
|
|
||||||
return { it, it, normalized };
|
|
||||||
std::string upperBound = normalized;
|
|
||||||
++upperBound.back();
|
|
||||||
return { it, mIndex.lower_bound(upperBound), normalized };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -49,18 +48,11 @@ namespace VFS
|
|||||||
const std::string& operator*() const { return mIt->first; }
|
const std::string& operator*() const { return mIt->first; }
|
||||||
const std::string* operator->() const { return &mIt->first; }
|
const std::string* operator->() const { return &mIt->first; }
|
||||||
bool operator!=(const RecursiveDirectoryIterator& other) { return mIt != other.mIt; }
|
bool operator!=(const RecursiveDirectoryIterator& other) { return mIt != other.mIt; }
|
||||||
bool operator==(const RecursiveDirectoryIterator& other) const { return mIt == other.mIt; }
|
|
||||||
RecursiveDirectoryIterator& operator++()
|
RecursiveDirectoryIterator& operator++()
|
||||||
{
|
{
|
||||||
++mIt;
|
++mIt;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
RecursiveDirectoryIterator operator++(int)
|
|
||||||
{
|
|
||||||
RecursiveDirectoryIterator old = *this;
|
|
||||||
mIt++;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, File*>::const_iterator mIt;
|
std::map<std::string, File*>::const_iterator mIt;
|
||||||
@ -69,31 +61,6 @@ namespace VFS
|
|||||||
using RecursiveDirectoryRange = IteratorPair<RecursiveDirectoryIterator>;
|
using RecursiveDirectoryRange = IteratorPair<RecursiveDirectoryIterator>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class StatefulIterator : RecursiveDirectoryRange
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
StatefulIterator(RecursiveDirectoryIterator first, RecursiveDirectoryIterator last, const std::string& path)
|
|
||||||
: RecursiveDirectoryRange(first, last)
|
|
||||||
, mCurrent(first)
|
|
||||||
, mPath(path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& getPath() const { return mPath; }
|
|
||||||
|
|
||||||
std::optional<std::string_view> next()
|
|
||||||
{
|
|
||||||
if (mCurrent == end())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
return *mCurrent++;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
RecursiveDirectoryIterator mCurrent;
|
|
||||||
std::string mPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Empty the file index and unregister archives.
|
// Empty the file index and unregister archives.
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
@ -126,13 +93,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.
|
||||||
RecursiveDirectoryRange getRecursiveDirectoryIterator(std::string_view path) const;
|
RecursiveDirectoryRange getRecursiveDirectoryIterator(std::string_view path) const;
|
||||||
|
|
||||||
/// Recursively iterate over the elements of the given path
|
|
||||||
/// In practice it return all files of the VFS starting with the given path
|
|
||||||
/// Stores iterator to current element.
|
|
||||||
/// @note the path is normalized
|
|
||||||
/// @note May be called from any thread once the index has been built.
|
|
||||||
StatefulIterator getStatefulIterator(std::string_view path) const;
|
|
||||||
|
|
||||||
/// Retrieve the absolute path to the file
|
/// Retrieve the absolute path to the file
|
||||||
/// @note Throws an exception if the file can not be found.
|
/// @note Throws an exception if the file can not be found.
|
||||||
/// @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.
|
||||||
|
@ -6,10 +6,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
-- @type VFSIterator
|
|
||||||
-- @field #string path VFS prefix path
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @type FileHandle
|
-- @type FileHandle
|
||||||
-- @field #string fileName VFS path to related file
|
-- @field #string fileName VFS path to related file
|
||||||
@ -135,14 +131,18 @@
|
|||||||
-- end
|
-- end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Get iterator to fetch file names with given path prefix from VFS
|
-- Get iterator function to fetch file names with given path prefix from VFS
|
||||||
-- @function [parent=#vfs] getIterator
|
-- @function [parent=#vfs] pathsWithPrefix
|
||||||
-- @param #string path Path prefix
|
-- @param #string path Path prefix
|
||||||
-- @return #VFSIterator Opened iterator
|
-- @return #function Function to get next file name
|
||||||
-- @usage local dir = vfs.getIterator("Music\\Explore");
|
-- @usage -- get all files with given prefix from VFS index
|
||||||
-- for _, fileName in pairs(dir) do
|
-- for fileName in vfs.pathsWithPrefix("Music\\Explore") do
|
||||||
-- print(fileName);
|
-- print(fileName);
|
||||||
-- end
|
-- end
|
||||||
|
-- @usage -- get some first files
|
||||||
|
-- local getNextFile = vfs.pathsWithPrefix("Music\\Explore");
|
||||||
|
-- local firstFile = getNextFile();
|
||||||
|
-- local secondFile = getNextFile();
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Detect a file handle type
|
-- Detect a file handle type
|
||||||
|
Loading…
x
Reference in New Issue
Block a user