Cogs.Core
SubContext.cpp
1#include "SubContext.h"
2
3#include "../Systems/Core/CameraSystem.h"
4
5#include "Foundation/Logging/Logger.h"
6
7namespace
8{
9 const Cogs::Logging::Log logger = Cogs::Logging::getLogger("SubContext");
10}
11
12Cogs::Core::SubContext::SubContext(ExpressionContext* parent)
13{
14 if (parent) expressionContext.inherit(parent);
15}
16
17void Cogs::Core::SubContext::useVariables(Context* context, const std::vector<ParsedValue>& vars)
18{
19 for (const auto& p : vars) {
20 switch (p.type)
21 {
22 case Cogs::Core::ParsedDataType::Unknown:
23 case Cogs::Core::ParsedDataType::String:
24 {
25 auto tokens = Cogs::Core::tokenize(p.value);
26 if (tokens.size() == 2) {
27 auto value = std::stod(tokens[1].to_string());
28 value = context->variables->get(tokens[0], value);
29
30 auto& expVal = expressionContext.add(p.key, value);
31 toPull.push_back({ tokens[0].to_string(), &expVal.value });
32 }
33 else {
34 LOG_ERROR(logger, "Malformed useVariables entry: %s", p.value.c_str());
35 }
36 break;
37 }
38 case Cogs::Core::ParsedDataType::Float:
39 expressionContext.add(p.key, p.floatValue);
40 break;
41
42 default:
43 break;
44 }
45 }
46}
47
48void Cogs::Core::SubContext::setVariables(Context* /*context*/, const std::vector<ParsedValue>& vars)
49{
50 for (const auto& p : vars) {
51 switch (p.type)
52 {
53 case Cogs::Core::ParsedDataType::Unknown:
54 case Cogs::Core::ParsedDataType::String:
55 {
56 expressionContext.add(p.key, 0.0);
57 auto expr = expressionContext.compile(p.value, p.key);
58 if (expr) {
59 expressionContext.update(expr, 0.0);
60 toUpdate.push_back(expr);
61 }
62 break;
63 }
64 case Cogs::Core::ParsedDataType::Float:
65 expressionContext.add(p.key, p.floatValue);
66 break;
67
68 default:
69 break;
70 }
71 }
72}
73
74void Cogs::Core::SubContext::useComponentFields(RenderTaskContext* renderContext, const std::vector<ParsedValue>& vars)
75{
76 for (const auto& p : vars) {
77 auto tokens = Cogs::Core::tokenize(p.value);
78
79 if (tokens.size() != 2) {
80 LOG_ERROR(logger, "Malformed useComponentFields entry: %s", p.value.c_str());
81 continue;
82 }
83
84 auto& expVal = expressionContext.add(p.key, std::stod(tokens[1].to_string()));
85
86 TokenStream hierarchy;
87 tokens.reserve(8);
88 split(tokens[0], ".", hierarchy);
89
90 if (2 <= hierarchy.size() && renderContext->cameraData && renderContext->cameraData->camera) {
91 const auto compHandle = renderContext->cameraData->camera.resolveComponent<Cogs::Core::CameraComponent>()->getComponentHandle(hierarchy[0]);
92 if (auto* component = compHandle.resolve(); component) {
93 auto& componentType = Cogs::Reflection::TypeDatabase::getType(component->getTypeId());
94 auto field = componentType.getField(hierarchy[1]);
95 if (field) {
96
97 uint32_t index = 0;
98 if (3 <= hierarchy.size()) {
99 switch (hierarchy[2][0])
100 {
101 case 'x': case 'r': index = 0; break;
102 case 'y': case 'g': index = 1; break;
103 case 'z': case 'b': index = 2; break;
104 case 'w': case 'a': index = 3; break;
105 default:
106 break;
107 }
108 }
109
110 auto& fieldType = Cogs::Reflection::TypeDatabase::getType(field->getTypeId());
111 auto hash = Cogs::StringView(fieldType.getName().c_str()).hash();
112
113 size_t offset = 0;
114 ParsedDataType baseType = ParsedDataType::Unknown;
115
116 switch (hash)
117 {
118 case Cogs::hash("bool"):
119 offset = field->getOffset();
120 baseType = ParsedDataType::Bool;
121 break;
122 case Cogs::hash("uint32_t"):
123 offset = field->getOffset();
124 baseType = ParsedDataType::UInt;
125 break;
126 case Cogs::hash("uvec2"):
127 offset = field->getOffset() + sizeof(uint32_t) * std::min(index, 1u);
128 baseType = ParsedDataType::UInt;
129 break;
130 case Cogs::hash("uvec3"):
131 offset = field->getOffset() + sizeof(uint32_t) * std::min(index, 2u);
132 baseType = ParsedDataType::UInt;
133 break;
134 case Cogs::hash("uvec4"):
135 offset = field->getOffset() + sizeof(uint32_t) * std::min(index, 3u);
136 baseType = ParsedDataType::UInt;
137 break;
138 case Cogs::hash("int32_t"):
139 offset = field->getOffset();
140 baseType = ParsedDataType::Int;
141 break;
142 case Cogs::hash("ivec2"):
143 offset = field->getOffset() + sizeof(int32_t) * std::min(index, 1u);
144 baseType = ParsedDataType::Int;
145 break;
146 case Cogs::hash("ivec3"):
147 offset = field->getOffset() + sizeof(int32_t) * std::min(index, 2u);
148 baseType = ParsedDataType::Int;
149 break;
150 case Cogs::hash("ivec4"):
151 offset = field->getOffset() + sizeof(int32_t) * std::min(index, 3u);
152 baseType = ParsedDataType::Int;
153 break;
154 case Cogs::hash("float"):
155 offset = field->getOffset();
156 baseType = ParsedDataType::Float;
157 break;
158 case Cogs::hash("vec2"):
159 offset = field->getOffset() + sizeof(float) * std::min(index, 1u);
160 baseType = ParsedDataType::Float;
161 break;
162 case Cogs::hash("vec3"):
163 offset = field->getOffset() + sizeof(float) * std::min(index, 2u);
164 baseType = ParsedDataType::Float;
165 break;
166 case Cogs::hash("vec4"):
167 offset = field->getOffset() + sizeof(float) * std::min(index, 3u);
168 baseType = ParsedDataType::Float;
169 break;
170 default:
171 break;
172 }
173 if (baseType != ParsedDataType::Unknown) {
174 compFieldsToPull.push_back({ compHandle, offset, baseType, &expVal.value });
175 }
176 else {
177 LOG_ERROR(logger, "useComponentFields: Unsupported type %s", fieldType.getName().c_str());
178 }
179 }
180 else {
181 LOG_ERROR(logger, "useComponentFields: Component %s doesn't have field %s", hierarchy[0].to_string().c_str(), hierarchy[1].to_string().c_str());
182 }
183 }
184 else {
185 LOG_ERROR(logger, "useComponentFields: couldn't find component %s in entity", hierarchy[0].to_string().c_str());
186 }
187 }
188 }
189
190}
191
192
193void Cogs::Core::SubContext::pullVariables(Context* context)
194{
195 for (const auto& p : toPull) {
196 *p.second = context->variables->get(p.first, *p.second);
197 }
198 for (const auto& p : compFieldsToPull) {
199 if (!std::get<0>(p)) continue;
200 const auto* component = std::get<0>(p).resolve();
201 const auto* src = (char*)component + std::get<1>(p);
202 auto* dst = std::get<3>(p);
203 switch (std::get<2>(p))
204 {
205 case ParsedDataType::Bool: *dst = *(const bool*)src ? 1 : 0; break;
206 case ParsedDataType::Int: *dst = *(const int32_t*)src; break;
207 case ParsedDataType::UInt: *dst = *(const uint32_t*)src; break;
208 case ParsedDataType::Float: *dst = *(const float*)src; break;
209 default:
210 break;
211 }
212 }
213
214 for (auto& e : toUpdate) {
215 expressionContext.update(e, 0.0);
216 }
217}
Log implementation class.
Definition: LogManager.h:139
static const Type & getType()
Get the Type of the given template argument.
Definition: TypeDatabase.h:168
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:24
constexpr size_t hash() const noexcept
Get the hash code of the string.
Definition: StringView.h:200
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
Definition: HashFunctions.h:62
STL namespace.