replace template variables in shaders

This commit is contained in:
jrkb 2023-05-29 08:05:06 +02:00
parent 7a0f588bcb
commit d89034e540
2 changed files with 58 additions and 7 deletions

View file

@ -20,10 +20,10 @@ class UpdateList {
std::unordered_map <std::string, std::chrono::steady_clock::time_point> updates; std::unordered_map <std::string, std::chrono::steady_clock::time_point> updates;
public: public:
void requestUpdate(const std::string & name){ void requestUpdate(const std::string & name, bool immediately){
using namespace std::chrono_literals; using namespace std::chrono_literals;
std::lock_guard <std::mutex> guard(mutex); std::lock_guard <std::mutex> guard(mutex);
updates[name] = std::chrono::steady_clock::now() + 50ms; updates[name] = std::chrono::steady_clock::now() + (immediately ? 0ms : 50ms);
} }
std::vector <std::string> collectDueUpdates(){ std::vector <std::string> collectDueUpdates(){
@ -46,17 +46,39 @@ class ShaderCatalog::Impl {
private: private:
std::string dir; std::string dir;
std::unordered_map <std::string, std::shared_ptr <Entry> > entries; std::unordered_map <std::string, std::shared_ptr <Entry> > entries;
std::map <std::string, std::string> replacements;
std::mutex replacementMutex;
UpdateList list; UpdateList list;
public: public:
void setReplacement(const std::string & a, const std::string & b){
std::lock_guard <std::mutex> guard(replacementMutex);
replacements[a] = b;
}
const map <std::string, std::string> & getReplacements(){
std::lock_guard <std::mutex> guard(replacementMutex);
return replacements;
}
Impl(const std::string & dir) : dir(dir){ Impl(const std::string & dir) : dir(dir){
} }
void requestUpdate(const std::string & name){ void requestUpdate(const std::string & name, bool immediately){
list.requestUpdate(name); list.requestUpdate(name, immediately);
} }
private: 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::string readFile(const std::string & filename, std::string & error){
std::ifstream stream(filename, std::ios::binary); std::ifstream stream(filename, std::ios::binary);
if(!stream){ if(!stream){
@ -70,11 +92,24 @@ class ShaderCatalog::Impl {
std::string result = std::string(size, 0); std::string result = std::string(size, 0);
stream.read(&result[0], size); stream.read(&result[0], size);
if(!stream){ if(!stream){
error = "failed to read: " + filename; error = "failed to read: " + filename;
return ""; 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; return result;
} }
@ -164,6 +199,7 @@ class ShaderCatalog::Impl {
for(const std::string & name : updates){ for(const std::string & name : updates){
auto it = entries.find(name); auto it = entries.find(name);
if(it == entries.end()){ if(it == entries.end()){
//cout << "this should have do update but don't in " << __LINE__ << endl;
continue; continue;
} }
@ -186,6 +222,18 @@ ShaderCatalog::ShaderCatalog(const std::string & dir) : impl(std::make_unique <I
ShaderCatalog::~ShaderCatalog(){ ShaderCatalog::~ShaderCatalog(){
} }
void ShaderCatalog::setReplacement(const std::string & a, const std::string & b){
impl->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::Entry> ShaderCatalog::get(const std::string & name){ std::shared_ptr <ShaderCatalog::Entry> ShaderCatalog::get(const std::string & name){
return impl->get(name); return impl->get(name);
} }
@ -194,7 +242,7 @@ void ShaderCatalog::update(){
impl->update(); impl->update();
} }
void ShaderCatalog::requestUpdate(const std::string & name){ void ShaderCatalog::requestUpdate(const std::string & name, bool immediately){
impl->requestUpdate(name); impl->requestUpdate(name, immediately);
} }
} }

View file

@ -24,12 +24,15 @@ class ShaderCatalog {
ShaderCatalog(const std::string & dir); ShaderCatalog(const std::string & dir);
~ShaderCatalog(); ~ShaderCatalog();
void setReplacement(const std::string & a, const std::string & b);
const std::string & getReplacement(const std::string & a);
std::shared_ptr <Entry> get(const std::string & name); std::shared_ptr <Entry> get(const std::string & name);
void update(); void update();
void requestUpdate(const std::string & name); void requestUpdate(const std::string & name, bool immediately = false);
private: private:
class Impl; class Impl;
std::unique_ptr <Impl> impl; std::unique_ptr <Impl> impl;
const std::string dummy = "";
}; };
} }