Skip to content

Commit ff0fdd5

Browse files
committed
fix: generate, actions, and association data issues
1 parent 5139cba commit ff0fdd5

File tree

12 files changed

+215
-72
lines changed

12 files changed

+215
-72
lines changed

.vscode/launch.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"cwd": "${workspaceFolder}",
99
"args": [
1010
"--gtest_catch_exceptions",
11+
// "--gtest_break_on_failure",
1112
],
1213
"type": "cppvsdbg",
1314
"windows": {

ecsact/entt/error_check.hh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,18 @@ auto check_update_component_error( //
4747
)");
4848
}
4949

50+
template<typename A>
51+
auto check_action_error( //
52+
::entt::registry&,
53+
const A&
54+
) -> ecsact_execute_systems_error {
55+
static_assert(detail::error_check_unimplemented_by_codegen<A>, R"(
56+
-----------------------------------------------------------------------------
57+
| (!) CODEGEN ERROR |
58+
| `check_update_component_error<>` template specialization cannot be found. |
59+
| This is typically generated by ecsact_rt_entt_codegen. |
60+
-----------------------------------------------------------------------------
61+
)");
62+
}
63+
5064
} // namespace ecsact::entt

ecsact/entt/wrapper/core.hh

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,6 @@ auto remove_component_exec_options(
193193
reg.template get<C>(entity)
194194
);
195195
}
196-
// NOTE(Kelwan): Check if a system is trivial
197-
// AKA: No read or write components and no adding non-tag components
198-
// If it is trivial, generate code for a manual system impl execution
199-
// Do it in template_specialization so execute_system isn't generated for
200-
// trivial systems
201196

202197
reg.template erase<C>(entity);
203198
reg.template remove<component_added<C>>(entity);
@@ -209,7 +204,7 @@ auto remove_component_exec_options(
209204
}
210205
}
211206

212-
inline auto _trigger_create_entity_event(
207+
inline auto _trigger_create_entity_events(
213208
ecsact_registry_id registry_id,
214209
ecsact::entt::detail::execution_events_collector& events_collector
215210
) -> void {
@@ -229,7 +224,7 @@ inline auto _trigger_create_entity_event(
229224
}
230225
}
231226

232-
inline auto _trigger_destroy_entity_event(
227+
inline auto _trigger_destroy_entity_events(
233228
ecsact_registry_id registry_id,
234229
ecsact::entt::detail::execution_events_collector& events_collector
235230
) -> void {
@@ -351,11 +346,31 @@ auto _trigger_remove_component_event(
351346
}
352347
}
353348

354-
inline auto handle_execution_options(
355-
ecsact_registry_id registry_id,
356-
ecsact_execution_options* options
357-
) -> void {
349+
auto check_action_error_t(
350+
ecsact_registry_id registry_id,
351+
const void* action_data
352+
) -> ecsact_execute_systems_error;
353+
354+
template<typename A>
355+
inline auto check_action_error(
356+
ecsact_registry_id registry_id,
357+
const void* action_data
358+
) -> ecsact_execute_systems_error {
358359
auto& reg = ecsact::entt::get_registry(registry_id);
360+
361+
auto action = *static_cast<const A*>(action_data);
362+
auto result = ecsact::entt::check_action_error(reg, action);
363+
364+
return result;
365+
}
366+
367+
template<typename C>
368+
inline auto clear_component(ecsact_registry_id registry_id) -> void {
369+
auto& reg = ecsact::entt::get_registry(registry_id);
370+
371+
reg.clear<ecsact::entt::component_added<C>>();
372+
reg.clear<ecsact::entt::component_changed<C>>();
373+
reg.clear<ecsact::entt::component_removed<C>>();
359374
}
360375

361376
} // namespace ecsact::entt::wrapper::core

ecsact/entt/wrapper/dynamic.hh

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,17 +178,14 @@ template<typename C>
178178
auto context_generate_add(
179179
ecsact_system_execution_context* context,
180180
ecsact_component_id component_id,
181-
const void* component_data
181+
const void* component_data,
182+
ecsact::entt::entity_id entity
182183
) -> void {
183184
using ecsact::entt::detail::created_entity;
184185
using ecsact::entt::detail::pending_add;
185186

186187
auto& registry = *context->registry;
187188

188-
// NOTE: This is flawed. An entity is being created for every component in a
189-
// generate components list
190-
auto entity = registry.create();
191-
192189
registry.template emplace<created_entity>(
193190
entity,
194191
created_entity{

rt_entt_codegen/core/check_error_template_specializations.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,40 @@ static auto print_check_update_component_error_template_specialization(
9797
ctx.write("return ECSACT_UPDATE_OK;");
9898
}
9999

100+
static auto print_check_action_error_template_specialization(
101+
ecsact::codegen_plugin_context& ctx,
102+
const ecsact::rt_entt_codegen::ecsact_entt_details& details,
103+
ecsact_action_id action_id
104+
) -> void {
105+
using ecsact::cpp_codegen_plugin_util::block;
106+
using ecsact::cpp_codegen_plugin_util::method_printer;
107+
using ecsact::rt_entt_codegen::util::decl_cpp_ident;
108+
109+
auto cpp_action_ident = decl_cpp_ident(action_id);
110+
111+
const auto method_name =
112+
"ecsact::entt::check_action_error<" + cpp_action_ident + ">";
113+
114+
ctx.write("template<>\n");
115+
116+
auto printer = //
117+
method_printer{ctx, method_name}
118+
.parameter("::entt::registry&", "registry")
119+
.parameter(cpp_action_ident + " const&", "action")
120+
.return_type("ecsact_execute_systems_error");
121+
122+
ctx.write("auto err = ECSACT_EXEC_SYS_OK;\n");
123+
124+
for_each_entity_field(action_id, [&](auto field_name) {
125+
auto field_var = "ecsact::entt::entity_id{action." + field_name + "}";
126+
block(ctx, "if(!registry.valid(" + field_var + "))", [&] {
127+
ctx.write("return ECSACT_EXEC_SYS_ERR_ACTION_ENTITY_INVALID;\n");
128+
});
129+
});
130+
131+
ctx.write("return err;\n");
132+
}
133+
100134
auto ecsact::rt_entt_codegen::core::print_check_error_template_specializations(
101135
codegen_plugin_context& ctx,
102136
const ecsact_entt_details& details
@@ -116,4 +150,8 @@ auto ecsact::rt_entt_codegen::core::print_check_error_template_specializations(
116150
comp_id
117151
);
118152
}
153+
154+
for(auto action_id : details.all_actions) {
155+
print_check_action_error_template_specialization(ctx, details, action_id);
156+
}
119157
}

rt_entt_codegen/core/core.hh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,17 @@ auto print_check_error_template_specializations( //
3131
const ecsact_entt_details& details
3232
) -> void;
3333

34-
auto print_trigger_component_events_minimal( //
34+
auto print_trigger_ecsact_events_minimal( //
3535
codegen_plugin_context& ctx,
3636
const ecsact_entt_details& details
3737
) -> void;
3838

39-
auto print_trigger_component_events_all( //
39+
auto print_trigger_ecsact_events_all( //
40+
codegen_plugin_context& ctx,
41+
const ecsact_entt_details& details
42+
) -> void;
43+
44+
auto print_cleanup_ecsact_component_events( //
4045
codegen_plugin_context& ctx,
4146
const ecsact_entt_details& details
4247
) -> void;

rt_entt_codegen/core/events.cc

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "ecsact/lang-support/lang-cc.hh"
55
#include "rt_entt_codegen/core/core.hh"
66
#include "rt_entt_codegen/shared/util.hh"
7+
#include "ecsact/cpp_codegen_plugin_util.hh"
78
#include "rt_entt_codegen/shared/comps_with_caps.hh"
89

910
static auto print_trigger_event_fn_call(
@@ -20,7 +21,7 @@ static auto print_trigger_event_fn_call(
2021
);
2122
}
2223

23-
auto ecsact::rt_entt_codegen::core::print_trigger_component_events_minimal( //
24+
auto ecsact::rt_entt_codegen::core::print_trigger_ecsact_events_minimal( //
2425
codegen_plugin_context& ctx,
2526
const ecsact_entt_details& details
2627
) -> void {
@@ -51,9 +52,19 @@ auto ecsact::rt_entt_codegen::core::print_trigger_component_events_minimal( //
5152
auto type_name = cpp_identifier(decl_full_name(comp_id));
5253
print_trigger_event_fn_call(ctx, "remove", type_name);
5354
}
55+
56+
ctx.write(
57+
"ecsact::entt::wrapper::core::_trigger_create_entity_events(registry_id, "
58+
"events_collector);\n"
59+
);
60+
61+
ctx.write(
62+
"ecsact::entt::wrapper::core::_trigger_destroy_entity_events(registry_id, "
63+
"events_collector);\n"
64+
);
5465
}
5566

56-
auto ecsact::rt_entt_codegen::core::print_trigger_component_events_all( //
67+
auto ecsact::rt_entt_codegen::core::print_trigger_ecsact_events_all( //
5768
codegen_plugin_context& ctx,
5869
const ecsact_entt_details& details
5970
) -> void {
@@ -89,4 +100,41 @@ auto ecsact::rt_entt_codegen::core::print_trigger_component_events_all( //
89100
auto type_name = cpp_identifier(decl_full_name(component_id));
90101
print_trigger_event_fn_call(ctx, "remove", type_name);
91102
}
103+
104+
ctx.write(
105+
"ecsact::entt::wrapper::core::_trigger_create_entity_events(registry_id, "
106+
"events_collector);\n"
107+
);
108+
109+
ctx.write(
110+
"ecsact::entt::wrapper::core::_trigger_destroy_entity_events(registry_id, "
111+
"events_collector);\n"
112+
);
113+
}
114+
115+
auto ecsact::rt_entt_codegen::core::print_cleanup_ecsact_component_events( //
116+
codegen_plugin_context& ctx,
117+
const ecsact_entt_details& details
118+
) -> void {
119+
using ecsact::cc_lang_support::cpp_identifier;
120+
using ecsact::cpp_codegen_plugin_util::block;
121+
using ecsact::meta::decl_full_name;
122+
using ecsact::rt_entt_codegen::util::method_printer;
123+
124+
auto printer = //
125+
method_printer{ctx, "cleanup_component_events"}
126+
.parameter("ecsact_registry_id", "registry_id")
127+
.return_type("void");
128+
129+
for(auto component_id : details.all_components) {
130+
auto type_name = cpp_identifier(decl_full_name(component_id));
131+
ctx.write(
132+
"ecsact::entt::wrapper::core::clear_component",
133+
"<::",
134+
type_name,
135+
">(registry_id);\n"
136+
);
137+
}
138+
139+
ctx.write("auto& reg = ecsact::entt::get_registry(registry_id);\n");
92140
}

rt_entt_codegen/core/execute_system_like_template_specializations.cc

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ static auto print_sys_exec_ctx_generate(
409409
"static const auto generate_fns = "
410410
"std::unordered_map<ecsact_component_id, "
411411
"void(*)(ecsact_system_execution_context*, ecsact_component_id, const "
412-
"void*)>",
412+
"void*, ecsact::entt::entity_id)>",
413413
[&] {
414414
for(const auto& component : details.generate_comps) {
415415
for(const auto& [comp_id, requirements] : component) {
@@ -430,13 +430,15 @@ static auto print_sys_exec_ctx_generate(
430430
// NOTE(Kelwan): Multiple generates blocks are allowed in Ecsact systems but
431431
// currently the interpreter won't allow this. More testing required after the
432432
// issue is resolved https://github.com/ecsact-dev/ecsact_interpret/issues/185
433+
ctx.write("auto entity = this->registry->create();\n");
434+
433435
block(ctx, "for(int i = 0; i < component_count; ++i)", [&] {
434436
ctx.write("const auto component_id = component_ids[i];\n");
435437
ctx.write("const void* component_data = components_data[i];\n");
436438

437439
ctx.write(
438440
"generate_fns.at(component_id)(this, component_id, "
439-
"component_data);\n"
441+
"component_data, entity);\n"
440442
);
441443
});
442444
}
@@ -789,39 +791,11 @@ static auto print_other_contexts(
789791
)
790792
);
791793

792-
ctx.write("auto ", view_name, " = ", options.registry_var_name, ".view<");
793-
794-
std::string result;
795-
for(auto&& [comp_id, capability] : assoc_detail.capabilities) {
796-
if(capability != ECSACT_SYS_CAP_EXCLUDE) {
797-
result += "::" + cpp_identifier(decl_full_name(comp_id)) + ", ";
798-
}
799-
}
800-
801-
if(result.ends_with(", ")) {
802-
result = result.substr(0, result.size() - 2);
803-
}
804-
805-
ctx.write(result);
806-
807-
ctx.write(">(");
808-
809-
if(!details.exclude_comps.empty()) {
810-
ctx.write("::entt::exclude<");
811-
for(auto&& [comp_id, capability] : assoc_detail.capabilities) {
812-
if((ECSACT_SYS_CAP_EXCLUDE & capability) == ECSACT_SYS_CAP_EXCLUDE) {
813-
auto full_name = cpp_identifier(decl_full_name(comp_id));
814-
ctx.write("::", full_name, ", ");
815-
}
816-
}
817-
ctx.write(">");
818-
}
819-
820-
ctx.write(");\n");
821-
822794
auto other_details =
823795
ecsact_entt_system_details::from_capabilities(assoc_detail.capabilities);
824796

797+
make_view(ctx, view_name, "registry", other_details);
798+
825799
block(ctx, "struct " + struct_header, [&] {
826800
using namespace std::string_literals;
827801
using ecsact::rt_entt_codegen::util::decl_cpp_ident;
@@ -854,7 +828,7 @@ static auto print_other_contexts(
854828
return other_views;
855829
}
856830

857-
static auto is_trivial_system(ecsact_system_id system_id) -> bool {
831+
static auto is_trivial_system(ecsact_system_like_id system_id) -> bool {
858832
using ecsact::meta::get_field_ids;
859833
using ecsact::meta::system_capabilities;
860834

@@ -956,7 +930,7 @@ static auto print_execute_system_template_specialization(
956930

957931
using ecsact::rt_entt_codegen::util::method_printer;
958932

959-
if(is_trivial_system(system_id)) {
933+
if(is_trivial_system(ecsact_id_cast<ecsact_system_like_id>(system_id))) {
960934
print_trivial_system_like(
961935
ctx,
962936
details,
@@ -1004,6 +978,15 @@ static auto print_execute_actions_template_specialization(
1004978
using ecsact::meta::decl_full_name;
1005979
using ecsact::rt_entt_codegen::util::method_printer;
1006980

981+
if(is_trivial_system(ecsact_id_cast<ecsact_system_like_id>(action_id))) {
982+
print_trivial_system_like(
983+
ctx,
984+
details,
985+
ecsact_id_cast<ecsact_system_like_id>(action_id)
986+
);
987+
return;
988+
}
989+
1007990
auto cpp_system_name = cpp_identifier(decl_full_name(action_id));
1008991

1009992
const auto method_name =

rt_entt_codegen/core/execute_systems.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ auto ecsact::rt_entt_codegen::core::print_execute_systems( //
3737

3838
block(ctx, "if(execution_options_list != nullptr)", [&] {
3939
ctx.write(
40-
"handle_execution_options(registry_id, execution_options_list[i]);\n\n"
40+
"auto err = handle_execution_options(registry_id, "
41+
"execution_options_list[i]);\n\n"
4142
);
43+
block(ctx, "if(err != ECSACT_EXEC_SYS_OK)", [&] {
44+
ctx.write("return err;");
45+
});
4246
});
4347

4448
for(auto sys_like : details.top_execution_order) {
@@ -84,9 +88,8 @@ auto ecsact::rt_entt_codegen::core::print_execute_systems( //
8488
"trigger_component_events_all(registry_id, events_collector);\n\n"
8589
);
8690
});
91+
ctx.write("cleanup_component_events(registry_id);\n");
8792
});
8893

89-
// TODO: clear all event markers
90-
9194
ctx.write("return ECSACT_EXEC_SYS_OK;");
9295
}

0 commit comments

Comments
 (0)