@@ -16,40 +16,15 @@ ISystem::ISystem(core::smart_refctd_ptr<ISystem::ICaller>&& caller) : m_dispatch
16
16
// addArchiveLoader(core::make_smart_refctd_ptr<CArchiveLoaderTar>(nullptr));
17
17
}
18
18
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
-
43
19
core::smart_refctd_ptr<IFile> ISystem::impl_loadEmbeddedBuiltinData (const std::string& builtinPath, const std::pair<const uint8_t *,size_t >& found) const
44
20
{
45
21
#ifdef _NBL_EMBED_BUILTIN_RESOURCES_
46
22
if (found.first && found.second )
47
23
{
48
24
auto fileView = core::make_smart_refctd_ptr<CFileView<CNullAllocator>>(
49
- core::smart_refctd_ptr<ISystem>(this ),
50
25
builtinPath,
51
26
IFile::ECF_READ,
52
- found.first ,
27
+ const_cast < uint8_t *>( found.first ) ,
53
28
found.second
54
29
);
55
30
return fileView;
@@ -58,14 +33,21 @@ core::smart_refctd_ptr<IFile> ISystem::impl_loadEmbeddedBuiltinData(const std::s
58
33
return nullptr ;
59
34
}
60
35
36
+ constexpr const char * builtinPathPrefix = " nbl/builtin/" ;
61
37
bool ISystem::exists (const system::path& filename, const core::bitflag<IFile::E_CREATE_FLAGS> flags) const
62
38
{
63
39
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
+ }
69
51
// filename too long
70
52
if (filename.string ().size () >= sizeof (SRequestParams_CREATE_FILE::filename))
71
53
return false ;
@@ -78,17 +60,14 @@ bool ISystem::exists(const system::path& filename, const core::bitflag<IFile::E_
78
60
79
61
bool ISystem::isPathReadOnly (const system::path& p) const
80
62
{
63
+ // first check if its a builtin path
64
+ if (p.string ().find (builtinPathPrefix)==0 )
65
+ return true ;
66
+
81
67
// check all parent subpaths
82
68
auto curPath = p;
83
69
while (!curPath.empty () && curPath.parent_path () != curPath)
84
70
{
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
-
92
71
// then check for presence in an archive
93
72
auto archives = m_cachedArchiveFiles.findRange (curPath);
94
73
if (!archives.empty ())
@@ -103,33 +82,55 @@ bool ISystem::isPathReadOnly(const system::path& p) const
103
82
core::vector<system::path> ISystem::listItemsInDirectory (const system::path& p) const
104
83
{
105
84
core::vector<system::path> res;
106
- res.reserve (128u );
85
+ res.reserve (512u );
107
86
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
110
88
{
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 )
113
91
{
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 );
124
95
}
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 ());
125
106
}
126
107
else
127
108
{
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
+ }
131
133
}
132
- // TODO: recurse into any archives which could have been found!
133
134
return res;
134
135
}
135
136
@@ -204,18 +205,26 @@ bool ISystem::copy(const system::path& from, const system::path& to)
204
205
205
206
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)
206
207
{
208
+ // canonicalize
209
+ if (std::filesystem::exists (filename))
210
+ filename = std::filesystem::canonical (filename);
207
211
// try builtins
208
- if (!(flags.value &IFile::ECF_WRITE))
212
+ if (!(flags.value &IFile::ECF_WRITE) && filename. string (). find (builtinPathPrefix)== 0 )
209
213
{
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);
214
223
return ;
215
- }
224
+ # endif
216
225
}
217
- // try archives
218
- if (flags.value &IFile::ECF_READ )
226
+ // try archives (readonly, for now)
227
+ if (!( flags.value &IFile::ECF_WRITE) )
219
228
{
220
229
const auto found = findFileInArchive (filename);
221
230
if (found.archive )
0 commit comments