@@ -13,6 +13,20 @@ ShaderTemplate::ShaderTemplate(const util::Path &template_path) {
1313 auto file = template_path.open ();
1414 this ->template_code = file.read ();
1515 file.close ();
16+
17+ std::string marker = " // PLACEHOLDER: " ;
18+ size_t pos = 0 ;
19+
20+ while ((pos = this ->template_code .find (marker, pos)) != std::string::npos) {
21+ size_t name_start = pos + marker.length ();
22+ size_t line_end = this ->template_code .find (' \n ' , name_start);
23+ std::string name = this ->template_code .substr (name_start, line_end - name_start);
24+ // Trim trailing whitespace (space, tab, carriage return, etc.)
25+ name.erase (name.find_last_not_of (" \t\r\n " ) + 1 );
26+
27+ this ->placeholders .push_back ({name, pos, line_end - pos});
28+ pos = line_end;
29+ }
1630}
1731
1832void ShaderTemplate::load_snippets (const util::Path &snippet_path) {
@@ -38,28 +52,18 @@ void ShaderTemplate::add_snippet(const util::Path &snippet_path) {
3852renderer::resources::ShaderSource ShaderTemplate::generate_source () const {
3953 std::string result_src = template_code;
4054
41- // Process each placeholder
42- for (const auto &[name, snippet_code] : snippets) {
43- std::string placeholder = " // PLACEHOLDER: " + name;
44- size_t pos = result_src.find (placeholder);
45-
46- if (pos != std::string::npos) {
47- result_src.replace (pos, placeholder.length (), snippet_code);
55+ // Replace placeholders in reverse order (to avoid offset issues)
56+ for (auto it = placeholders.rbegin (); it != placeholders.rend (); ++it) {
57+ const auto &ph = *it;
58+ auto snippet_it = snippets.find (ph.name );
59+ if (snippet_it != snippets.end ()) {
60+ result_src.replace (ph.position , ph.length , snippet_it->second );
4861 }
4962 else {
50- log::log (WARN << " Placeholder not found in template : " << name);
63+ throw Error ( MSG (err) << " Missing snippet for placeholder : " << ph. name );
5164 }
5265 }
5366
54- // Check if all placeholders were replaced
55- size_t placeholder_pos = result_src.find (" // PLACEHOLDER:" );
56- if (placeholder_pos != std::string::npos) {
57- size_t line_end = result_src.find (' \n ' , placeholder_pos);
58- std::string missing = result_src.substr (placeholder_pos,
59- line_end - placeholder_pos);
60- throw Error (MSG (err) << " Missing snippet for placeholder: " << missing);
61- }
62-
6367 auto result = resources::ShaderSource (
6468 resources::shader_lang_t ::glsl,
6569 resources::shader_stage_t ::fragment,
0 commit comments