// This file is part of the 64k demo project. // It implements the ShaderComposer class. #include "gpu/effects/shader_composer.h" #include #include ShaderComposer& ShaderComposer::Get() { static ShaderComposer instance; return instance; } void ShaderComposer::RegisterSnippet(const std::string& name, const std::string& code) { snippets_[name] = code; } void ShaderComposer::ResolveRecursive(const std::string& source, std::stringstream& ss, std::set& included) { std::istringstream stream(source); std::string line; while (std::getline(stream, line)) { // Check for #include "snippet_name" if (line.compare(0, 9, "#include ") == 0) { size_t start = line.find('"'); size_t end = line.find('"', start + 1); if (start != std::string::npos && end != std::string::npos) { std::string name = line.substr(start + 1, end - start - 1); if (included.find(name) == included.end()) { included.insert(name); auto it = snippets_.find(name); if (it != snippets_.end()) { ss << "// --- Included: " << name << " ---\n"; ResolveRecursive(it->second, ss, included); ss << "// --- End Include: " << name << " ---\n"; } else { ss << "// ERROR: Snippet not found: " << name << "\n"; } } } } else { ss << line << "\n"; } } } std::string ShaderComposer::Compose(const std::vector& dependencies, const std::string& main_code) { std::stringstream ss; ss << "// Generated by ShaderComposer\n\n"; std::set included; // Process explicit dependencies first for (const auto& dep : dependencies) { if (included.find(dep) == included.end()) { included.insert(dep); auto it = snippets_.find(dep); if (it != snippets_.end()) { ss << "// --- Dependency: " << dep << " ---\n"; ResolveRecursive(it->second, ss, included); ss << "\n"; } } } ss << "// --- Main Code ---\n"; ResolveRecursive(main_code, ss, included); return ss.str(); }