Skip to content

Commit 10c39a7

Browse files
authored
feat: parallel entities (#129)
1 parent d324920 commit 10c39a7

32 files changed

+573
-183
lines changed

build_recipe.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ sources:
179179
outdir: include/ecsact/entt/detail
180180
- path: ./ecsact/entt/detail/globals.hh
181181
outdir: include/ecsact/entt/detail
182+
- path: ./ecsact/entt/detail/registry.hh
183+
outdir: include/ecsact/entt/detail
182184
- path: ./ecsact/entt/detail/internal_markers.hh
183185
outdir: include/ecsact/entt/detail
184186
- path: ./ecsact/entt/detail/system_execution_context.hh

ecsact/entt/detail/apply_pending.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace ecsact::entt::detail {
88

99
template<typename C>
10-
auto apply_pending_add(::entt::registry& registry) -> void {
10+
auto apply_pending_add(ecsact::entt::registry_t& registry) -> void {
1111
if constexpr(std::is_empty_v<C>) {
1212
registry.view<pending_add<C>>().each([&](auto entity) {
1313
registry.emplace<C>(entity);
@@ -26,7 +26,7 @@ auto apply_pending_add(::entt::registry& registry) -> void {
2626
}
2727

2828
template<typename C>
29-
auto apply_pending_remove(::entt::registry& registry) -> void {
29+
auto apply_pending_remove(ecsact::entt::registry_t& registry) -> void {
3030
registry.view<pending_remove<C>>().each([&](auto entity) {
3131
if constexpr(!std::is_empty_v<C>) {
3232
registry.erase<exec_beforechange_storage<C>>(entity);

ecsact/entt/detail/globals.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "ecsact/runtime/core.h"
88
#include "ecsact/runtime/dynamic.h"
99
#include "ecsact/entt/detail/system_execution_context.hh"
10+
#include "ecsact/entt/detail/registry.hh"
1011

1112
/**
1213
* A small set of globals expected to be available the ecsact_rt_entt_codegen
@@ -19,7 +20,7 @@ namespace ecsact::entt::detail::globals {
1920
*/
2021
extern std::unordered_map< //
2122
ecsact_registry_id,
22-
::entt::registry>
23+
ecsact::entt::registry_t>
2324
registries;
2425

2526
/**

ecsact/entt/detail/internal_markers.hh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ constexpr bool system_markers_unimplemented_by_codegen = false;
8787

8888
template<typename C>
8989
auto add_system_markers_if_needed( //
90-
::entt::registry&,
90+
ecsact::entt::registry_t&,
9191
ecsact::entt::entity_id
9292
) -> void {
9393
static_assert(system_markers_unimplemented_by_codegen<C>, R"(
@@ -101,7 +101,7 @@ auto add_system_markers_if_needed( //
101101

102102
template<typename C>
103103
auto remove_system_markers_if_needed( //
104-
::entt::registry&,
104+
ecsact::entt::registry_t&,
105105
ecsact::entt::entity_id
106106
) -> void {
107107
static_assert(system_markers_unimplemented_by_codegen<C>, R"(
@@ -115,7 +115,7 @@ auto remove_system_markers_if_needed( //
115115

116116
template<typename C>
117117
auto add_exec_itr_beforechange_if_needed( //
118-
::entt::registry&,
118+
ecsact::entt::registry_t&,
119119
ecsact::entt::entity_id
120120
) -> void {
121121
static_assert(system_markers_unimplemented_by_codegen<C>, R"(

ecsact/entt/detail/registry.hh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
3+
#include "entt/entity/registry.hpp"
4+
5+
namespace ecsact::entt {
6+
7+
using registry_t = ::entt::basic_registry<::entt::entity>;
8+
}

ecsact/entt/detail/system_execution_context.hh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "ecsact/runtime/common.h"
1111
#include "ecsact/entt/event_markers.hh"
1212
#include "ecsact/entt/entity.hh"
13+
#include "ecsact/entt/detail/registry.hh"
1314

1415
namespace ecsact::entt {
1516
/**
@@ -30,10 +31,10 @@ constexpr auto underlying_assoc_index(assoc_index n) -> unsigned {
3031
} // namespace ecsact::entt
3132

3233
struct ecsact_system_execution_context {
33-
ecsact_system_like_id id;
34-
ecsact::entt::entity_id entity;
35-
::entt::registry* registry = nullptr;
36-
const void* action_data = nullptr;
34+
ecsact_system_like_id id;
35+
ecsact::entt::entity_id entity;
36+
ecsact::entt::registry_t* registry = nullptr;
37+
const void* action_data = nullptr;
3738

3839
// pass in the context to this class that's a pointer
3940
// context(ptr) = parent_ctx(ptr)

ecsact/entt/error_check.hh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace ecsact::entt {
1919

2020
template<typename C>
2121
auto check_add_component_error( //
22-
::entt::registry&,
22+
ecsact::entt::registry_t&,
2323
::ecsact::entt::entity_id,
2424
const C&
2525
) -> ecsact_add_error {
@@ -34,7 +34,7 @@ auto check_add_component_error( //
3434

3535
template<typename C>
3636
auto check_update_component_error( //
37-
::entt::registry&,
37+
ecsact::entt::registry_t&,
3838
::ecsact::entt::entity_id,
3939
const C&
4040
) -> ecsact_update_error {
@@ -49,7 +49,7 @@ auto check_update_component_error( //
4949

5050
template<typename A>
5151
auto check_action_error( //
52-
::entt::registry&,
52+
ecsact::entt::registry_t&,
5353
const A&
5454
) -> ecsact_execute_systems_error {
5555
static_assert(detail::error_check_unimplemented_by_codegen<A>, R"(

ecsact/entt/event_markers.hh

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ namespace ecsact::entt {
1010
template<typename C>
1111
struct component_added {};
1212

13-
/**
14-
* Marker to indicate that a component has been changed during execution
15-
*/
16-
template<typename C>
17-
struct component_updated {};
18-
1913
/**
2014
* Marker to indicate that a component has been removed
2115
*/

ecsact/entt/execution.hh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct actions_map {
9393
*/
9494
template<typename System>
9595
auto execute_system( //
96-
::entt::registry& registry,
96+
ecsact::entt::registry_t& registry,
9797
ecsact_system_execution_context* parent,
9898
const ecsact::entt::actions_map& actions_map
9999
) -> void {
@@ -115,7 +115,7 @@ auto execute_system( //
115115
*/
116116
template<typename Action>
117117
auto execute_actions( //
118-
::entt::registry& registry,
118+
ecsact::entt::registry_t& registry,
119119
ecsact_system_execution_context* parent,
120120
const ecsact::entt::actions_map& actions_map
121121
) -> void {
@@ -129,7 +129,7 @@ auto execute_actions( //
129129
}
130130

131131
using execute_fn_t = void (*)(
132-
::entt::registry& registry,
132+
ecsact::entt::registry_t& registry,
133133
ecsact_system_execution_context* parent,
134134
const ecsact::entt::actions_map& actions_map
135135
);
@@ -140,7 +140,7 @@ using execute_fn_t = void (*)(
140140
* `ecsact_rt_entt_codegen`.
141141
*/
142142
template<typename SystemLike>
143-
auto prepare_system_like(::entt::registry&) -> void {
143+
auto prepare_system_like(ecsact::entt::registry_t&) -> void {
144144
static_assert(detail::unimplemented_by_codegen<SystemLike>, R"(
145145
-----------------------------------------------------------------------------
146146
| (!) CODEGEN ERROR |
@@ -155,7 +155,8 @@ auto prepare_system_like(::entt::registry&) -> void {
155155
* entity.
156156
*/
157157
template<typename SystemLike>
158-
auto entity_matches_system(::entt::registry&, ecsact::entt::entity_id) -> bool {
158+
auto entity_matches_system(ecsact::entt::registry_t&, ecsact::entt::entity_id)
159+
-> bool {
159160
static_assert(detail::unimplemented_by_codegen<SystemLike>, R"(
160161
-----------------------------------------------------------------------------
161162
| (!) CODEGEN ERROR |

ecsact/entt/registry_util.hh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
#include <cassert>
44
#include "entt/entity/registry.hpp"
55
#include "ecsact/entt/detail/globals.hh"
6+
#include "ecsact/entt/detail/registry.hh"
67

78
namespace ecsact::entt {
89

910
inline auto get_registry( //
1011
ecsact_registry_id id
11-
) -> ::entt::registry& {
12+
) -> ecsact::entt::registry_t& {
1213
using ecsact::entt::detail::globals::registries;
1314

1415
// Check to make sure we're not trying to get a registry that doesn't exist
@@ -18,7 +19,7 @@ inline auto get_registry( //
1819
}
1920

2021
inline auto create_registry()
21-
-> std::tuple<ecsact_registry_id, ::entt::registry&> {
22+
-> std::tuple<ecsact_registry_id, ecsact::entt::registry_t&> {
2223
using ecsact::entt::detail::globals::last_registry_id;
2324
using ecsact::entt::detail::globals::registries;
2425

ecsact/entt/wrapper/core.hh

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ inline auto update_component( //
118118
[[maybe_unused]] ecsact_component_id component_id,
119119
const void* component_data
120120
) -> ecsact_update_error {
121+
using ecsact::entt::detail::exec_beforechange_storage;
122+
121123
auto& reg = ecsact::entt::get_registry(registry_id);
122124
auto entity = ecsact::entt::entity_id{entity_id};
123125
assert(C::id == component_id);
@@ -129,10 +131,15 @@ inline auto update_component( //
129131
*static_cast<const C*>(component_data)
130132
);
131133

132-
if(err == ECSACT_UPDATE_OK) {
133-
reg.replace<C>(entity, *static_cast<const C*>(component_data));
134+
if(err != ECSACT_UPDATE_OK) {
135+
return err;
134136
}
135137

138+
const auto& in_component = *static_cast<const C*>(component_data);
139+
auto& current_component = reg.template get<C>(entity);
140+
141+
current_component = in_component;
142+
136143
return err;
137144
}
138145

@@ -143,6 +150,8 @@ inline auto update_component_exec_options( //
143150
[[maybe_unused]] ecsact_component_id component_id,
144151
const void* component_data
145152
) -> ecsact_update_error {
153+
using ecsact::entt::detail::exec_beforechange_storage;
154+
146155
auto& reg = ecsact::entt::get_registry(registry_id);
147156
auto entity = ecsact::entt::entity_id{entity_id};
148157
assert(C::id == component_id);
@@ -154,11 +163,20 @@ inline auto update_component_exec_options( //
154163
*static_cast<const C*>(component_data)
155164
);
156165

157-
if(err == ECSACT_UPDATE_OK) {
158-
reg.replace<C>(entity, *static_cast<const C*>(component_data));
159-
reg.template emplace_or_replace<component_updated<C>>(entity);
166+
if(err != ECSACT_UPDATE_OK) {
167+
return err;
160168
}
161169

170+
const auto& in_component = *static_cast<const C*>(component_data);
171+
auto& beforechange = reg.template get<exec_beforechange_storage<C>>(entity);
172+
auto& current_component = reg.template get<C>(entity);
173+
174+
if(!beforechange.has_update_occurred) {
175+
beforechange.value = current_component;
176+
beforechange.has_update_occurred = true;
177+
}
178+
current_component = in_component;
179+
162180
return err;
163181
}
164182

@@ -177,7 +195,6 @@ auto remove_component(
177195
reg.remove<detail::exec_beforechange_storage<C>>(entity);
178196
}
179197
reg.template remove<component_added<C>>(entity);
180-
reg.template remove<component_updated<C>>(entity);
181198
reg.template emplace_or_replace<component_removed<C>>(entity);
182199
ecsact::entt::detail::remove_system_markers_if_needed<C>(reg, entity);
183200
}
@@ -203,7 +220,6 @@ auto remove_component_exec_options(
203220

204221
reg.template erase<C>(entity);
205222
reg.template remove<component_added<C>>(entity);
206-
reg.template remove<component_updated<C>>(entity);
207223
reg.template emplace_or_replace<component_removed<C>>(entity);
208224

209225
if constexpr(!std::is_empty_v<C>) {
@@ -295,30 +311,30 @@ auto _trigger_update_component_event(
295311
ecsact_registry_id registry_id,
296312
ecsact::entt::detail::execution_events_collector& events_collector
297313
) -> void {
298-
using ecsact::entt::component_updated;
314+
using ecsact::entt::detail::beforeremove_storage;
299315
using ecsact::entt::detail::exec_beforechange_storage;
300316

317+
//
318+
301319
if(!events_collector.has_update_callback()) {
302320
return;
303321
}
304322

305323
auto& reg = ecsact::entt::get_registry(registry_id);
306324
if constexpr(!C::transient && !std::is_empty_v<C>) {
307-
::entt::basic_view changed_view{
308-
reg.template storage<C>(),
309-
reg.template storage<exec_beforechange_storage<C>>(),
310-
reg.template storage<component_updated<C>>(),
311-
};
325+
auto comp_view = reg.view<C, exec_beforechange_storage<C>>( //
326+
::entt::exclude<beforeremove_storage<C>>
327+
);
312328

313-
for(ecsact::entt::entity_id entity : changed_view) {
329+
for(ecsact::entt::entity_id entity : comp_view) {
314330
auto& before =
315-
changed_view.template get<exec_beforechange_storage<C>>(entity);
316-
auto& current = changed_view.template get<C>(entity);
317-
before.has_update_occurred = false;
331+
comp_view.template get<exec_beforechange_storage<C>>(entity);
332+
auto& current = comp_view.template get<C>(entity);
318333

319-
if(before.value != current) {
334+
if(before.has_update_occurred && before.value != current) {
320335
events_collector.invoke_update_callback<C>(entity, current);
321336
}
337+
before.has_update_occurred = false;
322338
}
323339
}
324340
}
@@ -384,7 +400,6 @@ inline auto clear_component(ecsact_registry_id registry_id) -> void {
384400
auto& reg = ecsact::entt::get_registry(registry_id);
385401

386402
reg.clear<ecsact::entt::component_added<C>>();
387-
reg.clear<ecsact::entt::component_updated<C>>();
388403
reg.clear<ecsact::entt::component_removed<C>>();
389404
}
390405

@@ -404,10 +419,13 @@ inline auto prepare_component(ecsact_registry_id registry_id) -> void {
404419
reg.template storage<C>();
405420
reg.template storage<component_added<C>>();
406421
reg.template storage<component_removed<C>>();
422+
reg.template storage<detail::pending_add<C>>();
423+
reg.template storage<detail::pending_remove<C>>();
424+
reg.template storage<detail::beforeremove_storage<C>>();
407425

408426
if constexpr(!std::is_empty_v<C>) {
409-
reg.storage<detail::exec_beforechange_storage<C>>();
410-
reg.template storage<component_updated<C>>();
427+
reg.template storage<detail::exec_beforechange_storage<C>>();
428+
reg.template storage<detail::exec_itr_beforechange_storage<C>>();
411429
}
412430
}
413431

@@ -418,6 +436,7 @@ inline auto prepare_system(ecsact_registry_id registry_id) -> void {
418436

419437
reg.template storage<system_sorted<S>>();
420438
reg.template storage<pending_lazy_execution<S>>();
439+
reg.template storage<run_system<S>>();
421440
}
422441

423442
template<typename C, typename V>
@@ -435,8 +454,10 @@ auto has_component_changed(entt::entity_id entity, V& view) -> bool {
435454
}
436455

437456
template<typename C>
438-
auto update_exec_itr_beforechange(entt::entity_id entity, ::entt::registry& reg)
439-
-> void {
457+
auto update_exec_itr_beforechange(
458+
entt::entity_id entity,
459+
ecsact::entt::registry_t& reg
460+
) -> void {
440461
auto comp = reg.get<C>(entity);
441462
auto& beforechange_comp =
442463
reg.get<detail::exec_itr_beforechange_storage<C>>(entity);

0 commit comments

Comments
 (0)