Skip to content

Commit 176deeb

Browse files
committed
Add reactive systems
* init, update and remove as initial features * OnChange to be added later to finish spec
1 parent 3dba899 commit 176deeb

17 files changed

+640
-85
lines changed

ecsact/entt/detail/internal_markers.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ struct system_sorted {
7272
template<typename S>
7373
struct pending_lazy_execution {};
7474

75+
template<typename S>
76+
struct run_system {};
77+
7578
template<typename>
7679
constexpr bool system_markers_unimplemented_by_codegen = false;
7780

ecsact/entt/event_markers.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct component_added {};
1414
* Marker to indicate that a component has been changed during execution
1515
*/
1616
template<typename C>
17-
struct component_changed {};
17+
struct component_updated {};
1818

1919
/**
2020
* Marker to indicate that a component has been removed

ecsact/entt/wrapper/core.hh

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ inline auto update_component_exec_options( //
153153

154154
if(err == ECSACT_UPDATE_OK) {
155155
reg.replace<C>(entity, *static_cast<const C*>(component_data));
156-
reg.template emplace_or_replace<component_changed<C>>(entity);
156+
reg.template emplace_or_replace<component_updated<C>>(entity);
157157
}
158158

159159
return err;
@@ -174,7 +174,7 @@ auto remove_component(
174174
reg.remove<detail::beforechange_storage<C>>(entity);
175175
}
176176
reg.template remove<component_added<C>>(entity);
177-
reg.template remove<component_changed<C>>(entity);
177+
reg.template remove<component_updated<C>>(entity);
178178
reg.template emplace_or_replace<component_removed<C>>(entity);
179179
ecsact::entt::detail::remove_system_markers_if_needed<C>(reg, entity);
180180
}
@@ -200,7 +200,7 @@ auto remove_component_exec_options(
200200

201201
reg.template erase<C>(entity);
202202
reg.template remove<component_added<C>>(entity);
203-
reg.template remove<component_changed<C>>(entity);
203+
reg.template remove<component_updated<C>>(entity);
204204
reg.template emplace_or_replace<component_removed<C>>(entity);
205205

206206
if constexpr(!std::is_empty_v<C>) {
@@ -292,7 +292,7 @@ auto _trigger_update_component_event(
292292
ecsact_registry_id registry_id,
293293
ecsact::entt::detail::execution_events_collector& events_collector
294294
) -> void {
295-
using ecsact::entt::component_changed;
295+
using ecsact::entt::component_updated;
296296
using ecsact::entt::detail::beforechange_storage;
297297

298298
if(!events_collector.has_update_callback()) {
@@ -304,7 +304,7 @@ auto _trigger_update_component_event(
304304
::entt::basic_view changed_view{
305305
reg.template storage<C>(),
306306
reg.template storage<beforechange_storage<C>>(),
307-
reg.template storage<component_changed<C>>(),
307+
reg.template storage<component_updated<C>>(),
308308
};
309309

310310
for(ecsact::entt::entity_id entity : changed_view) {
@@ -379,10 +379,17 @@ inline auto clear_component(ecsact_registry_id registry_id) -> void {
379379
auto& reg = ecsact::entt::get_registry(registry_id);
380380

381381
reg.clear<ecsact::entt::component_added<C>>();
382-
reg.clear<ecsact::entt::component_changed<C>>();
382+
reg.clear<ecsact::entt::component_updated<C>>();
383383
reg.clear<ecsact::entt::component_removed<C>>();
384384
}
385385

386+
template<typename S>
387+
inline auto clear_notify_component(ecsact_registry_id registry_id) -> void {
388+
auto& reg = ecsact::entt::get_registry(registry_id);
389+
390+
reg.clear<ecsact::entt::detail::run_system<S>>();
391+
}
392+
386393
template<typename C>
387394
inline auto prepare_component(ecsact_registry_id registry_id) -> void {
388395
using namespace ecsact::entt;
@@ -395,7 +402,7 @@ inline auto prepare_component(ecsact_registry_id registry_id) -> void {
395402

396403
if constexpr(!std::is_empty_v<C>) {
397404
reg.storage<detail::beforechange_storage<C>>();
398-
reg.template storage<component_changed<C>>();
405+
reg.template storage<component_updated<C>>();
399406
}
400407
}
401408

ecsact/entt/wrapper/dynamic.hh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,16 @@ auto context_remove(
8181
) -> void {
8282
assert(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id);
8383

84-
using ecsact::entt::component_changed;
8584
using ecsact::entt::component_removed;
85+
using ecsact::entt::component_updated;
8686
using ecsact::entt::detail::beforeremove_storage;
8787
using ecsact::entt::detail::pending_remove;
8888

8989
auto entity = context->entity;
9090
auto& registry = *context->registry;
9191

9292
registry.template remove<component_added<C>>(entity);
93-
registry.template remove<component_changed<C>>(entity);
93+
registry.template remove<component_updated<C>>(entity);
9494
registry.template emplace_or_replace<pending_remove<C>>(entity);
9595
registry.template emplace_or_replace<component_removed<C>>(entity);
9696

@@ -110,13 +110,13 @@ auto component_remove_trivial(
110110
::entt::registry& registry,
111111
ecsact::entt::entity_id entity_id
112112
) -> void {
113-
using ecsact::entt::component_changed;
114113
using ecsact::entt::component_removed;
114+
using ecsact::entt::component_updated;
115115
using ecsact::entt::detail::beforeremove_storage;
116116
using ecsact::entt::detail::pending_remove;
117117

118118
registry.template remove<component_added<C>>(entity_id);
119-
registry.template remove<component_changed<C>>(entity_id);
119+
registry.template remove<component_updated<C>>(entity_id);
120120
registry.template emplace_or_replace<pending_remove<C>>(entity_id);
121121
registry.template emplace_or_replace<component_removed<C>>(entity_id);
122122

@@ -150,7 +150,7 @@ auto context_update(
150150
[[maybe_unused]] ecsact_component_like_id component_id,
151151
const void* in_component_data
152152
) -> void {
153-
using ecsact::entt::component_changed;
153+
using ecsact::entt::component_updated;
154154
// TODO(Kelwan): for remove, beforeremove_storage
155155

156156
auto entity = context->entity;
@@ -160,7 +160,7 @@ auto context_update(
160160

161161
auto& current_component = registry.template get<C>(entity);
162162
current_component = in_component;
163-
registry.template emplace_or_replace<component_changed<C>>(entity);
163+
registry.template emplace_or_replace<component_updated<C>>(entity);
164164
}
165165

166166
template<typename C>

rt_entt_codegen/core/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ _CORE_CODEGEN_METHODS = {
2121
"print_sys_exec": [
2222
"//rt_entt_codegen/shared:comps_with_caps",
2323
"//rt_entt_codegen/shared:sorting",
24+
"//rt_entt_codegen/shared:system_util",
2425
"@entt//:entt",
2526
"@ecsact_rt_entt//:lib",
2627
],
@@ -32,6 +33,7 @@ _CORE_CODEGEN_METHODS = {
3233
"system_markers": [
3334
"//rt_entt_codegen/shared:sorting",
3435
],
36+
"system_notify": ["//rt_entt_codegen/shared:system_util"],
3537
}
3638

3739
[cc_library(

rt_entt_codegen/core/core.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ auto print_system_marker_remove_fn(
6666
const ecsact_entt_details& details
6767
) -> void;
6868

69+
auto print_cleanup_system_notifies(
70+
codegen_plugin_context& ctx,
71+
const ecsact_entt_details& details
72+
) -> void;
73+
6974
auto print_entity_match_fn(
7075
codegen_plugin_context& ctx,
7176
const ecsact_entt_details& details

rt_entt_codegen/core/execute_systems.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ auto ecsact::rt_entt_codegen::core::print_execute_systems( //
8989
);
9090
});
9191
ctx.write("cleanup_component_events(registry_id);\n");
92+
ctx.write("cleanup_system_notifies(registry_id);\n");
9293
});
9394

9495
ctx.write("return ECSACT_EXEC_SYS_OK;");

rt_entt_codegen/core/print_sys_exec.cc

Lines changed: 24 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "rt_entt_codegen/shared/util.hh"
1616
#include "rt_entt_codegen/shared/comps_with_caps.hh"
1717
#include "rt_entt_codegen/shared/sorting.hh"
18+
#include "rt_entt_codegen/shared/system_util.hh"
1819

1920
using capability_t =
2021
std::unordered_map<ecsact_component_like_id, ecsact_system_capability>;
@@ -560,6 +561,10 @@ static auto print_ecsact_entt_system_details(
560561
using ecsact::meta::decl_full_name;
561562
using ecsact::meta::get_child_system_ids;
562563
using ecsact::rt_entt_codegen::ecsact_entt_system_details;
564+
using ecsact::rt_entt_codegen::system_util::create_context_struct_name;
565+
using ecsact::rt_entt_codegen::system_util::create_context_var_name;
566+
using ecsact::rt_entt_codegen::system_util::is_notify_system;
567+
using ecsact::rt_entt_codegen::system_util::print_system_notify_views;
563568
using ecsact::rt_entt_codegen::util::method_printer;
564569

565570
constexpr auto is_system_id =
@@ -603,6 +608,18 @@ static auto print_ecsact_entt_system_details(
603608
additional_view_components.push_back(system_sorting_struct_name);
604609
}
605610

611+
if(is_notify_system(options.sys_like_id)) {
612+
additional_view_components.push_back(
613+
std::format("ecsact::entt::detail::run_system<{}>", options.system_name)
614+
);
615+
print_system_notify_views(
616+
ctx,
617+
details,
618+
options.sys_like_id,
619+
options.registry_var_name
620+
);
621+
}
622+
606623
ecsact::rt_entt_codegen::util::make_view(
607624
ctx,
608625
"view",
@@ -771,7 +788,8 @@ static auto print_ecsact_entt_system_details(
771788

772789
if(lazy_iteration_rate > 0) {
773790
ctx.write(
774-
"// If this assertion triggers that's a ecsact_rt_entt codegen failure\n"
791+
"// If this assertion triggers that's a ecsact_rt_entt codegen "
792+
"failure\n"
775793
);
776794
ctx.write("assert(iteration_count_ <= lazy_iteration_rate_);\n");
777795
block(ctx, "if(iteration_count_ < lazy_iteration_rate_)", [&] {
@@ -828,31 +846,6 @@ static auto print_ecsact_entt_system_details(
828846
);
829847
}
830848

831-
static auto get_unique_view_name() -> std::string {
832-
static int counter = 0;
833-
return "view" + std::to_string(counter++);
834-
}
835-
836-
template<typename ComponentLikeID>
837-
static auto create_context_struct_name( //
838-
ComponentLikeID component_like_id
839-
) -> std::string {
840-
using ecsact::cc_lang_support::c_identifier;
841-
auto full_name =
842-
c_identifier(ecsact::meta::decl_full_name(component_like_id));
843-
return full_name + "Struct";
844-
}
845-
846-
template<typename ComponentLikeID>
847-
static auto create_context_var_name( //
848-
ComponentLikeID component_like_id
849-
) -> std::string {
850-
using ecsact::cc_lang_support::c_identifier;
851-
auto full_name =
852-
c_identifier(ecsact::meta::decl_full_name(component_like_id));
853-
return full_name + "_context";
854-
}
855-
856849
template<typename SystemLikeID>
857850
static auto print_other_contexts(
858851
ecsact::codegen_plugin_context& ctx,
@@ -866,6 +859,9 @@ static auto print_other_contexts(
866859
using ecsact::meta::get_child_system_ids;
867860
using ecsact::rt_entt_codegen::ecsact_entt_system_details;
868861
using ecsact::rt_entt_codegen::other_key;
862+
using ecsact::rt_entt_codegen::system_util::create_context_struct_name;
863+
using ecsact::rt_entt_codegen::system_util::create_context_var_name;
864+
using ecsact::rt_entt_codegen::system_util::get_unique_view_name;
869865
using ecsact::rt_entt_codegen::util::method_printer;
870866

871867
std::map<other_key, std::string> other_views;
@@ -928,44 +924,6 @@ static auto print_other_contexts(
928924
return other_views;
929925
}
930926

931-
static auto is_trivial_system(ecsact_system_like_id system_id) -> bool {
932-
using ecsact::meta::get_field_ids;
933-
using ecsact::meta::system_capabilities;
934-
935-
auto sys_capabilities = system_capabilities(system_id);
936-
937-
auto non_trivial_capabilities = std::array{
938-
ECSACT_SYS_CAP_READONLY,
939-
ECSACT_SYS_CAP_READWRITE,
940-
ECSACT_SYS_CAP_WRITEONLY,
941-
ECSACT_SYS_CAP_OPTIONAL_READONLY,
942-
ECSACT_SYS_CAP_OPTIONAL_READWRITE,
943-
ECSACT_SYS_CAP_OPTIONAL_WRITEONLY,
944-
};
945-
946-
bool has_non_tag_adds = false;
947-
bool has_read_write = false;
948-
for(auto&& [comp_id, sys_cap] : sys_capabilities) {
949-
if((ECSACT_SYS_CAP_ADDS & sys_cap) == ECSACT_SYS_CAP_ADDS) {
950-
auto field_count =
951-
ecsact_meta_count_fields(ecsact_id_cast<ecsact_composite_id>(comp_id));
952-
if(field_count > 0) {
953-
has_non_tag_adds = true;
954-
}
955-
}
956-
957-
for(auto non_trivial_cap : non_trivial_capabilities) {
958-
if((non_trivial_cap & sys_cap) == sys_cap) {
959-
has_read_write = true;
960-
}
961-
}
962-
}
963-
if(has_non_tag_adds || has_read_write) {
964-
return false;
965-
}
966-
return true;
967-
}
968-
969927
static auto print_trivial_system_like(
970928
ecsact::codegen_plugin_context& ctx,
971929
const ecsact::rt_entt_codegen::ecsact_entt_system_details& details,
@@ -1027,6 +985,7 @@ static auto print_execute_system_template_specialization(
1027985
using ecsact::cc_lang_support::cpp_identifier;
1028986
using ecsact::cpp_codegen_plugin_util::block;
1029987
using ecsact::meta::decl_full_name;
988+
using ecsact::rt_entt_codegen::system_util::is_trivial_system;
1030989

1031990
using ecsact::rt_entt_codegen::util::method_printer;
1032991

@@ -1076,6 +1035,7 @@ static auto print_execute_actions_template_specialization(
10761035
using ecsact::cc_lang_support::cpp_identifier;
10771036
using ecsact::cpp_codegen_plugin_util::block;
10781037
using ecsact::meta::decl_full_name;
1038+
using ecsact::rt_entt_codegen::system_util::is_trivial_system;
10791039
using ecsact::rt_entt_codegen::util::method_printer;
10801040

10811041
if(is_trivial_system(ecsact_id_cast<ecsact_system_like_id>(action_id))) {

rt_entt_codegen/core/system_markers.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ auto ecsact::rt_entt_codegen::core::print_system_marker_remove_fn(
7575
const ecsact_entt_details& details
7676
) -> void {
7777
for(auto comp : details.all_components) {
78-
auto comp_like_id = ecsact_id_cast<ecsact_component_like_id>(comp);
7978
auto comp_name = ecsact::meta::decl_full_name(comp);
8079
auto comp_cpp_ident = cc_lang_support::cpp_identifier(comp_name);
8180
auto sorting_structs_covered = std::set<ecsact_system_id>{};

rt_entt_codegen/core/system_notify.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "rt_entt_codegen/core/core.hh"
2+
#include "ecsact/lang-support/lang-cc.hh"
3+
#include "ecsact/cpp_codegen_plugin_util.hh"
4+
#include "rt_entt_codegen/shared/system_util.hh"
5+
6+
auto ecsact::rt_entt_codegen::core::print_cleanup_system_notifies(
7+
codegen_plugin_context& ctx,
8+
const ecsact_entt_details& details
9+
) -> void {
10+
using ecsact::cc_lang_support::cpp_identifier;
11+
using ecsact::cpp_codegen_plugin_util::block;
12+
using ecsact::meta::decl_full_name;
13+
using ecsact::rt_entt_codegen::util::method_printer;
14+
15+
auto printer = //
16+
method_printer{ctx, "cleanup_system_notifies"}
17+
.parameter("ecsact_registry_id", "registry_id")
18+
.return_type("void");
19+
20+
for(auto system_id : details.all_systems) {
21+
if(!system_util::is_notify_system(system_id)) {
22+
continue;
23+
}
24+
25+
auto system_name = cpp_identifier(decl_full_name(system_id));
26+
27+
ctx.write(
28+
"ecsact::entt::wrapper::core::clear_notify_component<",
29+
system_name,
30+
">(registry_id);\n"
31+
);
32+
}
33+
}
34+
35+
namespace ecsact::rt_entt_codegen::core::notify {
36+
auto print_system_oninit() -> void {
37+
}
38+
} // namespace ecsact::rt_entt_codegen::core::notify

rt_entt_codegen/rt_entt_codegen.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ void ecsact_codegen_plugin(
216216
core::print_trigger_ecsact_events_all(ctx, details);
217217
core::print_cleanup_ecsact_component_events(ctx, details);
218218
core::print_execution_options(ctx, details);
219+
core::print_cleanup_system_notifies(ctx, details);
219220
core::print_execute_systems(ctx, details);
220221
}
221222
}

0 commit comments

Comments
 (0)