From d89034e540014f71136fc083abbec49a898dd156 Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Mon, 29 May 2023 08:05:06 +0200 Subject: [PATCH] replace template variables in shaders --- src/gpufont/shader_catalog.cpp | 60 ++++++++++++++++++++++++++++++---- src/gpufont/shader_catalog.hpp | 5 ++- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/gpufont/shader_catalog.cpp b/src/gpufont/shader_catalog.cpp index b6012dc..5aedc5c 100644 --- a/src/gpufont/shader_catalog.cpp +++ b/src/gpufont/shader_catalog.cpp @@ -20,10 +20,10 @@ class UpdateList { std::unordered_map updates; public: - void requestUpdate(const std::string & name){ + void requestUpdate(const std::string & name, bool immediately){ using namespace std::chrono_literals; std::lock_guard guard(mutex); - updates[name] = std::chrono::steady_clock::now() + 50ms; + updates[name] = std::chrono::steady_clock::now() + (immediately ? 0ms : 50ms); } std::vector collectDueUpdates(){ @@ -46,17 +46,39 @@ class ShaderCatalog::Impl { private: std::string dir; std::unordered_map > entries; + std::map replacements; + std::mutex replacementMutex; UpdateList list; public: + void setReplacement(const std::string & a, const std::string & b){ + std::lock_guard guard(replacementMutex); + replacements[a] = b; + } + const map & getReplacements(){ + std::lock_guard guard(replacementMutex); + return replacements; + } Impl(const std::string & dir) : dir(dir){ } - void requestUpdate(const std::string & name){ - list.requestUpdate(name); + void requestUpdate(const std::string & name, bool immediately){ + list.requestUpdate(name, immediately); } private: + + void replaceAll(std::string & str, const std::string & from, const std::string & to){ + if(from.empty()){ + return; + } + size_t start_pos = 0; + while((start_pos = str.find(from, start_pos)) != std::string::npos){ + str.replace(start_pos, from.length(), to); + start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' + } + } + std::string readFile(const std::string & filename, std::string & error){ std::ifstream stream(filename, std::ios::binary); if(!stream){ @@ -70,11 +92,24 @@ class ShaderCatalog::Impl { std::string result = std::string(size, 0); stream.read(&result[0], size); + if(!stream){ error = "failed to read: " + filename; return ""; } + { + //std::cout << "read shader from " << filename << " : " << result << std::endl; + const auto & r = getReplacements(); + for(const auto & pair : r){ + replaceAll(result, pair.first, pair.second); + //cout << "replace " << pair.first << " with " << pair.second << endl; + } + + //std::cout << "after replacement " << filename << " : " << result << std::endl; + + } + return result; } @@ -164,6 +199,7 @@ class ShaderCatalog::Impl { for(const std::string & name : updates){ auto it = entries.find(name); if(it == entries.end()){ + //cout << "this should have do update but don't in " << __LINE__ << endl; continue; } @@ -186,6 +222,18 @@ ShaderCatalog::ShaderCatalog(const std::string & dir) : impl(std::make_unique setReplacement(a, b); +} +const std::string & ShaderCatalog::getReplacement(const std::string & a){ + auto & replacements = impl->getReplacements(); + if(replacements.count(a) > 0){ + return replacements.at(a); + }else{ + return dummy; + } +} + std::shared_ptr ShaderCatalog::get(const std::string & name){ return impl->get(name); } @@ -194,7 +242,7 @@ void ShaderCatalog::update(){ impl->update(); } -void ShaderCatalog::requestUpdate(const std::string & name){ - impl->requestUpdate(name); +void ShaderCatalog::requestUpdate(const std::string & name, bool immediately){ + impl->requestUpdate(name, immediately); } } diff --git a/src/gpufont/shader_catalog.hpp b/src/gpufont/shader_catalog.hpp index b1c95fd..903dbd6 100644 --- a/src/gpufont/shader_catalog.hpp +++ b/src/gpufont/shader_catalog.hpp @@ -24,12 +24,15 @@ class ShaderCatalog { ShaderCatalog(const std::string & dir); ~ShaderCatalog(); + void setReplacement(const std::string & a, const std::string & b); + const std::string & getReplacement(const std::string & a); std::shared_ptr get(const std::string & name); void update(); - void requestUpdate(const std::string & name); + void requestUpdate(const std::string & name, bool immediately = false); private: class Impl; std::unique_ptr impl; + const std::string dummy = ""; }; }