Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
chunk_iterator_typed.inl
1#pragma once
2
3namespace gaia {
4 namespace ecs {
6 namespace detail {
7 template <typename T>
8 IterTermDesc ChunkIterTypedOps::term_desc(const ChunkIterImpl& self) {
9 using Arg = std::remove_cv_t<std::remove_reference_t<T>>;
10 IterTermDesc desc;
11 if constexpr (std::is_same_v<Arg, Entity>) {
12 desc.termId = EntityBad;
13 desc.isEntity = true;
14 } else {
15 using FT = typename component_type_t<Arg>::TypeFull;
16 if constexpr (is_pair<FT>::value) {
17 desc.termId = EntityBad;
18 desc.isEntity = false;
19 desc.storageKnown = true;
20 } else {
21 desc.termId = world_query_arg_id<Arg>(*const_cast<World*>(self.world()));
22 desc.isEntity = false;
23 desc.usesSparseStorage = auto_storage_policy_v<Arg> == DataStorageType::Sparse;
24 desc.storageKnown = true;
25 }
26 }
27 return desc;
28 }
29
30 template <typename T>
31 auto ChunkIterTypedOps::view_any(const ChunkIterImpl& self) {
32 using U = typename actual_type_t<T>::Type;
33 if constexpr (std::is_same_v<U, Entity> || mem::is_soa_layout_v<U>)
34 return self.m_pChunk->template view<T>(self.from(), self.to());
35 else if constexpr (auto_storage_policy_v<U> == DataStorageType::Sparse) {
36 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
37 auto* pWorld = const_cast<World*>(self.world());
38 return EntityTermViewGetSparse<U>{
39 self.m_pChunk->entity_view().data() + self.from(), pWorld,
40 world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId, self.size()};
41 } else {
42 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
43 const auto id = desc.usesSparseStorage ? desc.termId : EntityBad;
44
45 if (id != EntityBad)
46 return EntityTermViewGet<U>::entity(
47 self.m_pChunk->entity_view().data() + self.from(), const_cast<World*>(self.world()), id, self.size());
48
49 auto* pData = reinterpret_cast<const U*>(self.m_pChunk->template view<T>(self.from(), self.to()).data());
50 return EntityTermViewGet<U>::pointer(pData, self.size());
51 }
52 }
53
54 template <typename T>
55 auto ChunkIterTypedOps::view_any(ChunkIterImpl& self, uint32_t termIdx) {
56 using U = typename actual_type_t<T>::Type;
57
58 if constexpr (mem::is_soa_layout_v<U>) {
59 const auto compIdx = self.m_pCompIndices[termIdx];
60 if (compIdx == 0xFF) {
61 const auto* pEntities = self.m_pChunk->entity_view().data() + self.from();
62 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
63 GAIA_ASSERT(desc.termId != EntityBad);
64 return SoATermViewGet<U>{nullptr, 0, pEntities, const_cast<World*>(self.world()),
65 desc.termId, 0, self.size()};
66 }
67
68 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
69 return SoATermViewGet<U>{
70 self.m_pChunk->comp_ptr(compIdx),
71 self.m_pChunk->capacity(),
72 nullptr,
73 const_cast<World*>(self.world()),
74 EntityBad,
75 self.from(),
76 self.size()};
77 } else if constexpr (auto_storage_policy_v<U> == DataStorageType::Sparse) {
78 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
79 auto* pWorld = const_cast<World*>(self.world());
80 return EntityTermViewGetSparse<U>{
81 self.m_pChunk->entity_view().data() + self.from(), pWorld,
82 world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId, self.size()};
83 } else {
84 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
85 const auto compIdx = self.m_pCompIndices[termIdx];
86 if (desc.usesSparseStorage)
87 return EntityTermViewGet<U>::entity(
88 self.m_pChunk->entity_view().data() + self.from(), const_cast<World*>(self.world()), desc.termId,
89 self.size());
90
91 if (compIdx == 0xFF) {
92 GAIA_ASSERT(desc.termId != EntityBad);
93 if (!self.m_inheritedData.empty()) {
94 const auto* pInheritedValue = reinterpret_cast<const U*>(self.m_inheritedData[termIdx]);
95 if (pInheritedValue != nullptr)
96 return EntityTermViewGet<U>::inherited(pInheritedValue, self.size());
97 }
98 if (world_term_uses_inherit_policy(*self.world(), desc.termId)) {
99 return EntityTermViewGet<U>::entity_chunk_stable(
100 self.m_pChunk->entity_view().data() + self.from(), self.m_pChunk, const_cast<World*>(self.world()),
101 desc.termId, self.from(), self.size());
102 }
103 return EntityTermViewGet<U>::entity(
104 self.m_pChunk->entity_view().data() + self.from(), const_cast<World*>(self.world()), desc.termId,
105 self.size());
106 }
107 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
108
109 auto* pData = reinterpret_cast<const U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
110 return EntityTermViewGet<U>::pointer(pData, self.size());
111 }
112 }
113
114 template <typename T>
115 auto ChunkIterTypedOps::view(const ChunkIterImpl& self) {
116 using U = typename actual_type_t<T>::Type;
117 if constexpr (std::is_same_v<U, Entity>)
118 return self.m_pChunk->template view<T>(self.from(), self.to());
119 else if constexpr (mem::is_soa_layout_v<U>) {
120 const auto view = self.m_pChunk->template view<T>(self.from(), self.to());
121 return SoATermViewGetPointer<U>{(const uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
122 } else {
123 auto* pData = reinterpret_cast<const U*>(self.m_pChunk->template view<T>(self.from(), self.to()).data());
124 return EntityTermViewGetPointer<U>{pData, self.size()};
125 }
126 }
127
128 template <typename T>
129 auto ChunkIterTypedOps::view(const ChunkIterImpl& self, uint32_t termIdx) {
130 using U = typename actual_type_t<T>::Type;
131 const auto compIdx = self.m_pCompIndices[termIdx];
132 GAIA_ASSERT(compIdx != 0xFF);
133
134 if constexpr (mem::is_soa_layout_v<U>)
135 return SoATermViewGetPointer<U>{
136 self.m_pChunk->comp_ptr(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
137 else {
138 auto* pData = reinterpret_cast<const U*>(self.m_pChunk->comp_ptr(compIdx, self.from()));
139 return EntityTermViewGetPointer<U>{pData, self.size()};
140 }
141 }
142
143 template <typename T>
144 auto ChunkIterTypedOps::view_any_mut(ChunkIterImpl& self) {
145 using U = typename actual_type_t<T>::Type;
146 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via view_mut is forbidden");
147 if constexpr (mem::is_soa_layout_v<U>) {
148 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
149 const bool tracked = self.touch_term_desc(desc);
150 GAIA_ASSERT(tracked);
151 (void)tracked;
152 if (self.m_writeIm)
153 return self.m_pChunk->template view_mut<T>(self.from(), self.to());
154 return self.m_pChunk->template sview_mut<T>(self.from(), self.to());
155 } else if constexpr (auto_storage_policy_v<U> == DataStorageType::Sparse) {
156 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
157 if (!self.touch_term(desc.termId))
158 return EntityTermViewSetSparse<U>{};
159 auto* pWorld = const_cast<World*>(self.world());
160 return EntityTermViewSetSparse<U>{
161 self.entity_snapshot(), pWorld, world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId,
162 self.size()};
163 } else {
164 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
165 const auto id = desc.usesSparseStorage ? desc.termId : EntityBad;
166
167 if (id != EntityBad) {
168 if (!self.touch_term(id))
169 return self.template entity_view_set_empty<U>(self.m_writeIm);
170 return self.template entity_view_set<U>(id, self.m_writeIm);
171 }
172
173 if (!self.touch_term_desc(desc))
174 return self.template entity_view_set_empty<U>(self.m_writeIm);
175 auto* pData =
176 reinterpret_cast<U*>((self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
177 : self.m_pChunk->template sview_mut<T>(self.from(), self.to()))
178 .data());
179 return EntityTermViewSet<U>::pointer(pData, self.size());
180 }
181 }
182
183 template <typename T>
184 auto ChunkIterTypedOps::view_mut(ChunkIterImpl& self) {
185 using U = typename actual_type_t<T>::Type;
186 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via view_mut is forbidden");
187 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
188 const bool tracked = self.touch_term_desc(desc);
189 if constexpr (mem::is_soa_layout_v<U>) {
190 if (!tracked)
191 return SoATermViewSetPointer<U>{};
192 auto view = self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
193 : self.m_pChunk->template sview_mut<T>(self.from(), self.to());
194 return SoATermViewSetPointer<U>{(uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
195 } else {
196 if (!tracked)
197 return EntityTermViewSetPointer<U>{};
198 auto* pData =
199 reinterpret_cast<U*>((self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
200 : self.m_pChunk->template sview_mut<T>(self.from(), self.to()))
201 .data());
202 return EntityTermViewSetPointer<U>{pData, self.size()};
203 }
204 }
205
206 template <typename T>
207 auto ChunkIterTypedOps::view_mut(ChunkIterImpl& self, uint32_t termIdx) {
208 using U = typename actual_type_t<T>::Type;
209 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via view_mut is forbidden");
210 const auto compIdx = self.m_pCompIndices[termIdx];
211 GAIA_ASSERT(compIdx != 0xFF);
212 self.touch_comp_idx(compIdx);
213
214 if constexpr (mem::is_soa_layout_v<U>) {
215 if (self.m_writeIm)
216 self.m_pChunk->update_world_version(compIdx);
217 return SoATermViewSetPointer<U>{
218 self.m_pChunk->comp_ptr_mut(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
219 } else {
220 if (self.m_writeIm)
221 self.m_pChunk->update_world_version(compIdx);
222 auto* pData = reinterpret_cast<U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
223 return EntityTermViewSetPointer<U>{pData, self.size()};
224 }
225 }
226
227 template <typename T>
228 auto ChunkIterTypedOps::view_any_mut(ChunkIterImpl& self, uint32_t termIdx) {
229 using U = typename actual_type_t<T>::Type;
230
231 if constexpr (mem::is_soa_layout_v<U>) {
232 const auto compIdx = self.m_pCompIndices[termIdx];
233 if (compIdx == 0xFF) {
234 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
235 GAIA_ASSERT(desc.termId != EntityBad);
236 if (!self.touch_term(desc.termId))
237 return self.template entity_soa_view_set_empty<U>(self.m_writeIm);
238 return self.template entity_soa_view_set<U>(desc.termId, self.m_writeIm);
239 }
240
241 GAIA_ASSERT(compIdx < self.m_pChunk->comp_rec_view().size());
242 self.touch_comp_idx(compIdx);
243 if (self.m_writeIm)
244 self.m_pChunk->update_world_version(compIdx);
245 return SoATermViewSet<U>{
246 self.m_pChunk->comp_ptr_mut(compIdx),
247 self.m_pChunk->capacity(),
248 nullptr,
249 self.world(),
250 EntityBad,
251 self.from(),
252 self.size(),
253 self.m_writeIm};
254 } else if constexpr (auto_storage_policy_v<U> == DataStorageType::Sparse) {
255 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
256 if (!self.touch_term(desc.termId))
257 return EntityTermViewSetSparse<U>{};
258 auto* pWorld = const_cast<World*>(self.world());
259 return EntityTermViewSetSparse<U>{
260 self.entity_snapshot(), pWorld, world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId,
261 self.size()};
262 } else {
263 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
264 const auto compIdx = self.m_pCompIndices[termIdx];
265 if (desc.usesSparseStorage) {
266 if (!self.touch_term(desc.termId))
267 return self.template entity_view_set_empty<U>(self.m_writeIm);
268 return self.template entity_view_set<U>(desc.termId, self.m_writeIm);
269 }
270
271 if (compIdx == 0xFF) {
272 GAIA_ASSERT(desc.termId != EntityBad);
273 if (!self.touch_term(desc.termId))
274 return self.template entity_view_set_empty<U>(self.m_writeIm);
275 return self.template entity_view_set<U>(desc.termId, self.m_writeIm);
276 }
277 GAIA_ASSERT(compIdx < self.m_pChunk->comp_rec_view().size());
278
279 self.touch_comp_idx(compIdx);
280 if (self.m_writeIm)
281 self.m_pChunk->update_world_version(compIdx);
282
283 auto* pData = reinterpret_cast<U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
284 return EntityTermViewSet<U>::pointer(pData, self.size());
285 }
286 }
287
288 template <typename T>
289 auto ChunkIterTypedOps::sview_any_mut(ChunkIterImpl& self) {
290 using U = typename actual_type_t<T>::Type;
291 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via sview_mut is forbidden");
292 if constexpr (mem::is_soa_layout_v<U>)
293 return self.m_pChunk->template sview_mut<T>(self.from(), self.to());
294 else if constexpr (auto_storage_policy_v<U> == DataStorageType::Sparse) {
295 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
296 auto* pWorld = const_cast<World*>(self.world());
297 return EntityTermViewSetSparse<U>{
298 self.entity_snapshot(), pWorld, world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId,
299 self.size()};
300 } else {
301 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
302 const auto id = desc.usesSparseStorage ? desc.termId : EntityBad;
303
304 if (id != EntityBad)
305 return self.template entity_view_set<U>(id, false);
306
307 auto* pData = reinterpret_cast<U*>(self.m_pChunk->template sview_mut<T>(self.from(), self.to()).data());
308 return EntityTermViewSet<U>::pointer(pData, self.size());
309 }
310 }
311
312 template <typename T>
313 auto ChunkIterTypedOps::sview_mut(ChunkIterImpl& self) {
314 using U = typename actual_type_t<T>::Type;
315 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via sview_mut is forbidden");
316 if constexpr (mem::is_soa_layout_v<U>) {
317 auto view = self.m_pChunk->template sview_mut<T>(self.from(), self.to());
318 return SoATermViewSetPointer<U>{(uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
319 } else {
320 auto* pData = reinterpret_cast<U*>(self.m_pChunk->template sview_mut<T>(self.from(), self.to()).data());
321 return EntityTermViewSetPointer<U>{pData, self.size()};
322 }
323 }
324
325 template <typename T>
326 auto ChunkIterTypedOps::sview_mut(ChunkIterImpl& self, uint32_t termIdx) {
327 using U = typename actual_type_t<T>::Type;
328 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via sview_mut is forbidden");
329 const auto compIdx = self.m_pCompIndices[termIdx];
330 GAIA_ASSERT(compIdx != 0xFF);
331
332 if constexpr (mem::is_soa_layout_v<U>)
333 return SoATermViewSetPointer<U>{
334 self.m_pChunk->comp_ptr_mut(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
335 else {
336 auto* pData = reinterpret_cast<U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
337 return EntityTermViewSetPointer<U>{pData, self.size()};
338 }
339 }
340
341 template <typename T>
342 auto ChunkIterTypedOps::sview_any_mut(ChunkIterImpl& self, uint32_t termIdx) {
343 using U = typename actual_type_t<T>::Type;
344
345 if constexpr (mem::is_soa_layout_v<U>) {
346 const auto compIdx = self.m_pCompIndices[termIdx];
347 if (compIdx == 0xFF) {
348 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
349 GAIA_ASSERT(desc.termId != EntityBad);
350 return self.template entity_soa_view_set<U>(desc.termId, false);
351 }
352
353 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
354 return SoATermViewSet<U>{
355 self.m_pChunk->comp_ptr_mut(compIdx),
356 self.m_pChunk->capacity(),
357 nullptr,
358 self.world(),
359 EntityBad,
360 self.from(),
361 self.size(),
362 false};
363 } else if constexpr (auto_storage_policy_v<U> == DataStorageType::Sparse) {
364 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
365 auto* pWorld = const_cast<World*>(self.world());
366 return EntityTermViewSetSparse<U>{
367 self.entity_snapshot(), pWorld, world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId,
368 self.size()};
369 } else {
370 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
371 const auto compIdx = self.m_pCompIndices[termIdx];
372 if (desc.usesSparseStorage)
373 return self.template entity_view_set<U>(desc.termId, false);
374
375 if (compIdx == 0xFF) {
376 GAIA_ASSERT(desc.termId != EntityBad);
377 return self.template entity_view_set<U>(desc.termId, false);
378 }
379 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
380
381 auto* pData = reinterpret_cast<U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
382 return EntityTermViewSet<U>::pointer(pData, self.size());
383 }
384 }
385
386 } // namespace detail
388
389 } // namespace ecs
390} // namespace gaia
static constexpr bool value
True when the type derives from the pair base.
Definition id.h:287