Skip to content

Commit 2725d9b

Browse files
Rewrite ISystem::listItemsInDirectory
remove deprecated `ISystem::loadBuiltinData` function
1 parent c11bafd commit 2725d9b

File tree

3 files changed

+81
-71
lines changed

3 files changed

+81
-71
lines changed

include/nbl/system/ISystem.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,16 @@ class ISystem : public core::IReferenceCounted
111111
}
112112
};
113113

114-
// [[deprecated]] use `createFile` instead
115-
core::smart_refctd_ptr<IFile> loadBuiltinData(const std::string& builtinPath) const;
116-
117114
//! Compile time resource ID
118115
template<typename StringUniqueType>
119116
inline core::smart_refctd_ptr<IFile> loadBuiltinData() const
120117
{
121118
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
122119
return impl_loadEmbeddedBuiltinData(StringUniqueType::value,nbl::builtin::get_resource<StringUniqueType>());
123120
#else
124-
return loadBuiltinData(StringUniqueType::value);
121+
future_t<core::smart_refctd_ptr<IFile>> future;
122+
createFile(future,StringUniqueType::value,core::bitflag(IFileBase::ECF_READ)|IFileBase::ECF_MAPPABLE);
123+
return future.get();
125124
#endif
126125
}
127126

@@ -177,7 +176,7 @@ class ISystem : public core::IReferenceCounted
177176
//
178177
void createFile(
179178
future_t<core::smart_refctd_ptr<IFile>>& future, // creation may happen on a dedicated thread, so its async
180-
std::filesystem::path filename, // absolute path within our virtual filesystem
179+
path filename, // absolute path within our virtual filesystem
181180
const core::bitflag<IFileBase::E_CREATE_FLAGS> flags, // access flags (IMPORTANT: files from most archives wont open with ECF_WRITE bit)
182181
const std::string_view& accessToken="" // usually password for archives, but should be SSH key for URL downloads
183182
);

src/nbl/asset/utils/IGLSLEmbeddedIncludeLoader.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ class IGLSLEmbeddedIncludeLoader : public IBuiltinIncludeLoader
5050
//
5151
inline std::string getFromDiskOrEmbedding(const std::string& _name) const
5252
{
53+
system::ISystem::future_t<core::smart_refctd_ptr<system::IFile>> future;
5354
auto path = "nbl/builtin/" + _name;
54-
auto data = s->loadBuiltinData(path);
55+
s->createFile(future,path,core::bitflag(system::IFileBase::ECF_READ)|system::IFileBase::ECF_MAPPABLE);
56+
auto data = future.get();
5557
if (!data)
5658
return "";
5759
auto begin = reinterpret_cast<const char*>(data->getMappedPointer());

src/nbl/system/ISystem.cpp

Lines changed: 74 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,15 @@ ISystem::ISystem(core::smart_refctd_ptr<ISystem::ICaller>&& caller) : m_dispatch
1616
//addArchiveLoader(core::make_smart_refctd_ptr<CArchiveLoaderTar>(nullptr));
1717
}
1818

19-
core::smart_refctd_ptr<IFile> ISystem::loadBuiltinData(const std::string& builtinPath) const
20-
{
21-
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
22-
return impl_loadEmbeddedBuiltinData(builtinPath,nbl::builtin::get_resource_runtime(builtinPath));
23-
#else
24-
constexpr auto pathPrefix = "nbl/builtin/";
25-
auto pos = builtinPath.find(pathPrefix);
26-
std::string path;
27-
if (pos != std::string::npos)
28-
path = builtinResourceDirectory + builtinPath.substr(pos + strlen(pathPrefix));
29-
else
30-
path = builtinResourceDirectory + builtinPath;
31-
32-
future_t<core::smart_refctd_ptr<IFile>> fut;
33-
createFile(future, path.c_str(), core::bitflag<IFile::E_CREATE_FLAGS>(IFile::ECF_READ) :: IFile::ECF_MAPPABLE);
34-
auto file = fut.get();
35-
if (file.get())
36-
{
37-
return file;
38-
}
39-
return nullptr;
40-
#endif
41-
}
42-
4319
core::smart_refctd_ptr<IFile> ISystem::impl_loadEmbeddedBuiltinData(const std::string& builtinPath, const std::pair<const uint8_t*,size_t>& found) const
4420
{
4521
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
4622
if (found.first && found.second)
4723
{
4824
auto fileView = core::make_smart_refctd_ptr<CFileView<CNullAllocator>>(
49-
core::smart_refctd_ptr<ISystem>(this),
5025
builtinPath,
5126
IFile::ECF_READ,
52-
found.first,
27+
const_cast<uint8_t*>(found.first),
5328
found.second
5429
);
5530
return fileView;
@@ -58,14 +33,21 @@ core::smart_refctd_ptr<IFile> ISystem::impl_loadEmbeddedBuiltinData(const std::s
5833
return nullptr;
5934
}
6035

36+
constexpr const char* builtinPathPrefix = "nbl/builtin/";
6137
bool ISystem::exists(const system::path& filename, const core::bitflag<IFile::E_CREATE_FLAGS> flags) const
6238
{
6339
const bool writeUsage = flags.value&IFile::ECF_WRITE;
64-
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
65-
std::pair<const uint8_t*, size_t> found = nbl::builtin::get_resource_runtime(filename.string());
66-
if (!writeUsage && found.first && found.second)
67-
return true;
68-
#endif
40+
if (!writeUsage && filename.string().find(builtinPathPrefix)==0)
41+
{
42+
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
43+
std::pair<const uint8_t*, size_t> found = nbl::builtin::get_resource_runtime(filename.string());
44+
if (found.first && found.second)
45+
return true;
46+
#else
47+
if (exists(builtinResourceDirectory/filename))
48+
return true;
49+
#endif
50+
}
6951
// filename too long
7052
if (filename.string().size() >= sizeof(SRequestParams_CREATE_FILE::filename))
7153
return false;
@@ -78,17 +60,14 @@ bool ISystem::exists(const system::path& filename, const core::bitflag<IFile::E_
7860

7961
bool ISystem::isPathReadOnly(const system::path& p) const
8062
{
63+
// first check if its a builtin path
64+
if (p.string().find(builtinPathPrefix)==0)
65+
return true;
66+
8167
// check all parent subpaths
8268
auto curPath = p;
8369
while (!curPath.empty() && curPath.parent_path() != curPath)
8470
{
85-
// first check if its a builtin path
86-
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
87-
std::pair<const uint8_t*,size_t> found = nbl::builtin::get_resource_runtime(curPath.string());
88-
if (found.first && found.second)
89-
return true;
90-
#endif
91-
9271
// then check for presence in an archive
9372
auto archives = m_cachedArchiveFiles.findRange(curPath);
9473
if (!archives.empty())
@@ -103,33 +82,55 @@ bool ISystem::isPathReadOnly(const system::path& p) const
10382
core::vector<system::path> ISystem::listItemsInDirectory(const system::path& p) const
10483
{
10584
core::vector<system::path> res;
106-
res.reserve(128u);
85+
res.reserve(512u);
10786

108-
// TODO: check for path being a builtin
109-
if (isPathReadOnly(p)) // TODO: better check for archives
87+
auto addArchiveItems = [this,&res](const path& archPath) -> void
11088
{
111-
auto curPath = p;
112-
while (!curPath.empty() && curPath.parent_path() != curPath)
89+
const auto archives = m_cachedArchiveFiles.findRange(archPath);
90+
for (auto& arch : archives)
11391
{
114-
auto archives = m_cachedArchiveFiles.findRange(curPath);
115-
for (auto& arch : archives)
116-
{
117-
auto rel = std::filesystem::relative(p, arch.first);
118-
auto res = arch.second->listAssets(rel.generic_string().c_str());
119-
std::for_each(res.begin(), res.end(), [&arch](system::path& p) {p = arch.first / p; });
120-
return res;
121-
}
122-
123-
curPath = curPath.parent_path().generic_string();
92+
const auto assets = arch.second->listAssets();
93+
for (auto& item : assets)
94+
res.push_back(archPath/item.pathRelativeToArchive);
12495
}
96+
};
97+
98+
std::error_code err;
99+
const auto directories = std::filesystem::recursive_directory_iterator(p,err);
100+
if (!err)
101+
for (auto entry : directories)
102+
{
103+
res.push_back(entry.path());
104+
// entry could have been an archive
105+
addArchiveItems(entry.path());
125106
}
126107
else
127108
{
128-
uint32_t fileCount = std::distance(std::filesystem::recursive_directory_iterator(p), std::filesystem::recursive_directory_iterator{});
129-
for (auto entry : std::filesystem::recursive_directory_iterator(p))
130-
res.push_back(entry.path());
109+
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
110+
// TODO: Change the python generator and make builtinResourceData.cpp's `resourcesByFilename` a nicely named `extern` variable
111+
// then in ISystem precompute a [unordered] multimap with keys being builtin subpaths and values being full paths they contain
112+
// find all the values here and iterate over them, adding to `res
113+
#else
114+
err.clear();
115+
// check root path is prefixed with "nbl/builtin/"
116+
if (p.string().find(builtinPathPrefix) == 0)
117+
{
118+
const auto subdirs = std::filesystem::recursive_directory_iterator(builtinResourceDirectory/p,err);
119+
if (!err)
120+
for (auto entry : subdirs) // there are never any archives inside builtins
121+
res.push_back(entry.path());
122+
}
123+
#endif
124+
// check for part of subpath being an archive
125+
system::path path = std::filesystem::exists(p) ? std::filesystem::canonical(p.parent_path()):p.parent_path();
126+
// going up the directory tree
127+
while (!path.empty() && path.parent_path()!=path)
128+
{
129+
path = std::filesystem::exists(path) ? std::filesystem::canonical(path):path;
130+
addArchiveItems(path);
131+
path = path.parent_path();
132+
}
131133
}
132-
// TODO: recurse into any archives which could have been found!
133134
return res;
134135
}
135136

@@ -204,18 +205,26 @@ bool ISystem::copy(const system::path& from, const system::path& to)
204205

205206
void ISystem::createFile(future_t<core::smart_refctd_ptr<IFile>>& future, std::filesystem::path filename, const core::bitflag<IFileBase::E_CREATE_FLAGS> flags, const std::string_view& accessToken)
206207
{
208+
// canonicalize
209+
if (std::filesystem::exists(filename))
210+
filename = std::filesystem::canonical(filename);
207211
// try builtins
208-
if (!(flags.value&IFile::ECF_WRITE))
212+
if (!(flags.value&IFile::ECF_WRITE) && filename.string().find(builtinPathPrefix)==0)
209213
{
210-
auto file = loadBuiltinData(filename.string());
211-
if (file)
212-
{
213-
future.notify(std::move(file));
214+
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
215+
auto file = impl_loadEmbeddedBuiltinData(filename.string(),nbl::builtin::get_resource_runtime(filename.string()));
216+
if (file)
217+
{
218+
future.notify(std::move(file));
219+
return;
220+
}
221+
#else
222+
createFile(future,builtinResourceDirectory/filename,flags);
214223
return;
215-
}
224+
#endif
216225
}
217-
// try archives
218-
if (flags.value&IFile::ECF_READ)
226+
// try archives (readonly, for now)
227+
if (!(flags.value&IFile::ECF_WRITE))
219228
{
220229
const auto found = findFileInArchive(filename);
221230
if (found.archive)

0 commit comments

Comments
 (0)