SDEngine
Game Engine
Loading...
Searching...
No Matches
SparseEntitySet.hpp
Go to the documentation of this file.
1#pragma once
2#include "Entity.hpp"
3#include "SD/arena.hpp"
8
9namespace sd {
10
11template<typename T>
13 static constexpr USize PAGE_SIZE = 1024;
14 static constexpr USize SHIFT = math::log2_int(PAGE_SIZE);
15 static constexpr USize MASK = PAGE_SIZE - 1;
16
17 Arena* arena = nullptr;
18
19 USize** sparse_pages = nullptr;
22
25
27 if (page >= sparse_cap) {
28 U64 new_cap = sparse_cap ? sparse_cap * 2 : 4;
29 while (new_cap <= page)
30 new_cap *= 2;
32 for (U64 i = 0; i < sparse_count; ++i)
34 for (U64 i = sparse_count; i < new_cap; ++i)
35 new_pages[i] = nullptr;
38 }
39 if (page >= sparse_count)
40 sparse_count = page + 1;
41 if (!sparse_pages[page]) {
43 for (USize i = 0; i < PAGE_SIZE; ++i)
44 sparse_pages[page][i] = std::numeric_limits<USize>::max();
45 }
46 }
47
48 template<typename... Args>
49 void add(Entity entity, Args&&... args) {
50 USize page = entity.index >> SHIFT;
51 USize offset = entity.index & MASK;
52
54
56 if (dense_idx != std::numeric_limits<USize>::max()) {
57 dense_data[dense_idx] = T{std::forward<Args>(args)...};
59 } else {
60 sparse_pages[page][offset] = static_cast<USize>(dense_entities.count);
61 dense_data.push(arena, T{std::forward<Args>(args)...});
63 }
64 }
65
67 USize page = entity.index >> SHIFT;
68 USize offset = entity.index & MASK;
69
71 return false;
72
74 if (dense_idx == std::numeric_limits<USize>::max())
75 return false;
77 return false;
78
79 U64 last_idx = dense_entities.count - 1;
81
84
88
89 sparse_pages[page][offset] = std::numeric_limits<USize>::max();
90
91 dense_data.count--;
92 dense_entities.count--;
93 return true;
94 }
95
97 USize page = entity.index >> SHIFT;
98 USize offset = entity.index & MASK;
99
101 return nullptr;
102
104 if (dense_idx == std::numeric_limits<USize>::max())
105 return nullptr;
107 return nullptr;
108
109 return &dense_data[dense_idx];
110 }
111
112 const T* get(Entity entity) const {
113 USize page = entity.index >> SHIFT;
114 USize offset = entity.index & MASK;
115
117 return nullptr;
118
120 if (dense_idx == std::numeric_limits<USize>::max())
121 return nullptr;
123 return nullptr;
124
125 return &dense_data[dense_idx];
126 }
127
128 T* operator[](Entity idx) { return get(idx); }
129
131
132 USize size() const { return static_cast<USize>(dense_entities.count); }
133
134 void clear() {
135 sparse_pages = nullptr;
136 sparse_count = 0;
137 sparse_cap = 0;
138 dense_data.clear();
139 dense_entities.clear();
140 }
141
142 void serialize_to(std::vector<char>& out) const {
143 size_t entity_count = static_cast<size_t>(dense_entities.count);
144 size_t comp_size = sizeof(T);
145
146 out.resize(sizeof(size_t) * 2 + entity_count * (sizeof(Entity) + comp_size));
147 char* ptr = out.data();
148 memcpy(ptr, &entity_count, sizeof(size_t));
149 ptr += sizeof(size_t);
150 memcpy(ptr, &comp_size, sizeof(size_t));
151 ptr += sizeof(size_t);
152
153 memcpy(ptr, dense_entities.data, entity_count * sizeof(Entity));
154 ptr += entity_count * sizeof(Entity);
156 }
157
158 void deserialize_from(const std::vector<char>& data) {
159 const char* ptr = data.data();
160 size_t entity_count, comp_size;
161 memcpy(&entity_count, ptr, sizeof(size_t));
162 ptr += sizeof(size_t);
163 memcpy(&comp_size, ptr, sizeof(size_t));
164 ptr += sizeof(size_t);
165
166 for (size_t i = 0; i < entity_count; ++i) {
167 Entity e;
168 memcpy(&e, ptr + i * sizeof(Entity), sizeof(Entity));
169 ptr += sizeof(Entity);
170 }
171 ptr = data.data() + sizeof(size_t) * 2;
172 for (size_t i = 0; i < entity_count; ++i) {
173 Entity e;
174 memcpy(&e, ptr, sizeof(Entity));
175 ptr += sizeof(Entity);
176 dense_entities.push(arena, e);
177 T comp;
179 ptr += comp_size;
180 add(e, std::move(comp));
181 }
182 }
183
184 void serialize(Serializer& s) const {
185 s.write(static_cast<U32>(dense_entities.count));
186 for (U64 i = 0; i < dense_entities.count; ++i) {
187 s.write(dense_entities[i].index);
188 s.write(dense_entities[i].generation);
189 }
190 if constexpr (SerializableComponent<T>) {
191 for (U64 i = 0; i < dense_data.count; ++i) {
193 }
194 }
195 }
196
198 U32 count = s.read<U32>();
199 for (U32 i = 0; i < count; ++i) {
200 Entity e;
201 e.index = s.read<U32>();
202 e.generation = s.read<U32>();
203 dense_entities.push(arena, e);
204 }
205 if constexpr (SerializableComponent<T>) {
206 for (U32 i = 0; i < count; ++i) {
207 T comp;
209 dense_data.push(arena, comp);
210 }
211 }
212 for (U64 i = 0; i < dense_entities.count; ++i) {
214 USize page = e.index >> SHIFT;
215 USize offset = e.index & MASK;
217 sparse_pages[page][offset] = static_cast<USize>(i);
218 }
219 }
220
222};
223
224} // namespace sd
Definition component_registration.hpp:68
consteval USize log2_int(std::unsigned_integral auto n)
Definition math_utils.hpp:10
Definition Application.hpp:22
Definition arena_vec.hpp:6
Definition arena.hpp:85
T * push_array(this Arena &arena, U64 count)
Definition arena.hpp:120
static void deserialize(T &component, Serializer &s)=delete
static void serialize(const T &component, Serializer &s)=delete
Definition Entity.hpp:18
U32 index
Definition Entity.hpp:19
Definition RuntimeStateManager.hpp:24
Definition serialization.hpp:38
Definition SparseEntitySet.hpp:12
const ArenaVec< Entity > & get_dense_entities() const
Definition SparseEntitySet.hpp:130
void deserialize(Serializer &s)
Definition SparseEntitySet.hpp:197
U64 sparse_cap
Definition SparseEntitySet.hpp:21
void serialize(Serializer &s) const
Definition SparseEntitySet.hpp:184
bool remove(Entity entity)
Definition SparseEntitySet.hpp:66
static constexpr USize MASK
Definition SparseEntitySet.hpp:15
T * operator[](Entity idx)
Definition SparseEntitySet.hpp:128
T * get(Entity entity)
Definition SparseEntitySet.hpp:96
void clear()
Definition SparseEntitySet.hpp:134
U64 sparse_count
Definition SparseEntitySet.hpp:20
const T * get(Entity entity) const
Definition SparseEntitySet.hpp:112
void deserialize_from(const std::vector< char > &data)
Definition SparseEntitySet.hpp:158
static constexpr USize SHIFT
Definition SparseEntitySet.hpp:14
USize ** sparse_pages
Definition SparseEntitySet.hpp:19
ArenaVec< Entity > dense_entities
Definition SparseEntitySet.hpp:24
USize size() const
Definition SparseEntitySet.hpp:132
ArenaVec< T > dense_data
Definition SparseEntitySet.hpp:23
Arena * arena
Definition SparseEntitySet.hpp:17
void add(Entity entity, Args &&... args)
Definition SparseEntitySet.hpp:49
static constexpr USize PAGE_SIZE
Definition SparseEntitySet.hpp:13
void ensure_page(USize page)
Definition SparseEntitySet.hpp:26
void serialize_to(std::vector< char > &out) const
Definition SparseEntitySet.hpp:142
consteval U64 type_id_of()
Definition type_id.hpp:6
std::uint32_t U32
Definition types.hpp:15
std::size_t USize
Definition types.hpp:18
std::uint64_t U64
Definition types.hpp:16