Skip to content

Commit ab0121d

Browse files
committed
chore: refactor entity entt <-> ecsact entity IDs
1 parent b91a459 commit ab0121d

File tree

6 files changed

+269
-250
lines changed

6 files changed

+269
-250
lines changed

ecsact/entt/detail/registry_info.hh

Lines changed: 33 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,19 @@
1212
#include "ecsact/cpp/type_info.hh"
1313
#include "ecsact/entt/system_view.hh"
1414
#include "ecsact/entt/event_markers.hh"
15+
#include "ecsact/entt/entity.hh"
1516
#include "ecsact/entt/detail/internal_markers.hh"
1617

1718
#include "meta_util.hh"
1819

1920
namespace ecsact_entt_rt {
20-
using entity_id_map_t = std::unordered_map<ecsact_entity_id, entt::entity>;
2121

2222
template<typename Package>
2323
struct registry_info {
2424
using package = Package;
2525

2626
std::optional<std::reference_wrapper<std::mutex>> mutex;
2727
::entt::registry registry;
28-
entity_id_map_t entities_map;
29-
30-
/**
31-
* Index of this vector is a statically casted EnTT ID
32-
*/
33-
std::vector<ecsact_entity_id> _ecsact_entity_ids;
34-
35-
ecsact_entity_id last_entity_id{};
36-
37-
struct create_new_entity_result {
38-
entt::entity entt_entity_id;
39-
ecsact_entity_id ecsact_entity_id;
40-
};
4128

4229
void init_registry() {
4330
using ecsact::entt::component_added;
@@ -64,18 +51,19 @@ struct registry_info {
6451
using boost::mp11::mp_with_index;
6552
using ecsact::entt::detail::association;
6653

67-
auto entity_field = field.template get<ecsact_entity_id>(&component);
68-
auto entity_field_entt = entities_map.at(entity_field);
54+
ecsact::entt::entity_id entity_field =
55+
field.template get<ecsact_entity_id>(&component);
56+
6957
// TODO(zaucy): Increasing the mp_with_index number causes really long
7058
// compile times. Iterating over the available associations
7159
// would perform better here.
7260
assert(field.offset < 32);
7361
mp_with_index<32>(field.offset, [&](auto I) {
74-
if(registry.all_of<association<C, I>>(entity_field_entt)) {
75-
auto& assoc_comp = registry.get<association<C, I>>(entity_field_entt);
62+
if(registry.all_of<association<C, I>>(entity_field)) {
63+
auto& assoc_comp = registry.get<association<C, I>>(entity_field);
7664
assoc_comp.ref_count += 1;
7765
} else {
78-
registry.emplace<association<C, I>>(entity_field_entt, 1);
66+
registry.emplace<association<C, I>>(entity_field, 1);
7967
}
8068
});
8169
}
@@ -88,30 +76,31 @@ struct registry_info {
8876
using boost::mp11::mp_with_index;
8977
using ecsact::entt::detail::association;
9078

91-
auto entity_field = field.template get<ecsact_entity_id>(&component);
92-
auto entity_field_entt = entities_map.at(entity_field);
79+
ecsact::entt::entity_id entity_field =
80+
field.template get<ecsact_entity_id>(&component);
81+
9382
assert(field.offset < 32);
9483
// TODO(zaucy): Increasing the mp_with_index number causes really long
9584
// compile times. Iterating over the available associations
9685
// would perform better here.
9786
mp_with_index<32>(field.offset, [&](auto I) {
98-
auto& assoc_comp = registry.get<association<C, I>>(entity_field_entt);
87+
auto& assoc_comp = registry.get<association<C, I>>(entity_field);
9988
assoc_comp.ref_count -= 1;
10089
if(assoc_comp.ref_count == 0) {
101-
registry.erase<association<C, I>>(entity_field_entt);
90+
registry.erase<association<C, I>>(entity_field);
10291
}
10392
});
10493
}
10594

10695
template<typename C>
10796
requires(std::is_empty_v<C>)
108-
void add_component(::entt::entity entity) {
97+
void add_component(ecsact::entt::entity_id entity) {
10998
registry.emplace<C>(entity);
11099
}
111100

112101
template<typename C, typename... Args>
113102
requires(!std::is_empty_v<C>)
114-
void add_component(::entt::entity entity, Args&&... args) {
103+
void add_component(ecsact::entt::entity_id entity, Args&&... args) {
115104
using boost::mp11::mp_with_index;
116105
using ecsact::entt::detail::mp_for_each_available_component;
117106

@@ -142,7 +131,7 @@ struct registry_info {
142131
}
143132

144133
template<typename C>
145-
void remove_component(::entt::entity entity) {
134+
void remove_component(ecsact::entt::entity_id entity) {
146135
using ecsact::entt::detail::mp_for_each_available_component;
147136

148137
constexpr auto fields_info = ecsact::fields_info<C>();
@@ -168,32 +157,27 @@ struct registry_info {
168157
}
169158

170159
/** @internal */
171-
inline auto _create_entity(ecsact_entity_id ecsact_entity_id) {
172-
auto new_entt_entity_id = registry.create();
173-
entities_map[ecsact_entity_id] = new_entt_entity_id;
174-
_ecsact_entity_ids.resize(static_cast<size_t>(new_entt_entity_id) + 1);
175-
_ecsact_entity_ids[_ecsact_entity_ids.size() - 1] = ecsact_entity_id;
176-
return new_entt_entity_id;
160+
inline auto _create_entity( //
161+
ecsact::entt::entity_id entity
162+
) -> ecsact::entt::entity_id {
163+
if(registry.valid(entity)) {
164+
return entity;
165+
}
166+
167+
auto new_entity = registry.create(entity.as_entt());
168+
// Our valid check above should have allowed this to happen
169+
assert(new_entity == entity.as_entt());
170+
return new_entity;
177171
}
178172

179173
/** @internal */
180-
inline create_new_entity_result _create_entity() {
181-
auto new_entity_id =
182-
static_cast<ecsact_entity_id>(static_cast<int>(last_entity_id) + 1);
183-
while(entities_map.contains(new_entity_id)) {
184-
new_entity_id =
185-
static_cast<ecsact_entity_id>(static_cast<int>(new_entity_id) + 1);
186-
}
187-
last_entity_id = new_entity_id;
188-
return {
189-
.entt_entity_id = _create_entity(new_entity_id),
190-
.ecsact_entity_id = new_entity_id,
191-
};
174+
inline auto _create_entity() -> ecsact::entt::entity_id {
175+
return registry.create();
192176
}
193177

194-
// Creates an entity and also makes sure there is a matching one in the
195-
// pending registry
196-
inline auto create_entity(ecsact_entity_id ecsact_entity_id) {
178+
inline auto create_entity( //
179+
ecsact::entt::entity_id ecsact_entity_id
180+
) -> ecsact::entt::entity_id {
197181
std::scoped_lock lk(mutex->get());
198182
return _create_entity(ecsact_entity_id);
199183
}
@@ -203,19 +187,8 @@ struct registry_info {
203187
return _create_entity();
204188
}
205189

206-
inline void destroy_entity(ecsact_entity_id entity_id) {
207-
auto entt_entity_id = entities_map.at(entity_id);
208-
209-
registry.destroy(entt_entity_id);
210-
entities_map.erase(entity_id);
211-
}
212-
213-
entt::entity get_entt_entity_id(ecsact_entity_id ecsact_entity_id) const {
214-
return entities_map.at(ecsact_entity_id);
215-
}
216-
217-
ecsact_entity_id get_ecsact_entity_id(entt::entity entt_entity_id) const {
218-
return _ecsact_entity_ids.at(static_cast<size_t>(entt_entity_id));
190+
inline void destroy_entity(ecsact::entt::entity_id entity_id) {
191+
registry.destroy(entity_id);
219192
}
220193
};
221194
} // namespace ecsact_entt_rt

ecsact/entt/detail/system_execution_context.hh

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ struct system_execution_context_base {
3636
using cptr_t = struct ::ecsact_system_execution_context*;
3737
using const_cptr_t = const struct ::ecsact_system_execution_context*;
3838

39-
::entt::entity entity;
40-
const cptr_t parent;
41-
const void* action;
39+
ecsact::entt::entity_id entity;
40+
const cptr_t parent;
41+
const void* action;
4242

4343
system_execution_context_base(
4444
::entt::entity entity,
@@ -48,13 +48,11 @@ struct system_execution_context_base {
4848
: entity(entity), parent(parent), action(action) {
4949
}
5050

51-
virtual ~system_execution_context_base() {
52-
}
53-
54-
virtual auto other(ecsact_entity_id other_entity)
55-
-> ecsact_system_execution_context* = 0;
51+
virtual ~system_execution_context_base() = default;
5652

57-
virtual auto get_ecsact_entity_id() -> ecsact_entity_id const = 0;
53+
virtual auto other( //
54+
ecsact::entt::entity_id other_entity
55+
) -> ecsact_system_execution_context* = 0;
5856

5957
virtual auto generate(
6058
int component_count,
@@ -376,7 +374,7 @@ struct system_execution_context : system_execution_context_base {
376374
using ecsact::entt::detail::mp_for_each_available_component;
377375
using ecsact::entt::detail::pending_add;
378376

379-
auto new_entity = info.create_entity().entt_entity_id;
377+
auto new_entity = info.create_entity();
380378
info.registry.template emplace<created_entity>(
381379
new_entity,
382380
ecsact_generated_entity
@@ -401,8 +399,9 @@ struct system_execution_context : system_execution_context_base {
401399
}
402400
}
403401

404-
auto other(ecsact_entity_id other_entity)
405-
-> ecsact_system_execution_context* override {
402+
auto other( //
403+
ecsact::entt::entity_id other_entity
404+
) -> ecsact_system_execution_context* override {
406405
using boost::mp11::mp_first;
407406
using boost::mp11::mp_for_each;
408407
using boost::mp11::mp_second;
@@ -422,13 +421,12 @@ struct system_execution_context : system_execution_context_base {
422421
constexpr std::size_t offset = Assoc::field_offset;
423422
const ComponentT& comp = info.registry.template get<ComponentT>(entity);
424423

425-
auto field_entity_value = *reinterpret_cast<const ecsact_entity_id*>(
426-
reinterpret_cast<const char*>(&comp) + offset
427-
);
424+
ecsact::entt::entity_id field_entity_value =
425+
*reinterpret_cast<const ecsact_entity_id*>(
426+
reinterpret_cast<const char*>(&comp) + offset
427+
);
428428

429429
if(field_entity_value == other_entity) {
430-
auto entt_field_entity_value =
431-
info.get_entt_entity_id(field_entity_value);
432430
using boost::mp11::mp_size;
433431
mp_with_index<mp_size<associations>::value>(assoc_index, [&](auto I) {
434432
using other_context_t = std::tuple_element_t<I, others_t>;
@@ -449,7 +447,7 @@ struct system_execution_context : system_execution_context_base {
449447
_c_ctx.system_id,
450448
assoc_view,
451449
empty_views, // see static assertion above
452-
entt_field_entity_value,
450+
field_entity_value,
453451
parent,
454452
action
455453
);
@@ -468,10 +466,6 @@ struct system_execution_context : system_execution_context_base {
468466

469467
return return_context;
470468
}
471-
472-
auto get_ecsact_entity_id() -> ecsact_entity_id const override {
473-
return info.get_ecsact_entity_id(entity);
474-
}
475469
};
476470

477471
} // namespace ecsact_entt_rt

ecsact/entt/entity.hh

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include "ecsact/runtime/common.h"
5+
#include <entt/entity/entity.hpp>
6+
7+
namespace ecsact::entt {
8+
9+
/**
10+
* The Ecsact and EnTT entity IDs are supposed to be 1:1. This class serves to
11+
* make using either trivial.
12+
*/
13+
class entity_id {
14+
std::int32_t _id;
15+
16+
public:
17+
inline entity_id(::entt::entity entt_entity)
18+
: _id(reinterpret_cast<std::int32_t&>(entt_entity)) {
19+
}
20+
21+
inline entity_id(ecsact_entity_id ecsact_entity)
22+
: _id(reinterpret_cast<std::int32_t&>(ecsact_entity)) {
23+
}
24+
25+
entity_id(const entity_id&) = default;
26+
entity_id(entity_id&&) = default;
27+
28+
auto operator=(const entity_id&) -> entity_id& = default;
29+
auto operator=(entity_id&&) -> entity_id& = default;
30+
31+
auto operator<=>(const entity_id&) const = default;
32+
33+
inline auto operator=(::entt::entity entt_entity) noexcept -> entity_id& {
34+
_id = reinterpret_cast<std::int32_t&>(entt_entity);
35+
return *this;
36+
}
37+
38+
inline auto operator=(ecsact_entity_id ecsact_entity) noexcept -> entity_id& {
39+
_id = reinterpret_cast<std::int32_t&>(ecsact_entity);
40+
return *this;
41+
}
42+
43+
inline operator ecsact_entity_id() const noexcept {
44+
return reinterpret_cast<const ecsact_entity_id&>(_id);
45+
}
46+
47+
inline operator ::entt::entity() const noexcept {
48+
return reinterpret_cast<const ::entt::entity&>(_id);
49+
}
50+
51+
[[nodiscard]] inline auto as_ecsact() const noexcept -> ecsact_entity_id {
52+
return reinterpret_cast<const ecsact_entity_id&>(_id);
53+
}
54+
55+
[[nodiscard]] inline auto as_entt() const noexcept -> ::entt::entity {
56+
return reinterpret_cast<const ::entt::entity&>(_id);
57+
}
58+
};
59+
60+
} // namespace ecsact::entt

0 commit comments

Comments
 (0)