Skip to content

Commit b94675b

Browse files
committed
Adding onchange for systems
1 parent fa98277 commit b94675b

File tree

12 files changed

+285
-5
lines changed

12 files changed

+285
-5
lines changed

ecsact/entt/detail/internal_markers.hh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ struct beforechange_storage {
4242
bool has_update_occurred = false;
4343
};
4444

45+
template<typename C>
46+
struct component_changed {};
47+
4548
template<typename C>
4649
struct pending_add;
4750

@@ -107,4 +110,18 @@ auto remove_system_markers_if_needed( //
107110
)");
108111
}
109112

113+
template<typename C>
114+
auto add_sys_changestorage_if_needed( //
115+
::entt::registry&,
116+
ecsact::entt::entity_id
117+
) -> void {
118+
static_assert(system_markers_unimplemented_by_codegen<C>, R"(
119+
-----------------------------------------------------------------------------
120+
| (!) CODEGEN ERROR |
121+
| `add_sys_changestorage_if_needed<>` template specialization cannot be found |
122+
| This is typically generated by ecsact_rt_entt_codegen. |
123+
-----------------------------------------------------------------------------
124+
)");
125+
}
126+
110127
} // namespace ecsact::entt::detail

ecsact/entt/wrapper/core.hh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "ecsact/entt/error_check.hh"
1111
#include "ecsact/entt/detail/execution_events_collector.hh"
1212

13+
#include <iostream>
14+
1315
namespace ecsact::entt::wrapper::core {
1416

1517
template<typename C>
@@ -408,4 +410,30 @@ inline auto prepare_component(ecsact_registry_id registry_id) -> void {
408410
}
409411
}
410412

413+
template<typename C>
414+
auto has_component_changed(entt::entity_id entity, ::entt::registry& reg)
415+
-> bool {
416+
using detail::beforechange_storage;
417+
using detail::component_changed;
418+
419+
auto current_comp = reg.get<C>(entity);
420+
auto before_comp = reg.get<beforechange_storage<C>>(entity);
421+
422+
if(before_comp.value != current_comp) {
423+
std::cout << "Component has changed!" << std::endl;
424+
return true;
425+
}
426+
std::cout << "Component has not changed!" << std::endl;
427+
return false;
428+
}
429+
430+
template<typename C>
431+
auto update_beforechange_storage(entt::entity_id entity, ::entt::registry& reg)
432+
-> void {
433+
auto comp = reg.get<C>(entity);
434+
auto& beforechange_comp = reg.get<detail::beforechange_storage<C>>(entity);
435+
436+
beforechange_comp.value = comp;
437+
}
438+
411439
} // namespace ecsact::entt::wrapper::core

ecsact/entt/wrapper/dynamic.hh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ auto component_add_trivial(
5454
) -> void {
5555
using ecsact::entt::component_added;
5656
using ecsact::entt::component_removed;
57-
using ecsact::entt::detail::beforechange_storage;
58-
using ecsact::entt::detail::beforeremove_storage;
5957
using ecsact::entt::detail::pending_add;
6058

6159
registry.template emplace_or_replace<pending_add<C>>(entity_id);

rt_entt_codegen/core/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ _CORE_CODEGEN_METHODS = {
3232
],
3333
"system_markers": [
3434
"//rt_entt_codegen/shared:sorting",
35+
"//rt_entt_codegen/shared:system_util",
3536
],
3637
"system_notify": ["//rt_entt_codegen/shared:system_util"],
38+
"update_beforechange": [],
3739
}
3840

3941
[cc_library(

rt_entt_codegen/core/core.hh

Lines changed: 10 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_add_sys_beforestorage_fn(
70+
codegen_plugin_context& ctx,
71+
const ecsact_entt_details& details
72+
) -> void;
73+
6974
auto print_cleanup_system_notifies(
7075
codegen_plugin_context& ctx,
7176
const ecsact_entt_details& details
@@ -76,4 +81,9 @@ auto print_entity_match_fn(
7681
const ecsact_entt_details& details
7782
) -> void;
7883

84+
auto print_update_all_beforechange_storage(
85+
codegen_plugin_context& ctx,
86+
const ecsact_entt_details& details
87+
) -> void;
88+
7989
} // namespace ecsact::rt_entt_codegen::core

rt_entt_codegen/core/execute_systems.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ auto ecsact::rt_entt_codegen::core::print_execute_systems( //
6767
}
6868
}
6969

70+
ctx.write("\nupdate_all_beforechange_storage(registry_id);\n");
71+
7072
ctx.indentation -= 1;
7173
ctx.write("\n}\n\n");
7274

rt_entt_codegen/core/system_markers.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "ecsact/lang-support/lang-cc.hh"
77
#include "ecsact/cpp_codegen_plugin_util.hh"
88
#include "rt_entt_codegen/shared/sorting.hh"
9+
#include "rt_entt_codegen/shared/system_util.hh"
910

1011
using ecsact::cpp_codegen_plugin_util::block;
1112
using ecsact::cpp_codegen_plugin_util::method_printer;
@@ -93,3 +94,45 @@ auto ecsact::rt_entt_codegen::core::print_system_marker_remove_fn(
9394
ctx.write("//TODO\n");
9495
}
9596
}
97+
98+
auto ecsact::rt_entt_codegen::core::print_add_sys_beforestorage_fn(
99+
codegen_plugin_context& ctx,
100+
const ecsact_entt_details& details
101+
) -> void {
102+
using cc_lang_support::cpp_identifier;
103+
using ecsact::meta::decl_full_name;
104+
105+
// for(auto comp_id : details.all_components) {
106+
// auto comp_name = cpp_identifier(decl_full_name(comp_id));
107+
108+
// ctx.write("template<>\n");
109+
// auto printer =
110+
// method_printer{
111+
// ctx,
112+
// std::format(
113+
// "ecsact::entt::detail::add_sys_changestorage_if_needed< {}>",
114+
// comp_name
115+
// )
116+
// }
117+
// .parameter("::entt::registry&", "reg")
118+
// .parameter("ecsact::entt::entity_id", "entity")
119+
// .return_type("void");
120+
121+
// for(auto system_id : details.all_systems) {
122+
// auto count = ecsact::meta::system_notify_settings_count(system_id);
123+
// auto notify_settings = ecsact::meta::system_notify_settings(system_id);
124+
125+
// for(auto const [comp_id_to_compare, notify_setting] : notify_settings) {
126+
// if(comp_id == static_cast<ecsact_component_id>(comp_id_to_compare)) {
127+
// if(notify_setting == ECSACT_SYS_NOTIFY_ONCHANGE) {
128+
// ctx.write(std::format( //
129+
// "reg.emplace<beforechange_storage<{}>>(entity);\n",
130+
// comp_name
131+
// ));
132+
// break;
133+
// }
134+
// }
135+
// }
136+
// }
137+
// }
138+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "core.hh"
2+
3+
#include "ecsact/lang-support/lang-cc.hh"
4+
#include "rt_entt_codegen/shared/util.hh"
5+
#include "ecsact/runtime/common.h"
6+
#include "ecsact/cpp_codegen_plugin_util.hh"
7+
8+
auto ecsact::rt_entt_codegen::core::print_update_all_beforechange_storage(
9+
codegen_plugin_context& ctx,
10+
const ecsact_entt_details& details
11+
) -> void {
12+
using ecsact::cc_lang_support::c_identifier;
13+
using ecsact::cc_lang_support::cpp_identifier;
14+
using ecsact::cpp_codegen_plugin_util::block;
15+
using ecsact::cpp_codegen_plugin_util::method_printer;
16+
using ecsact::meta::decl_full_name;
17+
18+
auto printer = //
19+
method_printer{ctx, "update_all_beforechange_storage"}
20+
.parameter("ecsact_registry_id", "registry_id")
21+
.return_type("void");
22+
23+
ctx.write("auto& reg = ecsact::entt::get_registry(registry_id);\n\n");
24+
25+
for(auto comp_id : details.all_components) {
26+
if(ecsact::meta::get_field_ids(comp_id).empty()) {
27+
continue;
28+
}
29+
30+
auto comp_name = c_identifier(decl_full_name((comp_id)));
31+
auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id));
32+
auto comp_change_name = std::format( //
33+
"ecsact::entt::detail::beforechange_storage<{}>",
34+
cpp_comp_name
35+
);
36+
37+
auto view_name = std::format("{}_view", comp_name);
38+
auto comp_list = std::format("{}, {}", cpp_comp_name, comp_change_name);
39+
40+
ctx.write( //
41+
std::format("auto {} = reg.view<{}>();\n", view_name, comp_list)
42+
);
43+
44+
block(ctx, std::format("for(auto entity: {})", view_name), [&]() {
45+
ctx.write(std::format(
46+
"ecsact::entt::wrapper::core::update_beforechange_storage<{}>(entity, "
47+
"reg);\n",
48+
cpp_comp_name
49+
));
50+
});
51+
}
52+
}

rt_entt_codegen/rt_entt_codegen.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ void ecsact_codegen_plugin(
207207
core::print_entity_match_fn(ctx, details);
208208
core::print_system_marker_add_fn(ctx, details);
209209
core::print_system_marker_remove_fn(ctx, details);
210+
core::print_add_sys_beforestorage_fn(ctx, details);
210211
core::print_entity_sorting_components(ctx, details);
211212
core::print_check_error_template_specializations(ctx, details);
212213
core::print_execute_system_like_template_specializations(ctx, details);
@@ -217,6 +218,7 @@ void ecsact_codegen_plugin(
217218
core::print_cleanup_ecsact_component_events(ctx, details);
218219
core::print_execution_options(ctx, details);
219220
core::print_cleanup_system_notifies(ctx, details);
221+
core::print_update_all_beforechange_storage(ctx, details);
220222
core::print_execute_systems(ctx, details);
221223
}
222224
}

rt_entt_codegen/shared/system_util.cc

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include <array>
44
#include <format>
5+
6+
#include "ecsact/runtime/common.h"
57
#include "rt_entt_codegen/shared/util.hh"
68

79
auto ecsact::rt_entt_codegen::system_util::detail::is_notify_system(
@@ -34,7 +36,6 @@ auto ecsact::rt_entt_codegen::system_util::detail::print_system_notify_views(
3436
using ecsact::cc_lang_support::c_identifier;
3537
using ecsact::cc_lang_support::cpp_identifier;
3638
using ecsact::cpp_codegen_plugin_util::block;
37-
using ecsact::meta::component_name;
3839
using ecsact::meta::decl_full_name;
3940

4041
auto notify_settings = ecsact::meta::system_notify_settings(system_id);
@@ -47,8 +48,7 @@ auto ecsact::rt_entt_codegen::system_util::detail::print_system_notify_views(
4748
break;
4849
}
4950
auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id));
50-
auto comp_name =
51-
c_identifier(component_name(static_cast<ecsact_component_id>(comp_id)));
51+
auto comp_name = c_identifier(decl_full_name((comp_id)));
5252

5353
auto run_system_comp =
5454
std::format("ecsact::entt::detail::run_system<{}>", system_name);
@@ -122,6 +122,45 @@ auto ecsact::rt_entt_codegen::system_util::detail::print_system_notify_views(
122122
if(notify_setting == ECSACT_SYS_NOTIFY_ONCHANGE) {
123123
// TODO: Implement a component to be checked and added in another PR
124124
// Added when component fields have changed during execution
125+
auto component_changed_str =
126+
std::format("ecsact::entt::component_updated<{}>", cpp_comp_name);
127+
128+
auto sys_onchange_str = std::format(
129+
"ecsact::entt::detail::beforechange_storage<{}>",
130+
cpp_comp_name
131+
);
132+
133+
auto sys_beforechanged_str = std::format(
134+
"ecsact::entt::detail::component_changed<{}>",
135+
cpp_comp_name
136+
);
137+
138+
auto view_name = std::format("{}_change_view", comp_name);
139+
140+
ecsact::rt_entt_codegen::util::make_view(
141+
ctx,
142+
view_name,
143+
registry_name,
144+
details,
145+
std::vector{component_changed_str},
146+
std::vector{run_system_comp}
147+
);
148+
149+
block(ctx, std::format("for(auto entity: {})", view_name), [&]() {
150+
block(
151+
ctx,
152+
std::format(
153+
"if(!ecsact::entt::wrapper::core::has_component_changed<{}>(entity,"
154+
" registry))",
155+
cpp_comp_name
156+
),
157+
[&] { ctx.write("continue;\n"); }
158+
);
159+
160+
ctx.write(
161+
std::format("registry.emplace<{}>(entity);\n", run_system_comp)
162+
);
163+
});
125164
}
126165
}
127166
}

0 commit comments

Comments
 (0)