8 IterTermDesc ChunkIterTypedOps::term_desc(
const ChunkIterImpl& self) {
9 using Arg = std::remove_cv_t<std::remove_reference_t<T>>;
11 if constexpr (std::is_same_v<Arg, Entity>) {
12 desc.termId = EntityBad;
15 desc.termId = world_query_arg_id<Arg>(*
const_cast<World*
>(self.world()));
16 desc.isEntity =
false;
17 desc.usesSparseStorage = uses_ct_sparse_storage_v<Arg>;
18 desc.storageKnown =
true;
24 auto ChunkIterTypedOps::view_any(
const ChunkIterImpl& self) {
25#if GAIA_ASSERT_ENABLED
26 self.assert_term_access(ChunkIterTypedOps::template term_desc<T>(self).termId);
28 using U =
typename actual_type_t<T>::Type;
29 if constexpr (std::is_same_v<U, Entity> || mem::is_soa_layout_v<U>)
30 return self.m_pChunk->template view<T>(self.from(), self.to());
31 else if constexpr (uses_ct_sparse_storage_v<T>) {
32 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
33 auto* pWorld =
const_cast<World*
>(self.world());
34 return EntityTermViewGetSparse<U>{
35 self.m_pChunk->entity_view().data() + self.from(), pWorld,
36 world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId, self.size()};
38 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
39 const auto id = desc.usesSparseStorage ? desc.termId : EntityBad;
42 return EntityTermViewGet<U>::entity(
43 self.m_pChunk->entity_view().data() + self.from(),
const_cast<World*
>(self.world()),
id, self.size());
45 auto* pData =
reinterpret_cast<const U*
>(self.m_pChunk->template view<T>(self.from(), self.to()).data());
46 return EntityTermViewGet<U>::pointer(pData, self.size());
51 auto ChunkIterTypedOps::view_any(ChunkIterImpl& self, uint32_t termIdx) {
52#if GAIA_ASSERT_ENABLED
53 self.assert_term_access(termIdx, ChunkIterTypedOps::template term_desc<T>(self).termId);
55 using U =
typename actual_type_t<T>::Type;
57 if constexpr (mem::is_soa_layout_v<U>) {
58 const auto compIdx = self.m_pCompIndices[termIdx];
59 if (compIdx == 0xFF) {
60 const auto* pEntities = self.m_pChunk->entity_view().data() + self.from();
61 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
62 GAIA_ASSERT(desc.termId != EntityBad);
63 return SoATermViewGet<U>{
nullptr, 0, pEntities,
const_cast<World*
>(self.world()),
64 desc.termId, 0, self.size()};
67 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
68 return SoATermViewGet<U>{
69 self.m_pChunk->comp_ptr(compIdx),
70 self.m_pChunk->capacity(),
72 const_cast<World*
>(self.world()),
76 }
else if constexpr (uses_ct_sparse_storage_v<T>) {
77 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
78 auto* pWorld =
const_cast<World*
>(self.world());
79 return EntityTermViewGetSparse<U>{
80 self.m_pChunk->entity_view().data() + self.from(), pWorld,
81 world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId, self.size()};
83 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
84 const auto compIdx = self.m_pCompIndices[termIdx];
85 if (desc.usesSparseStorage)
86 return EntityTermViewGet<U>::entity(
87 self.m_pChunk->entity_view().data() + self.from(),
const_cast<World*
>(self.world()), desc.termId,
90 if (compIdx == 0xFF) {
91 GAIA_ASSERT(desc.termId != EntityBad);
92 if (!self.m_inheritedData.empty()) {
93 const auto* pInheritedValue =
reinterpret_cast<const U*
>(self.m_inheritedData[termIdx]);
94 if (pInheritedValue !=
nullptr)
95 return EntityTermViewGet<U>::inherited(pInheritedValue, self.size());
97 if (world_term_uses_inherit_policy(*self.world(), desc.termId)) {
98 return EntityTermViewGet<U>::entity_chunk_stable(
99 self.m_pChunk->entity_view().data() + self.from(), self.m_pChunk,
const_cast<World*
>(self.world()),
100 desc.termId, self.from(), self.size());
102 return EntityTermViewGet<U>::entity(
103 self.m_pChunk->entity_view().data() + self.from(),
const_cast<World*
>(self.world()), desc.termId,
106 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
108 auto* pData =
reinterpret_cast<const U*
>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
109 return EntityTermViewGet<U>::pointer(pData, self.size());
113 template <
typename T>
114 auto ChunkIterTypedOps::view(
const ChunkIterImpl& self) {
115#if GAIA_ASSERT_ENABLED
116 self.assert_term_access(ChunkIterTypedOps::template term_desc<T>(self).termId);
118 using U =
typename actual_type_t<T>::Type;
119 if constexpr (std::is_same_v<U, Entity>)
120 return self.m_pChunk->template view<T>(self.from(), self.to());
121 else if constexpr (mem::is_soa_layout_v<U>) {
122 const auto view = self.m_pChunk->template view<T>(self.from(), self.to());
123 return SoATermViewGetPointer<U>{(
const uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
125 auto* pData =
reinterpret_cast<const U*
>(self.m_pChunk->template view<T>(self.from(), self.to()).data());
126 return EntityTermViewGetPointer<U>{pData, self.size()};
130 template <
typename T>
131 auto ChunkIterTypedOps::view(
const ChunkIterImpl& self, uint32_t termIdx) {
132#if GAIA_ASSERT_ENABLED
133 self.assert_term_access(termIdx, ChunkIterTypedOps::template term_desc<T>(self).termId);
135 using U =
typename actual_type_t<T>::Type;
136 const auto compIdx = self.m_pCompIndices[termIdx];
137 GAIA_ASSERT(compIdx != 0xFF);
139 if constexpr (mem::is_soa_layout_v<U>)
140 return SoATermViewGetPointer<U>{
141 self.m_pChunk->comp_ptr(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
143 auto* pData =
reinterpret_cast<const U*
>(self.m_pChunk->comp_ptr(compIdx, self.from()));
144 return EntityTermViewGetPointer<U>{pData, self.size()};
148 template <
typename T>
149 auto ChunkIterTypedOps::view_any_mut(ChunkIterImpl& self) {
150#if GAIA_ASSERT_ENABLED
151 self.assert_term_access(ChunkIterTypedOps::template term_desc<T>(self).termId);
153 using U =
typename actual_type_t<T>::Type;
154 static_assert(!std::is_same_v<U, Entity>,
"Modifying chunk entities via view_mut is forbidden");
155 if constexpr (mem::is_soa_layout_v<U>) {
156 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
157 const bool tracked = self.touch_term_desc(desc);
158 GAIA_ASSERT(tracked);
161 return self.m_pChunk->template view_mut<T>(self.from(), self.to());
162 return self.m_pChunk->template sview_mut<T>(self.from(), self.to());
163 }
else if constexpr (uses_ct_sparse_storage_v<T>) {
164 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
165 if (!self.touch_term(desc.termId))
166 return EntityTermViewSetSparse<U>{};
167 auto* pWorld =
const_cast<World*
>(self.world());
168 return EntityTermViewSetSparse<U>{
169 self.entity_snapshot(), pWorld, world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId,
172 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
173 const auto id = desc.usesSparseStorage ? desc.termId : EntityBad;
175 if (
id != EntityBad) {
176 if (!self.touch_term(
id))
177 return self.template entity_view_set_empty<U>(self.m_writeIm);
178 return self.template entity_view_set<U>(
id, self.m_writeIm);
181 if (!self.touch_term_desc(desc))
182 return self.template entity_view_set_empty<U>(self.m_writeIm);
184 reinterpret_cast<U*
>((self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
185 : self.m_pChunk->template sview_mut<T>(self.from(), self.to()))
187 return EntityTermViewSet<U>::pointer(pData, self.size());
191 template <
typename T>
192 auto ChunkIterTypedOps::view_mut(ChunkIterImpl& self) {
193#if GAIA_ASSERT_ENABLED
194 self.assert_term_access(ChunkIterTypedOps::template term_desc<T>(self).termId);
196 using U =
typename actual_type_t<T>::Type;
197 static_assert(!std::is_same_v<U, Entity>,
"Modifying chunk entities via view_mut is forbidden");
198 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
199 const bool tracked = self.touch_term_desc(desc);
200 if constexpr (mem::is_soa_layout_v<U>) {
202 return SoATermViewSetPointer<U>{};
203 auto view = self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
204 : self.m_pChunk->template sview_mut<T>(self.from(), self.to());
205 return SoATermViewSetPointer<U>{(uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
208 return EntityTermViewSetPointer<U>{};
210 reinterpret_cast<U*
>((self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
211 : self.m_pChunk->template sview_mut<T>(self.from(), self.to()))
213 return EntityTermViewSetPointer<U>{pData, self.size()};
217 template <
typename T>
218 auto ChunkIterTypedOps::view_mut(ChunkIterImpl& self, uint32_t termIdx) {
219#if GAIA_ASSERT_ENABLED
220 self.assert_term_access(termIdx, ChunkIterTypedOps::template term_desc<T>(self).termId);
222 using U =
typename actual_type_t<T>::Type;
223 static_assert(!std::is_same_v<U, Entity>,
"Modifying chunk entities via view_mut is forbidden");
224 const auto compIdx = self.m_pCompIndices[termIdx];
225 GAIA_ASSERT(compIdx != 0xFF);
226 self.touch_comp_idx(compIdx);
228 if constexpr (mem::is_soa_layout_v<U>) {
230 self.m_pChunk->update_world_version(compIdx);
231 return SoATermViewSetPointer<U>{
232 self.m_pChunk->comp_ptr_mut(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
235 self.m_pChunk->update_world_version(compIdx);
236 auto* pData =
reinterpret_cast<U*
>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
237 return EntityTermViewSetPointer<U>{pData, self.size()};
241 template <
typename T>
242 auto ChunkIterTypedOps::view_any_mut(ChunkIterImpl& self, uint32_t termIdx) {
243#if GAIA_ASSERT_ENABLED
244 self.assert_term_access(termIdx, ChunkIterTypedOps::template term_desc<T>(self).termId);
246 using U =
typename actual_type_t<T>::Type;
248 if constexpr (mem::is_soa_layout_v<U>) {
249 const auto compIdx = self.m_pCompIndices[termIdx];
250 if (compIdx == 0xFF) {
251 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
252 GAIA_ASSERT(desc.termId != EntityBad);
253 if (!self.touch_term(desc.termId))
254 return self.template entity_soa_view_set_empty<U>(self.m_writeIm);
255 return self.template entity_soa_view_set<U>(desc.termId, self.m_writeIm);
258 GAIA_ASSERT(compIdx < self.m_pChunk->comp_rec_view().size());
259 self.touch_comp_idx(compIdx);
261 self.m_pChunk->update_world_version(compIdx);
262 return SoATermViewSet<U>{
263 self.m_pChunk->comp_ptr_mut(compIdx),
264 self.m_pChunk->capacity(),
271 }
else if constexpr (uses_ct_sparse_storage_v<T>) {
272 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
273 if (!self.touch_term(desc.termId))
274 return EntityTermViewSetSparse<U>{};
275 auto* pWorld =
const_cast<World*
>(self.world());
276 return EntityTermViewSetSparse<U>{
277 self.entity_snapshot(), pWorld, world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId,
280 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
281 const auto compIdx = self.m_pCompIndices[termIdx];
282 if (desc.usesSparseStorage || compIdx == 0xFF) {
283 GAIA_ASSERT(desc.termId != EntityBad);
284 if (!self.touch_term(desc.termId))
285 return self.template entity_view_set_empty<U>(self.m_writeIm);
286 return self.template entity_view_set<U>(desc.termId, self.m_writeIm);
288 GAIA_ASSERT(compIdx < self.m_pChunk->comp_rec_view().size());
290 self.touch_comp_idx(compIdx);
292 self.m_pChunk->update_world_version(compIdx);
294 auto* pData =
reinterpret_cast<U*
>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
295 return EntityTermViewSet<U>::pointer(pData, self.size());
299 template <
typename T>
300 auto ChunkIterTypedOps::sview_any_mut(ChunkIterImpl& self) {
301#if GAIA_ASSERT_ENABLED
302 self.assert_term_access(ChunkIterTypedOps::template term_desc<T>(self).termId);
304 using U =
typename actual_type_t<T>::Type;
305 static_assert(!std::is_same_v<U, Entity>,
"Modifying chunk entities via sview_mut is forbidden");
306 if constexpr (mem::is_soa_layout_v<U>)
307 return self.m_pChunk->template sview_mut<T>(self.from(), self.to());
308 else if constexpr (uses_ct_sparse_storage_v<T>) {
309 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
310 auto* pWorld =
const_cast<World*
>(self.world());
311 return EntityTermViewSetSparse<U>{
312 self.entity_snapshot(), pWorld, world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId,
315 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
316 const auto id = desc.usesSparseStorage ? desc.termId : EntityBad;
319 return self.template entity_view_set<U>(
id,
false);
321 auto* pData =
reinterpret_cast<U*
>(self.m_pChunk->template sview_mut<T>(self.from(), self.to()).data());
322 return EntityTermViewSet<U>::pointer(pData, self.size());
326 template <
typename T>
327 auto ChunkIterTypedOps::sview_mut(ChunkIterImpl& self) {
328#if GAIA_ASSERT_ENABLED
329 self.assert_term_access(ChunkIterTypedOps::template term_desc<T>(self).termId);
331 using U =
typename actual_type_t<T>::Type;
332 static_assert(!std::is_same_v<U, Entity>,
"Modifying chunk entities via sview_mut is forbidden");
333 if constexpr (mem::is_soa_layout_v<U>) {
334 auto view = self.m_pChunk->template sview_mut<T>(self.from(), self.to());
335 return SoATermViewSetPointer<U>{(uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
337 auto* pData =
reinterpret_cast<U*
>(self.m_pChunk->template sview_mut<T>(self.from(), self.to()).data());
338 return EntityTermViewSetPointer<U>{pData, self.size()};
342 template <
typename T>
343 auto ChunkIterTypedOps::sview_mut(ChunkIterImpl& self, uint32_t termIdx) {
344#if GAIA_ASSERT_ENABLED
345 self.assert_term_access(termIdx, ChunkIterTypedOps::template term_desc<T>(self).termId);
347 using U =
typename actual_type_t<T>::Type;
348 static_assert(!std::is_same_v<U, Entity>,
"Modifying chunk entities via sview_mut is forbidden");
349 const auto compIdx = self.m_pCompIndices[termIdx];
350 GAIA_ASSERT(compIdx != 0xFF);
352 if constexpr (mem::is_soa_layout_v<U>)
353 return SoATermViewSetPointer<U>{
354 self.m_pChunk->comp_ptr_mut(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
356 auto* pData =
reinterpret_cast<U*
>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
357 return EntityTermViewSetPointer<U>{pData, self.size()};
361 template <
typename T>
362 auto ChunkIterTypedOps::sview_any_mut(ChunkIterImpl& self, uint32_t termIdx) {
363#if GAIA_ASSERT_ENABLED
364 self.assert_term_access(termIdx, ChunkIterTypedOps::template term_desc<T>(self).termId);
366 using U =
typename actual_type_t<T>::Type;
368 if constexpr (mem::is_soa_layout_v<U>) {
369 const auto compIdx = self.m_pCompIndices[termIdx];
370 if (compIdx == 0xFF) {
371 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
372 GAIA_ASSERT(desc.termId != EntityBad);
373 return self.template entity_soa_view_set<U>(desc.termId,
false);
376 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
377 return SoATermViewSet<U>{
378 self.m_pChunk->comp_ptr_mut(compIdx),
379 self.m_pChunk->capacity(),
386 }
else if constexpr (uses_ct_sparse_storage_v<T>) {
387 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
388 auto* pWorld =
const_cast<World*
>(self.world());
389 return EntityTermViewSetSparse<U>{
390 self.entity_snapshot(), pWorld, world_typed_sparse_store_ptr<U>(*pWorld, desc.termId), desc.termId,
393 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
394 const auto compIdx = self.m_pCompIndices[termIdx];
395 if (desc.usesSparseStorage || compIdx == 0xFF) {
396 GAIA_ASSERT(desc.termId != EntityBad);
397 return self.template entity_view_set<U>(desc.termId,
false);
399 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
401 auto* pData =
reinterpret_cast<U*
>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
402 return EntityTermViewSet<U>::pointer(pData, self.size());