Skip to content

Commit 402e1b3

Browse files
committed
Fix compilation with -std=23
/usr/include/c++/15.2.1/bits/unique_ptr.h: In instantiation of ‘constexpr std::__detail::__unique_ptr_t<_Tp> std::make_unique(_Args&& ...) [with _Tp = Shader::HotReloadManager; _Args = {}; __detail::__unique_ptr_t<_Tp> = __detail::__unique_ptr_t<Shader::HotReloadManager>]’: /home/elsid/dev/openmw/components/shader/shadermanager.cpp:83:63: required from here 83 | mHotReloadManager = std::make_unique<HotReloadManager>(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ /usr/include/c++/15.2.1/bits/unique_ptr.h:1085:30: error: invalid use of incomplete type ‘struct Shader::HotReloadManager’ 1085 | { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ components/shader/shadermanager.hpp:24:12: note: forward declaration of ‘struct Shader::HotReloadManager’ 24 | struct HotReloadManager; | ^~~~~~~~~~~~~~~~
1 parent cef1bb1 commit 402e1b3

File tree

1 file changed

+122
-123
lines changed

1 file changed

+122
-123
lines changed

components/shader/shadermanager.cpp

Lines changed: 122 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,6 @@ namespace
7474
+= static_cast<int>(std::count(source.begin() + lineDirectivePosition, source.begin() + foundPos, '\n'));
7575
return lineNumber;
7676
}
77-
}
78-
79-
namespace Shader
80-
{
81-
82-
ShaderManager::ShaderManager()
83-
{
84-
mHotReloadManager = std::make_unique<HotReloadManager>();
85-
}
86-
87-
ShaderManager::~ShaderManager() = default;
88-
89-
void ShaderManager::setShaderPath(const std::filesystem::path& path)
90-
{
91-
mPath = path;
92-
}
9377

9478
bool addLineDirectivesAfterConditionalBlocks(std::string& source)
9579
{
@@ -122,7 +106,7 @@ namespace Shader
122106
// Adjusts #line statements accordingly and detects cyclic includes.
123107
// cycleIncludeChecker is the set of files that include this file directly or indirectly, and is intentionally not a
124108
// reference to allow automatic cleanup.
125-
static bool parseIncludes(const std::filesystem::path& shaderPath, std::string& source, const std::string& fileName,
109+
bool parseIncludes(const std::filesystem::path& shaderPath, std::string& source, const std::string& fileName,
126110
int& fileNumber, std::set<std::filesystem::path> cycleIncludeChecker,
127111
std::set<std::filesystem::path>& includedFiles)
128112
{
@@ -195,6 +179,127 @@ namespace Shader
195179
}
196180
return true;
197181
}
182+
}
183+
184+
namespace Shader
185+
{
186+
struct HotReloadManager
187+
{
188+
using KeysHolder = std::set<ShaderManager::MapKey>;
189+
190+
std::unordered_map<std::string, KeysHolder> mShaderFiles;
191+
std::unordered_map<std::string, std::set<std::filesystem::path>> templateIncludedFiles;
192+
std::filesystem::file_time_type mLastAutoRecompileTime;
193+
bool mHotReloadEnabled;
194+
bool mTriggerReload;
195+
196+
HotReloadManager()
197+
{
198+
mTriggerReload = false;
199+
mHotReloadEnabled = false;
200+
mLastAutoRecompileTime = std::filesystem::file_time_type::clock::now();
201+
}
202+
203+
void addShaderFiles(const std::string& templateName, const ShaderManager::DefineMap& defines)
204+
{
205+
const std::set<std::filesystem::path>& shaderFiles = templateIncludedFiles[templateName];
206+
for (const std::filesystem::path& file : shaderFiles)
207+
{
208+
mShaderFiles[Files::pathToUnicodeString(file)].insert(std::make_pair(templateName, defines));
209+
}
210+
}
211+
212+
void update(ShaderManager& manager, osgViewer::Viewer& viewer)
213+
{
214+
auto timeSinceLastCheckMillis = std::chrono::duration_cast<std::chrono::milliseconds>(
215+
std::filesystem::file_time_type::clock::now() - mLastAutoRecompileTime);
216+
if ((mHotReloadEnabled && timeSinceLastCheckMillis.count() > 200) || mTriggerReload == true)
217+
{
218+
reloadTouchedShaders(manager, viewer);
219+
}
220+
mTriggerReload = false;
221+
}
222+
223+
void reloadTouchedShaders(ShaderManager& manager, osgViewer::Viewer& viewer)
224+
{
225+
bool threadsRunningToStop = false;
226+
for (auto& [pathShaderToTest, shaderKeys] : mShaderFiles)
227+
{
228+
const std::filesystem::file_time_type writeTime = std::filesystem::last_write_time(pathShaderToTest);
229+
if (writeTime.time_since_epoch() > mLastAutoRecompileTime.time_since_epoch())
230+
{
231+
if (!threadsRunningToStop)
232+
{
233+
threadsRunningToStop = viewer.areThreadsRunning();
234+
if (threadsRunningToStop)
235+
viewer.stopThreading();
236+
}
237+
238+
for (const auto& [templateName, shaderDefines] : shaderKeys)
239+
{
240+
ShaderManager::ShaderMap::iterator shaderIt
241+
= manager.mShaders.find(std::make_pair(templateName, shaderDefines));
242+
if (shaderIt == manager.mShaders.end())
243+
{
244+
Log(Debug::Error) << "Failed to find shader " << templateName;
245+
continue;
246+
}
247+
248+
ShaderManager::TemplateMap::iterator templateIt = manager.mShaderTemplates.find(
249+
templateName); // Can't be Null, if we're here it means the template was added
250+
assert(templateIt != manager.mShaderTemplates.end());
251+
std::string& shaderSource = templateIt->second;
252+
std::set<std::filesystem::path> insertedPaths;
253+
std::filesystem::path path = (std::filesystem::path(manager.mPath) / templateName);
254+
std::ifstream stream;
255+
stream.open(path);
256+
if (stream.fail())
257+
{
258+
Log(Debug::Error)
259+
<< "Failed to open " << path << ": " << std::generic_category().message(errno);
260+
continue;
261+
}
262+
std::stringstream buffer;
263+
buffer << stream.rdbuf();
264+
265+
// parse includes
266+
int fileNumber = 1;
267+
std::string source = buffer.str();
268+
if (!addLineDirectivesAfterConditionalBlocks(source)
269+
|| !parseIncludes(std::filesystem::path(manager.mPath), source, templateName, fileNumber,
270+
{}, insertedPaths))
271+
{
272+
break;
273+
}
274+
shaderSource = std::move(source);
275+
276+
std::vector<std::string> linkedShaderNames;
277+
if (!manager.createSourceFromTemplate(
278+
shaderSource, linkedShaderNames, templateName, shaderDefines))
279+
{
280+
break;
281+
}
282+
shaderIt->second->setShaderSource(shaderSource);
283+
}
284+
}
285+
}
286+
if (threadsRunningToStop)
287+
viewer.startThreading();
288+
mLastAutoRecompileTime = std::filesystem::file_time_type::clock::now();
289+
}
290+
};
291+
292+
ShaderManager::ShaderManager()
293+
{
294+
mHotReloadManager = std::make_unique<HotReloadManager>();
295+
}
296+
297+
ShaderManager::~ShaderManager() = default;
298+
299+
void ShaderManager::setShaderPath(const std::filesystem::path& path)
300+
{
301+
mPath = path;
302+
}
198303

199304
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos)
200305
{
@@ -399,112 +504,6 @@ namespace Shader
399504
return true;
400505
}
401506

402-
struct HotReloadManager
403-
{
404-
using KeysHolder = std::set<ShaderManager::MapKey>;
405-
406-
std::unordered_map<std::string, KeysHolder> mShaderFiles;
407-
std::unordered_map<std::string, std::set<std::filesystem::path>> templateIncludedFiles;
408-
std::filesystem::file_time_type mLastAutoRecompileTime;
409-
bool mHotReloadEnabled;
410-
bool mTriggerReload;
411-
412-
HotReloadManager()
413-
{
414-
mTriggerReload = false;
415-
mHotReloadEnabled = false;
416-
mLastAutoRecompileTime = std::filesystem::file_time_type::clock::now();
417-
}
418-
419-
void addShaderFiles(const std::string& templateName, const ShaderManager::DefineMap& defines)
420-
{
421-
const std::set<std::filesystem::path>& shaderFiles = templateIncludedFiles[templateName];
422-
for (const std::filesystem::path& file : shaderFiles)
423-
{
424-
mShaderFiles[Files::pathToUnicodeString(file)].insert(std::make_pair(templateName, defines));
425-
}
426-
}
427-
428-
void update(ShaderManager& manager, osgViewer::Viewer& viewer)
429-
{
430-
auto timeSinceLastCheckMillis = std::chrono::duration_cast<std::chrono::milliseconds>(
431-
std::filesystem::file_time_type::clock::now() - mLastAutoRecompileTime);
432-
if ((mHotReloadEnabled && timeSinceLastCheckMillis.count() > 200) || mTriggerReload == true)
433-
{
434-
reloadTouchedShaders(manager, viewer);
435-
}
436-
mTriggerReload = false;
437-
}
438-
439-
void reloadTouchedShaders(ShaderManager& manager, osgViewer::Viewer& viewer)
440-
{
441-
bool threadsRunningToStop = false;
442-
for (auto& [pathShaderToTest, shaderKeys] : mShaderFiles)
443-
{
444-
const std::filesystem::file_time_type writeTime = std::filesystem::last_write_time(pathShaderToTest);
445-
if (writeTime.time_since_epoch() > mLastAutoRecompileTime.time_since_epoch())
446-
{
447-
if (!threadsRunningToStop)
448-
{
449-
threadsRunningToStop = viewer.areThreadsRunning();
450-
if (threadsRunningToStop)
451-
viewer.stopThreading();
452-
}
453-
454-
for (const auto& [templateName, shaderDefines] : shaderKeys)
455-
{
456-
ShaderManager::ShaderMap::iterator shaderIt
457-
= manager.mShaders.find(std::make_pair(templateName, shaderDefines));
458-
if (shaderIt == manager.mShaders.end())
459-
{
460-
Log(Debug::Error) << "Failed to find shader " << templateName;
461-
continue;
462-
}
463-
464-
ShaderManager::TemplateMap::iterator templateIt = manager.mShaderTemplates.find(
465-
templateName); // Can't be Null, if we're here it means the template was added
466-
assert(templateIt != manager.mShaderTemplates.end());
467-
std::string& shaderSource = templateIt->second;
468-
std::set<std::filesystem::path> insertedPaths;
469-
std::filesystem::path path = (std::filesystem::path(manager.mPath) / templateName);
470-
std::ifstream stream;
471-
stream.open(path);
472-
if (stream.fail())
473-
{
474-
Log(Debug::Error)
475-
<< "Failed to open " << path << ": " << std::generic_category().message(errno);
476-
continue;
477-
}
478-
std::stringstream buffer;
479-
buffer << stream.rdbuf();
480-
481-
// parse includes
482-
int fileNumber = 1;
483-
std::string source = buffer.str();
484-
if (!addLineDirectivesAfterConditionalBlocks(source)
485-
|| !parseIncludes(std::filesystem::path(manager.mPath), source, templateName, fileNumber,
486-
{}, insertedPaths))
487-
{
488-
break;
489-
}
490-
shaderSource = std::move(source);
491-
492-
std::vector<std::string> linkedShaderNames;
493-
if (!manager.createSourceFromTemplate(
494-
shaderSource, linkedShaderNames, templateName, shaderDefines))
495-
{
496-
break;
497-
}
498-
shaderIt->second->setShaderSource(shaderSource);
499-
}
500-
}
501-
}
502-
if (threadsRunningToStop)
503-
viewer.startThreading();
504-
mLastAutoRecompileTime = std::filesystem::file_time_type::clock::now();
505-
}
506-
};
507-
508507
osg::ref_ptr<osg::Shader> ShaderManager::getShader(
509508
std::string templateName, const ShaderManager::DefineMap& defines, std::optional<osg::Shader::Type> type)
510509
{

0 commit comments

Comments
 (0)