Skip to content

Commit 59390ea

Browse files
authored
feat(performance): context fn indirect invocation instead of exhaust checks (#46)
1 parent be924bf commit 59390ea

File tree

5 files changed

+633
-160
lines changed

5 files changed

+633
-160
lines changed

WORKSPACE.bazel

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ http_archive(
1111

1212
http_archive(
1313
name = "rules_ecsact",
14-
sha256 = "8eaaf1f05eccbfcf4a0123c951436519672190a7a908fa847c24adf0778041f6",
15-
strip_prefix = "rules_ecsact-0.2.2",
16-
url = "https://github.com/ecsact-dev/rules_ecsact/archive/refs/tags/0.2.2.tar.gz",
14+
sha256 = "c170cebbee0af5bf9a26e9d038aa32e3c164aa8cc7f2d4f3996e19bf3510dd0f",
15+
strip_prefix = "rules_ecsact-0.2.3",
16+
url = "https://github.com/ecsact-dev/rules_ecsact/archive/refs/tags/0.2.3.tar.gz",
1717
)
1818

1919
http_archive(

ecsact/entt/detail/meta_util.hh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,27 @@ struct mp_components_t<HeadPackage, Package...> {
2828
typename mp_components_t<Package...>::type>>>;
2929
};
3030

31+
template<typename... Package>
32+
struct mp_transients_t;
33+
34+
template<>
35+
struct mp_transients_t<> {
36+
using type = ::ecsact::mp_list<>;
37+
};
38+
39+
template<typename Package>
40+
struct mp_transients_t<Package> {
41+
using type = typename Package::transients;
42+
};
43+
44+
template<typename HeadPackage, typename... Package>
45+
struct mp_transients_t<HeadPackage, Package...> {
46+
using type =
47+
boost::mp11::mp_unique<boost::mp11::mp_flatten<boost::mp11::mp_push_back<
48+
typename mp_transients_t<HeadPackage>::type,
49+
typename mp_transients_t<Package...>::type>>>;
50+
};
51+
3152
template<typename... Package>
3253
struct mp_actions_t;
3354

@@ -91,6 +112,26 @@ using mp_package_dependencies_recursive =
91112
boost::mp11::mp_identity_t,
92113
mp_package_dependencies_from_list>>>;
93114

115+
template<typename Package>
116+
using mp_all_components_t = typename boost::mp11::mp_append<
117+
mp_components_t<Package>,
118+
mp_package_dependencies_recursive<typename Package::dependencies>>::type;
119+
120+
template<typename Package>
121+
using mp_all_transients_t = typename boost::mp11::mp_append<
122+
mp_transients_t<Package>,
123+
mp_package_dependencies_recursive<typename Package::dependencies>>::type;
124+
125+
template<typename Package>
126+
using mp_all_systems_t = typename boost::mp11::mp_append<
127+
mp_systems_t<Package>,
128+
mp_package_dependencies_recursive<typename Package::dependencies>>::type;
129+
130+
template<typename Package>
131+
using mp_all_actions_t = typename boost::mp11::mp_append<
132+
mp_actions_t<Package>,
133+
mp_package_dependencies_recursive<typename Package::dependencies>>::type;
134+
94135
template<typename Package, typename Callback>
95136
void mp_for_each_available_component(Callback&& cb) {
96137
using boost::mp11::mp_append;

ecsact/entt/detail/system_execution_context.hh

Lines changed: 116 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ struct ecsact_system_execution_context {
2525
// templated type. See `system_execution_context<Package, System>`
2626
ecsact_entt_rt::system_execution_context_base* impl;
2727

28-
// This is set by the system_execution_context::other method
29-
signed association_index = -1;
28+
// This is set by the system_execution_context::other method. `0` means
29+
// no association.
30+
unsigned association_index = 0;
3031
};
3132

3233
namespace ecsact_entt_rt {
@@ -38,6 +39,28 @@ struct system_execution_context_base {
3839
::entt::entity entity;
3940
const cptr_t parent;
4041
const void* action;
42+
43+
system_execution_context_base(
44+
::entt::entity entity,
45+
cptr_t parent,
46+
const void* action
47+
)
48+
: entity(entity), parent(parent), action(action) {
49+
}
50+
51+
virtual ~system_execution_context_base() {
52+
}
53+
54+
virtual auto other(ecsact_entity_id other_entity)
55+
-> ecsact_system_execution_context* = 0;
56+
57+
virtual auto get_ecsact_entity_id() -> ecsact_entity_id const = 0;
58+
59+
virtual auto generate(
60+
int component_count,
61+
ecsact_component_id* component_ids,
62+
const void** components_data
63+
) -> void = 0;
4164
};
4265

4366
namespace detail {}
@@ -57,6 +80,17 @@ struct system_execution_context : system_execution_context_base {
5780
using association_views_type =
5881
ecsact::entt::association_views_type<caps_info>;
5982

83+
using readonly_components = typename caps_info::readonly_components;
84+
using readwrite_components = typename caps_info::readwrite_components;
85+
using adds_components = typename caps_info::adds_components;
86+
using removes_components = typename caps_info::removes_components;
87+
88+
using gettable_components = boost::mp11::mp_assign<
89+
::ecsact::mp_list<>,
90+
boost::mp11::mp_unique<boost::mp11::mp_flatten<
91+
boost::mp11::mp_push_back<readonly_components, readwrite_components>,
92+
::ecsact::mp_list<>>>>;
93+
6094
static_assert(
6195
boost::mp11::mp_size<typename caps_info::associations>::value ==
6296
std::tuple_size_v<association_views_type>,
@@ -85,7 +119,7 @@ struct system_execution_context : system_execution_context_base {
85119
const cptr_t parent,
86120
const void* action
87121
)
88-
: system_execution_context_base{entity, parent, action}
122+
: system_execution_context_base(entity, parent, action)
89123
, info(info)
90124
, view(view)
91125
, assoc_views(assoc_views) {
@@ -141,15 +175,15 @@ struct system_execution_context : system_execution_context_base {
141175
}
142176
}
143177

144-
void add(ecsact_component_like_id component_id, const void* component_data) {
145-
using ecsact::entt::detail::mp_for_each_available_component;
146-
147-
mp_for_each_available_component<package>([&]<typename C>(const C&) {
148-
if(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id) {
149-
add<C>(*static_cast<const C*>(component_data));
150-
}
151-
});
152-
}
178+
// void add(ecsact_component_like_id component_id, const void* component_data)
179+
// { using ecsact::entt::detail::mp_for_each_available_component;
180+
//
181+
// mp_for_each_available_component<package>([&]<typename C>(const C&) {
182+
// if(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id) {
183+
// add<C>(*static_cast<const C*>(component_data));
184+
// }
185+
// });
186+
// }
153187

154188
template<typename C>
155189
void remove() {
@@ -197,15 +231,15 @@ struct system_execution_context : system_execution_context_base {
197231
info.registry.template emplace_or_replace<pending_remove<C>>(entity);
198232
}
199233

200-
void remove(ecsact_component_like_id component_id) {
201-
using ecsact::entt::detail::mp_for_each_available_component;
202-
203-
mp_for_each_available_component<package>([&]<typename C>(const C&) {
204-
if(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id) {
205-
remove<C>();
206-
}
207-
});
208-
}
234+
// void remove(ecsact_component_like_id component_id) {
235+
// using ecsact::entt::detail::mp_for_each_available_component;
236+
//
237+
// mp_for_each_available_component<package>([&]<typename C>(const C&) {
238+
// if(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id) {
239+
// remove<C>();
240+
// }
241+
// });
242+
// }
209243

210244
template<typename C>
211245
requires(!std::is_empty_v<C>)
@@ -221,46 +255,44 @@ struct system_execution_context : system_execution_context_base {
221255
return view.template get<C>(entity);
222256
}
223257

224-
void get(ecsact_component_like_id component_id, void* out_component_data) {
225-
using boost::mp11::mp_assign;
226-
using boost::mp11::mp_flatten;
227-
using boost::mp11::mp_for_each;
228-
using boost::mp11::mp_push_back;
229-
using boost::mp11::mp_unique;
230-
using ecsact::entt_mp11_util::mp_map_find_value_or;
231-
232-
using readonly_components = typename caps_info::readonly_components;
233-
using readwrite_components = typename caps_info::readwrite_components;
234-
using gettable_components = mp_assign<
235-
::ecsact::mp_list<>,
236-
mp_unique<mp_flatten<
237-
mp_push_back<readonly_components, readwrite_components>,
238-
::ecsact::mp_list<>>>>;
239-
240-
#ifndef NDEBUG
241-
[[maybe_unused]] bool found_gettable_component = false;
242-
[[maybe_unused]] const char* get_component_name = "";
243-
[[maybe_unused]] auto gettable_components_type_name =
244-
typeid(gettable_components).name();
245-
#endif // NDEBUG
246-
247-
mp_for_each<gettable_components>([&]<typename C>(C) {
248-
if(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id) {
249-
if constexpr(!std::is_empty_v<C>) {
250-
C& out_component = *reinterpret_cast<C*>(out_component_data);
251-
out_component = get<C>();
252-
#ifndef NDEBUG
253-
get_component_name = typeid(C).name();
254-
found_gettable_component = true;
255-
#endif // NDEBUG
256-
}
257-
}
258-
});
259-
260-
#ifndef NDEBUG
261-
assert(found_gettable_component);
262-
#endif // NDEBUG
263-
}
258+
// void get(ecsact_component_like_id component_id, void* out_component_data)
259+
// { using boost::mp11::mp_assign; using boost::mp11::mp_flatten;
260+
// using boost::mp11::mp_for_each; using boost::mp11::mp_push_back; using
261+
// boost::mp11::mp_unique; using
262+
// ecsact::entt_mp11_util::mp_map_find_value_or;
263+
//
264+
// using readonly_components = typename caps_info::readonly_components;
265+
// using readwrite_components = typename caps_info::readwrite_components;
266+
// using gettable_components = mp_assign<
267+
// ::ecsact::mp_list<>,
268+
// mp_unique<mp_flatten<
269+
// mp_push_back<readonly_components, readwrite_components>,
270+
// ::ecsact::mp_list<>>>>;
271+
//
272+
// #ifndef NDEBUG
273+
// [[maybe_unused]] bool found_gettable_component = false;
274+
// [[maybe_unused]] const char* get_component_name = "";
275+
// [[maybe_unused]] auto gettable_components_type_name =
276+
// typeid(gettable_components).name();
277+
// #endif // NDEBUG
278+
//
279+
// mp_for_each<gettable_components>([&]<typename C>(C) {
280+
// if(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id) {
281+
// if constexpr(!std::is_empty_v<C>) {
282+
// C& out_component = *reinterpret_cast<C*>(out_component_data);
283+
// out_component = get<C>();
284+
// #ifndef NDEBUG
285+
// get_component_name = typeid(C).name();
286+
// found_gettable_component = true;
287+
// #endif // NDEBUG
288+
// }
289+
// }
290+
// });
291+
//
292+
// #ifndef NDEBUG
293+
// assert(found_gettable_component);
294+
// #endif // NDEBUG
295+
// }
264296

265297
template<typename C>
266298
requires(!std::is_empty_v<C>)
@@ -294,23 +326,23 @@ struct system_execution_context : system_execution_context_base {
294326
comp = c;
295327
}
296328

297-
void update(
298-
ecsact_component_like_id component_id,
299-
const void* component_data
300-
) {
301-
using boost::mp11::mp_for_each;
302-
using boost::mp11::mp_list;
303-
using boost::mp11::mp_map_find;
304-
using ecsact::entt_mp11_util::mp_map_find_value_or;
305-
306-
using readwrite_components = typename caps_info::readwrite_components;
307-
308-
mp_for_each<readwrite_components>([&]<typename C>(C) {
309-
if(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id) {
310-
update<C>(*reinterpret_cast<const C*>(component_data));
311-
}
312-
});
313-
}
329+
// void update(
330+
// ecsact_component_like_id component_id,
331+
// const void* component_data
332+
// ) {
333+
// using boost::mp11::mp_for_each;
334+
// using boost::mp11::mp_list;
335+
// using boost::mp11::mp_map_find;
336+
// using ecsact::entt_mp11_util::mp_map_find_value_or;
337+
//
338+
// using readwrite_components = typename caps_info::readwrite_components;
339+
//
340+
// mp_for_each<readwrite_components>([&]<typename C>(C) {
341+
// if(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id) {
342+
// update<C>(*reinterpret_cast<const C*>(component_data));
343+
// }
344+
// });
345+
// }
314346

315347
template<typename ComponentT>
316348
bool has() {
@@ -334,11 +366,11 @@ struct system_execution_context : system_execution_context_base {
334366
return result;
335367
}
336368

337-
void generate(
369+
auto generate(
338370
int component_count,
339371
ecsact_component_id* component_ids,
340372
const void** components_data
341-
) {
373+
) -> void override {
342374
using ecsact::entt::component_added;
343375
using ecsact::entt::detail::created_entity;
344376
using ecsact::entt::detail::mp_for_each_available_component;
@@ -369,7 +401,8 @@ struct system_execution_context : system_execution_context_base {
369401
}
370402
}
371403

372-
ecsact_system_execution_context* other(ecsact_entity_id other_entity) {
404+
auto other(ecsact_entity_id other_entity)
405+
-> ecsact_system_execution_context* override {
373406
using boost::mp11::mp_first;
374407
using boost::mp11::mp_for_each;
375408
using boost::mp11::mp_second;
@@ -422,7 +455,7 @@ struct system_execution_context : system_execution_context_base {
422455
);
423456

424457
other_context->_c_ctx.association_index =
425-
static_cast<signed>(assoc_index);
458+
static_cast<unsigned>(assoc_index + 1);
426459
}
427460

428461
return_context = &other_context->_c_ctx;
@@ -436,7 +469,7 @@ struct system_execution_context : system_execution_context_base {
436469
return return_context;
437470
}
438471

439-
ecsact_entity_id get_ecsact_entity_id() const {
472+
auto get_ecsact_entity_id() -> ecsact_entity_id const override {
440473
return info.get_ecsact_entity_id(entity);
441474
}
442475
};

0 commit comments

Comments
 (0)