@@ -123,29 +123,17 @@ class NBL_API IShaderCompiler : public core::IReferenceCounted
123
123
124
124
virtual IShader::E_CONTENT_TYPE getCodeContentType () const = 0;
125
125
126
- class NBL_API IIncludeLoader : public core::IReferenceCounted
126
+ class NBL_API2 IIncludeLoader : public core::IReferenceCounted
127
127
{
128
128
public:
129
129
virtual std::string getInclude (const system::path& searchPath, const std::string& includeName) const = 0;
130
130
};
131
131
132
- class NBL_API IIncludeGenerator : public core::IReferenceCounted
132
+ class NBL_API2 IIncludeGenerator : public core::IReferenceCounted
133
133
{
134
134
public:
135
135
// ! if includeName doesn't begin with prefix from `getPrefix` this function will return an empty string
136
- virtual std::string getInclude (const std::string& includeName) const
137
- {
138
- core::vector<std::pair<std::regex, HandleFunc_t>> builtinNames = getBuiltinNamesToFunctionMapping ();
139
-
140
- for (const auto & pattern : builtinNames)
141
- if (std::regex_match (includeName, pattern.first ))
142
- {
143
- auto a = pattern.second (includeName);
144
- return a;
145
- }
146
-
147
- return {};
148
- }
136
+ virtual std::string getInclude (const std::string& includeName) const ;
149
137
150
138
virtual std::string_view getPrefix () const = 0;
151
139
@@ -156,176 +144,46 @@ class NBL_API IShaderCompiler : public core::IReferenceCounted
156
144
157
145
// ! Parses arguments from include path
158
146
// ! template is path/to/shader.hlsl/arg0/arg1/...
159
- static core::vector<std::string> parseArgumentsFromPath (const std::string& _path)
160
- {
161
- core::vector<std::string> args;
162
-
163
- std::stringstream ss{ _path };
164
- std::string arg;
165
- while (std::getline (ss, arg, ' /' ))
166
- args.push_back (std::move (arg));
167
-
168
- return args;
169
- }
147
+ static core::vector<std::string> parseArgumentsFromPath (const std::string& _path);
170
148
};
171
149
172
- class NBL_API CFileSystemIncludeLoader : public IIncludeLoader
150
+ class NBL_API2 CFileSystemIncludeLoader : public IIncludeLoader
173
151
{
174
152
public:
175
- CFileSystemIncludeLoader (core::smart_refctd_ptr<system::ISystem>&& system) : m_system(std::move(system))
176
- {}
177
-
178
- std::string getInclude (const system::path& searchPath, const std::string& includeName) const override
179
- {
180
- system::path path = searchPath / includeName;
181
- if (std::filesystem::exists (path))
182
- path = std::filesystem::canonical (path);
153
+ CFileSystemIncludeLoader (core::smart_refctd_ptr<system::ISystem>&& system);
183
154
184
- core::smart_refctd_ptr<system::IFile> f;
185
- {
186
- system::ISystem::future_t <core::smart_refctd_ptr<system::IFile>> future;
187
- m_system->createFile (future, path.c_str (), system::IFile::ECF_READ);
188
- f = future.get ();
189
- if (!f)
190
- return {};
191
- }
192
- const size_t size = f->getSize ();
193
-
194
- std::string contents (size, ' \0 ' );
195
- system::IFile::success_t succ;
196
- f->read (succ, contents.data (), 0 , size);
197
- const bool success = bool (succ);
198
- assert (success);
199
-
200
- return contents;
201
- }
155
+ std::string getInclude (const system::path& searchPath, const std::string& includeName) const override ;
202
156
203
157
protected:
204
158
core::smart_refctd_ptr<system::ISystem> m_system;
205
159
};
206
160
207
- class NBL_API CIncludeFinder : public core::IReferenceCounted
161
+ class NBL_API2 CIncludeFinder : public core::IReferenceCounted
208
162
{
209
163
public:
210
- CIncludeFinder (core::smart_refctd_ptr<system::ISystem>&& system) : m_defaultFileSystemLoader(core::make_smart_refctd_ptr<CFileSystemIncludeLoader>(std::move(system)))
211
- {
212
- addSearchPath (" " , m_defaultFileSystemLoader);
213
- }
164
+ CIncludeFinder (core::smart_refctd_ptr<system::ISystem>&& system);
214
165
215
166
// ! includes within <>
216
167
// @param requestingSourceDir: the directory where the incude was requested
217
168
// @param includeName: the string within <> of the include preprocessing directive
218
- std::string getIncludeStandard (const system::path& requestingSourceDir, const std::string& includeName) const
219
- {
220
- std::string ret = tryIncludeGenerators (includeName);
221
- if (ret.empty ())
222
- ret = trySearchPaths (includeName);
223
- if (ret.empty ())
224
- ret = m_defaultFileSystemLoader->getInclude (requestingSourceDir.string (), includeName);
225
- return ret;
226
- }
169
+ std::string getIncludeStandard (const system::path& requestingSourceDir, const std::string& includeName) const ;
227
170
228
171
// ! includes within ""
229
172
// @param requestingSourceDir: the directory where the incude was requested
230
173
// @param includeName: the string within "" of the include preprocessing directive
231
- std::string getIncludeRelative (const system::path& requestingSourceDir, const std::string& includeName) const
232
- {
233
- std::string ret = m_defaultFileSystemLoader->getInclude (requestingSourceDir.string (), includeName);
234
- if (ret.empty ())
235
- ret = trySearchPaths (includeName);
236
- return ret;
237
- }
174
+ std::string getIncludeRelative (const system::path& requestingSourceDir, const std::string& includeName) const ;
238
175
239
- core::smart_refctd_ptr<CFileSystemIncludeLoader> getDefaultFileSystemLoader () const { return m_defaultFileSystemLoader; }
176
+ inline core::smart_refctd_ptr<CFileSystemIncludeLoader> getDefaultFileSystemLoader () const { return m_defaultFileSystemLoader; }
240
177
241
- void addSearchPath (const std::string& searchPath, core::smart_refctd_ptr<IIncludeLoader> loader)
242
- {
243
- if (!loader)
244
- return ;
245
- m_loaders.push_back (LoaderSearchPath{ loader, searchPath });
246
- }
247
-
248
- void addGenerator (core::smart_refctd_ptr<IIncludeGenerator> generator)
249
- {
250
- if (!generator)
251
- return ;
178
+ void addSearchPath (const std::string& searchPath, const core::smart_refctd_ptr<IIncludeLoader>& loader);
252
179
253
- auto itr = m_generators.begin ();
254
- for (; itr != m_generators.end (); ++itr)
255
- {
256
- auto str = (*itr)->getPrefix ();
257
- if (str.compare (generator->getPrefix ()) <= 0 ) // Reverse Lexicographic Order
258
- break ;
259
- }
260
- m_generators.insert (itr, generator);
261
- }
180
+ void addGenerator (const core::smart_refctd_ptr<IIncludeGenerator>& generator);
262
181
263
182
protected:
264
183
265
- std::string trySearchPaths (const std::string& includeName) const
266
- {
267
- std::string ret;
268
- for (const auto & itr : m_loaders)
269
- {
270
- ret = itr.loader ->getInclude (itr.searchPath , includeName);
271
- if (!ret.empty ())
272
- break ;
273
- }
274
- return ret;
275
- }
276
-
277
- std::string tryIncludeGenerators (const std::string& includeName) const
278
- {
279
- // Need custom function because std::filesystem doesn't consider the parameters we use after the extension like CustomShader.hlsl/512/64
280
- auto removeExtension = [](const std::string& str)
281
- {
282
- return str.substr (0 , str.find_last_of (' .' ));
283
- };
184
+ std::string trySearchPaths (const std::string& includeName) const ;
284
185
285
- auto standardizePrefix = [](const std::string_view& prefix) -> std::string
286
- {
287
- std::string ret (prefix);
288
- // Remove Trailing '/' if any, to compare to filesystem paths
289
- if (*ret.rbegin () == ' /' && ret.size () > 1u )
290
- ret.resize (ret.size () - 1u );
291
- return ret;
292
- };
293
-
294
- auto extension_removed_path = system::path (removeExtension (includeName));
295
- system::path path = extension_removed_path.parent_path ();
296
-
297
- // Try Generators with Matching Prefixes:
298
- // Uses a "Path Peeling" method which goes one level up the directory tree until it finds a suitable generator
299
- auto end = m_generators.begin ();
300
- while (!path.empty () && path.root_name ().empty () && end != m_generators.end ())
301
- {
302
- auto begin = std::lower_bound (end, m_generators.end (), path.string (),
303
- [&standardizePrefix](const core::smart_refctd_ptr<IIncludeGenerator>& generator, const std::string& value)
304
- {
305
- const auto element = standardizePrefix (generator->getPrefix ());
306
- return element.compare (value) > 0 ; // first to return false is lower_bound -> first element that is <= value
307
- });
308
-
309
- // search from new beginning to real end
310
- end = std::upper_bound (begin, m_generators.end (), path.string (),
311
- [&standardizePrefix](const std::string& value, const core::smart_refctd_ptr<IIncludeGenerator>& generator)
312
- {
313
- const auto element = standardizePrefix (generator->getPrefix ());
314
- return value.compare (element) > 0 ; // first to return true is upper_bound -> first element that is < value
315
- });
316
-
317
- for (auto generatorIt = begin; generatorIt != end; generatorIt++)
318
- {
319
- auto str = (*generatorIt)->getInclude (includeName);
320
- if (!str.empty ())
321
- return str;
322
- }
323
-
324
- path = path.parent_path ();
325
- }
326
-
327
- return " " ;
328
- }
186
+ std::string tryIncludeGenerators (const std::string& includeName) const ;
329
187
330
188
struct LoaderSearchPath
331
189
{
0 commit comments