Skip to content

Commit f45ca6c

Browse files
authored
fix: dynamic view gets (#123)
1 parent 39b0505 commit f45ca6c

File tree

3 files changed

+137
-82
lines changed

3 files changed

+137
-82
lines changed

ecsact/entt/wrapper/dynamic.hh

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ auto component_add_trivial(
6969
template<typename C>
7070
auto context_remove(
7171
ecsact_system_execution_context* context,
72-
[[maybe_unused]] ecsact_component_like_id component_id
72+
[[maybe_unused]] ecsact_component_like_id component_id,
73+
auto& view
7374
) -> void {
7475
assert(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id);
7576

@@ -88,7 +89,7 @@ auto context_remove(
8889

8990
// Stop here (tag)
9091
if constexpr(!std::is_empty_v<C>) {
91-
auto component = registry.template get<C>(entity);
92+
auto component = view.template get<C>(entity);
9293

9394
auto& remove_storage =
9495
registry.template emplace_or_replace<beforeremove_storage<C>>(entity);
@@ -100,7 +101,8 @@ auto context_remove(
100101
template<typename C>
101102
auto component_remove_trivial(
102103
::entt::registry& registry,
103-
ecsact::entt::entity_id entity_id
104+
ecsact::entt::entity_id entity_id,
105+
auto& view
104106
) -> void {
105107
using ecsact::entt::component_removed;
106108
using ecsact::entt::component_updated;
@@ -113,7 +115,7 @@ auto component_remove_trivial(
113115
registry.template emplace_or_replace<component_removed<C>>(entity_id);
114116

115117
if constexpr(!std::is_empty_v<C>) {
116-
auto component = registry.template get<C>(entity_id);
118+
auto component = view.template get<C>(entity_id);
117119

118120
auto& remove_storage =
119121
registry.template emplace_or_replace<beforeremove_storage<C>>(entity_id);
@@ -126,21 +128,23 @@ template<typename C>
126128
auto context_get(
127129
ecsact_system_execution_context* context,
128130
[[maybe_unused]] ecsact_component_like_id component_id,
129-
void* out_component_data
131+
void* out_component_data,
132+
auto& view
130133
) -> void {
131134
auto entity = context->entity;
132135
const auto& registry = *context->registry;
133136

134137
assert(registry.template any_of<C>(entity));
135138

136-
*static_cast<C*>(out_component_data) = registry.template get<C>(entity);
139+
*static_cast<C*>(out_component_data) = view.template get<C>(entity);
137140
}
138141

139142
template<typename C>
140143
auto context_update(
141144
ecsact_system_execution_context* context,
142145
[[maybe_unused]] ecsact_component_like_id component_id,
143-
const void* in_component_data
146+
const void* in_component_data,
147+
auto& view
144148
) -> void {
145149
using ecsact::entt::component_updated;
146150
using ecsact::entt::detail::exec_beforechange_storage;
@@ -151,9 +155,9 @@ auto context_update(
151155

152156
const auto& in_component = *static_cast<const C*>(in_component_data);
153157

154-
auto& current_component = registry.template get<C>(entity);
155-
auto& beforechange =
156-
registry.template get<exec_beforechange_storage<C>>(entity);
158+
auto& current_component = view.template get<C>(entity);
159+
auto& beforechange = view.template get<exec_beforechange_storage<C>>(entity);
160+
157161
if(!beforechange.has_update_occurred) {
158162
beforechange.value = current_component;
159163
beforechange.has_update_occurred = true;

rt_entt_codegen/core/print_sys_exec.cc

Lines changed: 113 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ static auto print_sys_exec_ctx_add(
132132
static auto print_sys_exec_ctx_remove(
133133
ecsact::codegen_plugin_context& ctx,
134134
const ecsact::rt_entt_codegen::ecsact_entt_system_details& details,
135-
capability_t sys_caps
135+
capability_t sys_caps,
136+
const std::string& view_type_name
136137
) -> void {
137138
using ecsact::cc_lang_support::cpp_identifier;
138139
using ecsact::cpp_codegen_plugin_util::block;
@@ -171,35 +172,43 @@ static auto print_sys_exec_ctx_remove(
171172
type_name,
172173
">(this, ecsact_id_cast<ecsact_component_like_id>(",
173174
type_name,
174-
"::id));\n"
175+
"::id), *view);\n"
175176
);
176177
return;
177178
}
178-
block(
179-
ctx,
180-
"static const auto remove_fns = "
181-
"std::unordered_map<ecsact_component_like_id, "
182-
"decltype(&ecsact_system_execution_context_remove)>",
183-
[&] {
184-
for(int i = 0; i < remove_comps.size(); ++i) {
185-
const auto comp_id = remove_comps[i];
186-
auto type_name = cpp_identifier(decl_full_name(comp_id));
187-
ctx.write(
188-
"{ecsact_id_cast<ecsact_component_like_id>(",
189-
type_name,
190-
"::id), &wrapper::dynamic::context_remove<",
191-
type_name,
192-
"> },"
193-
);
194-
}
179+
ctx.write(std::format(
180+
"using remove_fn_t = void (*)(ecsact_system_execution_context*, "
181+
"ecsact_component_like_id, {}_t&);\n",
182+
view_type_name
183+
));
184+
185+
ctx.write("static const auto remove_fns = []()\n");
186+
187+
block(ctx, "", [&] {
188+
ctx.write(
189+
"auto result = std::unordered_map<ecsact_component_like_id, "
190+
"remove_fn_t>{};\n"
191+
);
192+
for(const auto comp_id : details.removable_comps) {
193+
auto type_name = cpp_identifier(decl_full_name(comp_id));
194+
ctx.write(
195+
"result[ecsact_id_cast<ecsact_component_like_id>(",
196+
type_name,
197+
"::id)] = &wrapper::dynamic::context_remove<",
198+
type_name,
199+
">;\n"
200+
);
195201
}
196-
);
197-
ctx.write(";\n");
202+
203+
ctx.write("return result;\n");
204+
});
205+
ctx.write("();\n");
198206
}
199207

200208
static auto print_sys_exec_ctx_get(
201209
ecsact::codegen_plugin_context& ctx,
202-
const ecsact::rt_entt_codegen::ecsact_entt_system_details& details
210+
const ecsact::rt_entt_codegen::ecsact_entt_system_details& details,
211+
const std::string& view_type_name
203212
) -> void {
204213
using ecsact::cc_lang_support::cpp_identifier;
205214
using ecsact::cpp_codegen_plugin_util::block;
@@ -249,34 +258,44 @@ static auto print_sys_exec_ctx_get(
249258
);
250259
return;
251260
}
252-
block(
253-
ctx,
254-
"static const auto get_fns = "
255-
"std::unordered_map<ecsact_component_like_id, "
256-
"decltype(&ecsact_system_execution_context_get)>",
257-
[&] {
258-
for(const auto comp_id : details.readable_comps) {
259-
auto type_name = cpp_identifier(decl_full_name(comp_id));
260-
ctx.write(
261-
"{ecsact_id_cast<ecsact_component_like_id>(",
262-
type_name,
263-
"::id), &wrapper::dynamic::context_get<",
264-
type_name,
265-
"> },"
266-
);
267-
}
261+
262+
ctx.write(std::format(
263+
"using get_fn_t = void (*)(ecsact_system_execution_context*, "
264+
"ecsact_component_like_id, void *, {}_t&);\n",
265+
view_type_name
266+
));
267+
268+
ctx.write("static const auto get_fns = []()\n");
269+
270+
block(ctx, "", [&] {
271+
ctx.write(
272+
"auto result = std::unordered_map<ecsact_component_like_id, "
273+
"get_fn_t>{};\n"
274+
);
275+
for(const auto comp_id : details.readable_comps) {
276+
auto type_name = cpp_identifier(decl_full_name(comp_id));
277+
ctx.write(
278+
"result[ecsact_id_cast<ecsact_component_like_id>(",
279+
type_name,
280+
"::id)] = &wrapper::dynamic::context_get<",
281+
type_name,
282+
">;\n"
283+
);
268284
}
269-
);
270-
ctx.write(";\n");
285+
286+
ctx.write("return result;\n");
287+
});
288+
ctx.write("();\n");
271289

272290
ctx.write(
273-
"get_fns.at(component_id)(this, component_id, out_component_data);\n"
291+
"get_fns.at(component_id)(this, component_id, out_component_data, *view);\n"
274292
);
275293
}
276294

277295
static auto print_sys_exec_ctx_update(
278296
ecsact::codegen_plugin_context& ctx,
279-
const ecsact::rt_entt_codegen::ecsact_entt_system_details& details
297+
const ecsact::rt_entt_codegen::ecsact_entt_system_details& details,
298+
const std::string& view_type_name
280299
) -> void {
281300
using ecsact::cc_lang_support::cpp_identifier;
282301
using ecsact::cpp_codegen_plugin_util::block;
@@ -302,31 +321,42 @@ static auto print_sys_exec_ctx_update(
302321
">(this, ecsact_id_cast<ecsact_component_like_id>(",
303322
type_name,
304323
"::id),",
305-
"component_data); \n"
324+
"component_data, *view); \n"
306325
);
307326
return;
308327
}
309-
block(
310-
ctx,
311-
"static const auto update_fns = "
312-
"std::unordered_map<ecsact_component_like_id, "
313-
"decltype(&ecsact_system_execution_context_update)>",
314-
[&] {
315-
for(const auto comp_id : details.readable_comps) {
316-
auto type_name = cpp_identifier(decl_full_name(comp_id));
317-
ctx.write(
318-
"{ecsact_id_cast<ecsact_component_like_id>(",
319-
type_name,
320-
"::id), &wrapper::dynamic::context_update<",
321-
type_name,
322-
"> },"
323-
);
324-
}
328+
329+
ctx.write(std::format(
330+
"using update_fn_t = void (*)(ecsact_system_execution_context*, "
331+
"ecsact_component_like_id, const void *, {}_t&);\n",
332+
view_type_name
333+
));
334+
335+
ctx.write("static const auto update_fns = []()\n");
336+
337+
block(ctx, "", [&] {
338+
ctx.write(
339+
"auto result = std::unordered_map<ecsact_component_like_id, "
340+
"update_fn_t>{};\n"
341+
);
342+
for(const auto comp_id : details.writable_comps) {
343+
auto type_name = cpp_identifier(decl_full_name(comp_id));
344+
ctx.write(
345+
"result[ecsact_id_cast<ecsact_component_like_id>(",
346+
type_name,
347+
"::id)] = &wrapper::dynamic::context_update<",
348+
type_name,
349+
">;\n"
350+
);
325351
}
326-
);
327-
ctx.write(";\n");
328352

329-
ctx.write("update_fns.at(component_id)(this, component_id, component_data);\n"
353+
ctx.write("return result;\n");
354+
});
355+
ctx.write("();\n");
356+
357+
ctx.write(
358+
"update_fns.at(component_id)(this, component_id, component_data, "
359+
"*view);\n"
330360
);
331361
}
332362

@@ -644,14 +674,16 @@ static auto print_ecsact_entt_system_details(
644674
additional_view_components
645675
);
646676

677+
ctx.write("using view_t = decltype(view);\n");
678+
647679
if constexpr(is_system) {
648680
if(system_needs_sorted_entities(options.sys_like_id)) {
649681
ctx.write("view.use<", system_sorting_struct_name, ">();\n");
650682
}
651683
}
652684

653685
block(ctx, "struct : ecsact_system_execution_context ", [&] {
654-
ctx.write("decltype(view)* view;\n");
686+
ctx.write("view_t* view;\n");
655687

656688
ctx.write(
657689
"std::unordered_map<ecsact_entity_id,ecsact_system_execution_"
@@ -666,9 +698,9 @@ static auto print_ecsact_entt_system_details(
666698
ctx.write("\n");
667699
print_sys_exec_ctx_action(ctx, details, options.sys_like_id);
668700
print_sys_exec_ctx_add(ctx, details, sys_caps);
669-
print_sys_exec_ctx_remove(ctx, details, sys_caps);
670-
print_sys_exec_ctx_get(ctx, details);
671-
print_sys_exec_ctx_update(ctx, details);
701+
print_sys_exec_ctx_remove(ctx, details, sys_caps, "view");
702+
print_sys_exec_ctx_get(ctx, details, "view");
703+
print_sys_exec_ctx_update(ctx, details, "view");
672704
print_sys_exec_ctx_has(ctx, details);
673705
print_sys_exec_ctx_generate(ctx, details);
674706
print_sys_exec_ctx_parent(ctx);
@@ -841,7 +873,8 @@ static auto print_ecsact_entt_system_details(
841873
ctx.write(
842874
"// If this assertion triggers this is an indicator of a codegen "
843875
"failure.\n"
844-
"// Please report to https://github.com/ecsact-dev/ecsact_rt_entt\n"
876+
"// Please report to "
877+
"https://github.com/ecsact-dev/ecsact_rt_entt\n"
845878
);
846879
ctx.write(
847880
"assert(",
@@ -922,18 +955,26 @@ static auto print_other_contexts(
922955
other_details
923956
);
924957

958+
ctx.write(std::format("using {}_t = decltype({});\n", view_name, view_name)
959+
);
960+
925961
block(ctx, "struct " + struct_header, [&] {
926962
using namespace std::string_literals;
927963
using ecsact::rt_entt_codegen::util::decl_cpp_ident;
928964
using std::views::transform;
929965

930-
ctx.write("decltype(", view_name, ")* view;\n");
966+
ctx.write(std::format("{}_t* view;\n", view_name));
931967
ctx.write("\n");
932968
print_sys_exec_ctx_action(ctx, other_details, options.sys_like_id);
933969
print_sys_exec_ctx_add(ctx, other_details, assoc_detail.capabilities);
934-
print_sys_exec_ctx_remove(ctx, other_details, assoc_detail.capabilities);
935-
print_sys_exec_ctx_get(ctx, other_details);
936-
print_sys_exec_ctx_update(ctx, other_details);
970+
print_sys_exec_ctx_remove(
971+
ctx,
972+
other_details,
973+
assoc_detail.capabilities,
974+
view_name
975+
);
976+
print_sys_exec_ctx_get(ctx, other_details, view_name);
977+
print_sys_exec_ctx_update(ctx, other_details, view_name);
937978
print_sys_exec_ctx_has(ctx, other_details);
938979
print_sys_exec_ctx_generate(ctx, other_details);
939980
print_sys_exec_ctx_parent(ctx);
@@ -998,7 +1039,7 @@ static auto print_trivial_system_like(
9981039
"ecsact::entt::wrapper::dynamic::component_remove_trivial<",
9991040
type_name,
10001041
">(registry, "
1001-
"ecsact::entt::entity_id(entity));\n"
1042+
"ecsact::entt::entity_id(entity), view);\n"
10021043
);
10031044
}
10041045
}

rt_entt_codegen/shared/util.hh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <string>
66
#include <utility>
77
#include <ranges>
8+
#include <format>
89
#include "ecsact/codegen/plugin.hh"
910
#include "ecsact/lang-support/lang-cc.hh"
1011
#include "ecsact/runtime/meta.h"
@@ -289,6 +290,15 @@ auto make_view( //
289290
details.get_comps | transform(decl_cpp_ident<ecsact_component_like_id>)
290291
));
291292

293+
for(auto comp_id : details.writable_comps) {
294+
auto comp_name = decl_cpp_ident(comp_id);
295+
296+
additional_components.push_back(std::format(
297+
"ecsact::entt::detail::exec_beforechange_storage<{}>",
298+
comp_name
299+
));
300+
}
301+
292302
if(!additional_components.empty()) {
293303
ctx.write(", ");
294304
ctx.write(comma_delim(additional_components));

0 commit comments

Comments
 (0)