Skip to content

Commit b8c0888

Browse files
committed
adding children systems
1 parent 7593a7b commit b8c0888

File tree

6 files changed

+172
-33
lines changed

6 files changed

+172
-33
lines changed

ecsact/entt/execution.hh

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct actions_map {
6868
}
6969

7070
template<typename Action>
71-
auto as_action_span() -> std::span<const Action*> {
71+
auto as_action_span() const -> std::span<const Action*> {
7272
ecsact_action_id action_id = Action::id;
7373

7474
if(!raw_value.contains(action_id)) {
@@ -94,7 +94,8 @@ struct actions_map {
9494
template<typename System>
9595
auto execute_system( //
9696
::entt::registry& registry,
97-
ecsact_system_execution_context* parent
97+
ecsact_system_execution_context* parent,
98+
const ecsact::entt::actions_map& actions_map
9899
) -> void {
99100
static_assert(detail::unimplemented_by_codegen<System>, R"(
100101
-----------------------------------------------------------------------------
@@ -114,8 +115,9 @@ auto execute_system( //
114115
*/
115116
template<typename Action>
116117
auto execute_actions( //
117-
::entt::registry& registry,
118-
std::span<Action const*> action_range
118+
::entt::registry& registry,
119+
ecsact_system_execution_context* parent,
120+
const ecsact::entt::actions_map& actions_map
119121
) -> void {
120122
static_assert(detail::unimplemented_by_codegen<Action>, R"(
121123
-----------------------------------------------------------------------------

rt_entt_codegen/core/check_error.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ static auto print_check_action_error_template_specialization(
116116
auto printer = //
117117
method_printer{ctx, method_name}
118118
.parameter("::entt::registry&", "registry")
119-
.parameter(cpp_action_ident + " const&", "action")
119+
.parameter("const ecsact::entt::actions_map &", "actions")
120120
.return_type("ecsact_execute_systems_error");
121121

122122
ctx.write("auto err = ECSACT_EXEC_SYS_OK;\n");

rt_entt_codegen/core/execute_systems.cc

Lines changed: 144 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,160 @@
11
#include "core.hh"
22

3+
#include <set>
4+
35
#include "ecsact/lang-support/lang-cc.hh"
46
#include "rt_entt_codegen/shared/util.hh"
57
#include "ecsact/cpp_codegen_plugin_util.hh"
68

9+
#include <iostream>
10+
711
constexpr auto METHOD_BODY_TOP = R"(
812
auto& reg = ecsact::entt::get_registry(registry_id);
913
auto actions = ecsact::entt::actions_map{};
1014
)";
1115

12-
auto determine_parallel_execution(
16+
auto is_capability_safe(ecsact_system_capability capability) -> bool {
17+
// List of components capabilities that can't be executed in parallel
18+
if(capability == ECSACT_SYS_CAP_ADDS ||
19+
capability == ECSACT_SYS_CAP_REMOVES ||
20+
capability == ECSACT_SYS_CAP_READWRITE ||
21+
capability == ECSACT_SYS_CAP_WRITEONLY ||
22+
capability == ECSACT_SYS_CAP_OPTIONAL_WRITEONLY ||
23+
capability == ECSACT_SYS_CAP_OPTIONAL_READWRITE) {
24+
return false;
25+
}
26+
return true;
27+
}
28+
29+
auto manage_component_safety(
30+
const ecsact_component_id unsafe_comp_id,
31+
std::set<ecsact_component_id>& unsafe_comps
32+
) -> void {
33+
if(!unsafe_comps.contains(unsafe_comp_id)) {
34+
unsafe_comps.insert(unsafe_comp_id);
35+
return;
36+
}
37+
}
38+
39+
auto loop_iterator(
40+
std::vector<ecsact_system_like_id>& system_list,
41+
const std::vector<ecsact_system_like_id>::iterator begin,
42+
std::vector<std::vector<ecsact_system_like_id>>& parallel_system_cluster
43+
) -> void {
44+
std::cout << "loop iterator run" << std::endl;
45+
std::vector<ecsact_system_like_id> parallel_system_list;
46+
auto unsafe_comps = std::set<ecsact_component_like_id>{};
47+
48+
for(auto iterator = begin; iterator != system_list.end(); iterator++) {
49+
auto sys_like_id = *iterator;
50+
auto capabilities = ecsact::meta::system_capabilities(sys_like_id);
51+
52+
for(const auto [comp_id, capability] : capabilities) {
53+
if(!is_capability_safe(capability)) {
54+
if(!unsafe_comps.contains(comp_id)) {
55+
std::cout << "Unsafe comp inserted" << std::endl;
56+
unsafe_comps.insert(comp_id);
57+
} else {
58+
// We already have it. Uh-oh!
59+
std::cout << "Conflict found" << std::endl;
60+
parallel_system_cluster.push_back(parallel_system_list);
61+
parallel_system_list.clear();
62+
unsafe_comps.clear();
63+
loop_iterator(system_list, iterator, parallel_system_cluster);
64+
}
65+
}
66+
}
67+
68+
// Okay it's all good, check has passed. Now let's check the child systems
69+
auto child_systems = ecsact::meta::get_child_system_ids(sys_like_id);
70+
71+
for(const auto child_sys_id : child_systems) {
72+
auto child_capabilities = ecsact::meta::system_capabilities(child_sys_id);
73+
for(const auto [child_comp_id, child_capability] : child_capabilities) {
74+
if(!is_capability_safe(child_capability)) {
75+
if(!unsafe_comps.contains(child_comp_id)) {
76+
std::cout << "Unsafe comp inserted in child" << std::endl;
77+
unsafe_comps.insert(child_comp_id);
78+
} else {
79+
// We already have it. Uh-oh!
80+
std::cout << "Conflict found in child" << std::endl;
81+
parallel_system_cluster.push_back(parallel_system_list);
82+
parallel_system_list.clear();
83+
unsafe_comps.clear();
84+
loop_iterator(system_list, iterator, parallel_system_cluster);
85+
}
86+
}
87+
}
88+
}
89+
90+
std::cout << "System added to list" << std::endl;
91+
parallel_system_list.push_back(sys_like_id);
92+
}
93+
parallel_system_cluster.push_back(parallel_system_list);
94+
}
95+
96+
auto print_parallel_execution(
1397
ecsact::codegen_plugin_context& ctx,
1498
const ecsact::rt_entt_codegen::ecsact_entt_details& details
1599
) -> void {
16-
for(auto sys_like : details.top_execution_order) {
100+
using ecsact::cpp_codegen_plugin_util::block;
101+
102+
auto parallel_system_cluster =
103+
std::vector<std::vector<ecsact_system_like_id>>{};
104+
105+
auto top_systems_copy = std::vector<ecsact_system_like_id>{
106+
details.top_execution_order.begin(),
107+
details.top_execution_order.end()
108+
};
109+
110+
loop_iterator(
111+
top_systems_copy,
112+
top_systems_copy.begin(),
113+
parallel_system_cluster
114+
);
115+
116+
std::cout << "post loop iterator" << std::endl;
117+
118+
for(const auto& systems_to_parallel : parallel_system_cluster) {
119+
std::cout << "Parallel system cluster" << std::endl;
120+
using ecsact::cc_lang_support::cpp_identifier;
121+
block(ctx, "", [&] {
122+
block(ctx, "auto system_bank = std::array\n", [&] {
123+
for(const auto system_like_id : systems_to_parallel) {
124+
std::cout << "Systems to parallel" << std::endl;
125+
auto cpp_decl_name =
126+
cpp_identifier(ecsact::meta::decl_full_name(system_like_id));
127+
128+
if(details.is_action(system_like_id)) {
129+
ctx.write(
130+
"std::pair{&ecsact::entt::execute_actions<",
131+
cpp_decl_name,
132+
">, actions},\n"
133+
);
134+
} else if(details.is_system(system_like_id)) {
135+
ctx.write(
136+
"std::pair{&ecsact::entt::execute_system<",
137+
cpp_decl_name,
138+
">, actions},\n"
139+
);
140+
} else {
141+
ctx.write("// ??? unhandled ??? ", cpp_decl_name, "\n");
142+
}
143+
}
144+
});
145+
ctx.write(";\n");
146+
147+
ctx.write(
148+
"std::for_each(std::execution::par_unseq\n, system_bank.begin()\n, "
149+
"system_bank.end()\n, "
150+
);
151+
block(ctx, "[&](auto pair)", [&]() {
152+
ctx.write("auto fn_ptr = pair.first;\n");
153+
ctx.write("auto actions_map = pair.second;\n");
154+
ctx.write("fn_ptr(reg, actions_map);");
155+
});
156+
ctx.write(");\n");
157+
});
17158
}
18159
}
19160

@@ -53,27 +194,7 @@ auto ecsact::rt_entt_codegen::core::print_execute_systems( //
53194
});
54195
});
55196

56-
for(auto sys_like : details.top_execution_order) {
57-
auto cpp_decl_name = cpp_identifier(ecsact::meta::decl_full_name(sys_like));
58-
59-
if(details.is_action(sys_like)) {
60-
ctx.write(
61-
"ecsact::entt::execute_actions<",
62-
cpp_decl_name,
63-
">(reg, actions.as_action_span<",
64-
cpp_decl_name,
65-
">());\n"
66-
);
67-
} else if(details.is_system(sys_like)) {
68-
ctx.write(
69-
"ecsact::entt::execute_system<",
70-
cpp_decl_name,
71-
">(reg, nullptr);\n"
72-
);
73-
} else {
74-
ctx.write("// ??? unhandled ??? ", cpp_decl_name, "\n");
75-
}
76-
}
197+
print_parallel_execution(ctx, details);
77198

78199
ctx.write("\nupdate_all_beforechange_storage(registry_id);\n");
79200
ctx.write("cleanup_system_notifies(registry_id);\n");

rt_entt_codegen/core/print_sys_exec.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ static auto print_ecsact_entt_system_details(
768768
ctx.write(
769769
"ecsact::entt::execute_system<::" + child_system_name + ">(",
770770
options.registry_var_name,
771-
", &context);\n"
771+
", &context, {});\n"
772772
);
773773
}
774774
ctx.write("\n");
@@ -1075,6 +1075,7 @@ static auto print_execute_system_template_specialization(
10751075
method_printer{ctx, "ecsact::entt::execute_system<::" + system_name + ">"}
10761076
.parameter("::entt::registry&", "registry")
10771077
.parameter("ecsact_system_execution_context*", "parent_context")
1078+
.parameter("const ecsact::entt::actions_map&", "actions_map")
10781079
.return_type("void");
10791080

10801081
ctx.write(
@@ -1127,7 +1128,8 @@ static auto print_execute_actions_template_specialization(
11271128
auto printer = //
11281129
method_printer{ctx, method_name}
11291130
.parameter("::entt::registry&", "registry")
1130-
.parameter("std::span<::" + cpp_system_name + " const*>", "actions")
1131+
.parameter("ecsact_system_execution_context", "*parent_context")
1132+
.parameter("const ecsact::entt::actions_map&", "actions_map")
11311133
.return_type("void");
11321134

11331135
ctx.write(
@@ -1138,6 +1140,12 @@ static auto print_execute_actions_template_specialization(
11381140

11391141
block(ctx, "if(system_impl == nullptr)", [&] { ctx.write("return;"); });
11401142

1143+
ctx.write(
1144+
"auto actions = actions_map.as_action_span<",
1145+
cpp_system_name,
1146+
">();\n"
1147+
);
1148+
11411149
block(ctx, "for(auto action : actions)", [&] {
11421150
print_ecsact_entt_system_details<ecsact_action_id>(
11431151
ctx,

rt_entt_codegen/rt_entt_codegen.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ void ecsact_codegen_plugin(
5454
inc_header(ctx, "ecsact/entt/wrapper/core.hh");
5555
inc_header(ctx, "ecsact/entt/wrapper/dynamic.hh");
5656
inc_header(ctx, "ecsact/entt/error_check.hh");
57+
ctx.write("#include <execution>\n");
58+
5759
ctx.write("\n");
5860
inc_package_header(ctx, package_id);
5961
for(auto dep : ecsact::meta::get_dependencies(package_id)) {

test/parallel/parallel_test.ecsact

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ component ParallelA {
66
component ParallelB {
77
i32 val;
88
}
9+
component ParallelC {
10+
i32 val;
11+
}
912

1013
system ReadWriteParallelA {
1114
readwrite ParallelA;
1215
}
1316

14-
system ReadParallelA {
17+
action ActionParallelA {
1518
readonly ParallelA;
1619
}
1720

18-
system ReadParallelAB {
19-
readonly ParallelA;
21+
system ReadParallelA {
22+
readonly ParallelB;
23+
system ReadParallelAChildSystem {
24+
readwrite ParallelA;
25+
}
2026
}
2127

2228
system ReadWriteParallelB {

0 commit comments

Comments
 (0)