Skip to content

Commit 1223ca0

Browse files
committed
Merge branch 'fix_std_23' into 'master'
Fix compilation with -std=23 See merge request OpenMW/openmw!5019
2 parents 3d1b8d1 + 402e1b3 commit 1223ca0

File tree

1 file changed

+126
-123
lines changed

1 file changed

+126
-123
lines changed

components/shader/shadermanager.cpp

Lines changed: 126 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <regex>
1010
#include <set>
1111
#include <sstream>
12+
#include <system_error>
1213
#include <unordered_map>
1314

1415
#include <osg/Program>
@@ -73,22 +74,6 @@ namespace
7374
+= static_cast<int>(std::count(source.begin() + lineDirectivePosition, source.begin() + foundPos, '\n'));
7475
return lineNumber;
7576
}
76-
}
77-
78-
namespace Shader
79-
{
80-
81-
ShaderManager::ShaderManager()
82-
{
83-
mHotReloadManager = std::make_unique<HotReloadManager>();
84-
}
85-
86-
ShaderManager::~ShaderManager() = default;
87-
88-
void ShaderManager::setShaderPath(const std::filesystem::path& path)
89-
{
90-
mPath = path;
91-
}
9277

9378
bool addLineDirectivesAfterConditionalBlocks(std::string& source)
9479
{
@@ -121,7 +106,7 @@ namespace Shader
121106
// Adjusts #line statements accordingly and detects cyclic includes.
122107
// cycleIncludeChecker is the set of files that include this file directly or indirectly, and is intentionally not a
123108
// reference to allow automatic cleanup.
124-
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,
125110
int& fileNumber, std::set<std::filesystem::path> cycleIncludeChecker,
126111
std::set<std::filesystem::path>& includedFiles)
127112
{
@@ -169,7 +154,8 @@ namespace Shader
169154
includeFstream.open(includePath);
170155
if (includeFstream.fail())
171156
{
172-
Log(Debug::Error) << "Shader " << fileName << " error: Failed to open include " << includePath;
157+
Log(Debug::Error) << "Shader " << fileName << " error: Failed to open include " << includePath << ": "
158+
<< std::generic_category().message(errno);
173159
return false;
174160
}
175161
int includedFileNumber = fileNumber++;
@@ -193,6 +179,127 @@ namespace Shader
193179
}
194180
return true;
195181
}
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+
}
196303

197304
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos)
198305
{
@@ -397,110 +504,6 @@ namespace Shader
397504
return true;
398505
}
399506

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

0 commit comments

Comments
 (0)