1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
// This file is part of the 64k demo project.
// It implements the ShaderComposer class.
#include "gpu/effects/shader_composer.h"
#include <set>
#include <sstream>
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<std::string>& 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<std::string>& dependencies,
const std::string& main_code) {
std::stringstream ss;
ss << "// Generated by ShaderComposer\n\n";
std::set<std::string> 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();
}
|