2#include "gaia/config/config.h"
8#include "gaia/ecs/api.h"
9#include "gaia/ecs/archetype.h"
10#include "gaia/ecs/chunk.h"
11#include "gaia/ecs/command_buffer_fwd.h"
12#include "gaia/ecs/component.h"
13#include "gaia/ecs/component_cache_item.h"
14#include "gaia/ecs/component_cursor.h"
15#include "gaia/ecs/id.h"
16#include "gaia/ecs/query_common.h"
17#include "gaia/mem/data_layout_policy.h"
28 const void* (*funcGet)(
const void*,
Entity) =
nullptr;
30 void* (*funcMut)(
void*,
Entity) =
nullptr;
40 void* world_typed_sparse_store_ptr(
World& world,
Entity component);
42 const T& world_typed_sparse_store_get(
const void* pStore,
Entity entity);
44 T& world_typed_sparse_store_mut(
void* pStore,
Entity entity);
46 bool world_typed_sparse_store_has(
const void* pStore,
Entity entity);
48 decltype(
auto) world_query_entity_arg_by_id_cached_const(
52 void world_init_query_entity_arg_by_id_chunk_stable_const(
54 const std::remove_cv_t<std::remove_reference_t<T>>*& pDataInherited);
56 const std::remove_cv_t<std::remove_reference_t<T>>*
58 bool world_term_uses_inherit_policy(
const World& world,
Entity term);
63 enum class Constraints : uint8_t {
77 Entity termId = EntityBad;
78 bool isEntity =
false;
79 bool usesSparseStorage =
false;
80 bool storageKnown =
false;
83 struct ChunkIterTypedOps {
85 static IterTermDesc term_desc(
const ChunkIterImpl& self);
87 static auto view_any(
const ChunkIterImpl& self);
89 static auto view_any(ChunkIterImpl& self, uint32_t termIdx);
91 static auto view(
const ChunkIterImpl& self);
93 static auto view(
const ChunkIterImpl& self, uint32_t termIdx);
95 static auto view_any_mut(ChunkIterImpl& self);
97 static auto view_mut(ChunkIterImpl& self);
99 static auto view_mut(ChunkIterImpl& self, uint32_t termIdx);
100 template <
typename T>
101 static auto view_any_mut(ChunkIterImpl& self, uint32_t termIdx);
102 template <
typename T>
103 static auto sview_any_mut(ChunkIterImpl& self);
104 template <
typename T>
105 static auto sview_mut(ChunkIterImpl& self);
106 template <
typename T>
107 static auto sview_mut(ChunkIterImpl& self, uint32_t termIdx);
108 template <
typename T>
109 static auto sview_any_mut(ChunkIterImpl& self, uint32_t termIdx);
113 const Archetype* pArchetype =
nullptr;
114 Chunk* pChunk =
nullptr;
121 struct RawTermViewGet {
122 const uint8_t* pData =
nullptr;
123 uint32_t elemSize = 0;
125 uint32_t flags = ComponentRawViewFlag_None;
127 GAIA_NODISCARD ComponentRawView operator[](
size_t idx)
const {
128 GAIA_ASSERT(idx < cnt);
129 if ((flags & ComponentRawViewFlag_Valid) == 0 || idx >= cnt)
132 return {
nullptr, 0, ComponentRawViewFlag_Valid};
134 return {pData + (uintptr_t)elemSize * idx, elemSize, ComponentRawViewFlag_Valid};
137 GAIA_NODISCARD
constexpr size_t size() const noexcept {
143 struct RawTermViewSet {
144 uint8_t* pData =
nullptr;
145 uint32_t elemSize = 0;
147 uint32_t flags = ComponentRawViewFlag_None;
149 GAIA_NODISCARD ComponentRawMutView operator[](
size_t idx)
const {
150 GAIA_ASSERT(idx < cnt);
151 if ((flags & ComponentRawViewFlag_Valid) == 0 || idx >= cnt)
154 return {
nullptr, 0, ComponentRawViewFlag_Valid};
156 return {pData + (uintptr_t)elemSize * idx, elemSize, ComponentRawViewFlag_Valid};
159 GAIA_NODISCARD
constexpr size_t size() const noexcept {
166 struct RawTermViewGetEntity {
167 const Entity* pEntities =
nullptr;
168 const World* pWorld =
nullptr;
169 Entity component = EntityBad;
171 RawSparseStoreOps sparse{};
173 GAIA_NODISCARD ComponentRawView operator[](
size_t idx)
const {
174 GAIA_ASSERT(idx < cnt);
175 if (pEntities ==
nullptr || pWorld ==
nullptr || component == EntityBad || idx >= cnt)
178 const auto entity = pEntities[idx];
179 if (sparse.pStore !=
nullptr) {
180 if (sparse.funcHas(sparse.pStore, entity))
181 return {sparse.funcGet(sparse.pStore, entity), sparse.elemSize, ComponentRawViewFlag_Valid};
184 return world_get_raw(*pWorld, entity, component);
187 GAIA_NODISCARD
constexpr size_t size() const noexcept {
194 struct RawTermViewSetEntity {
195 const Entity* pEntities =
nullptr;
196 World* pWorld =
nullptr;
197 Entity component = EntityBad;
199 RawSparseStoreOps sparse{};
201 GAIA_NODISCARD ComponentRawMutView operator[](
size_t idx)
const {
202 GAIA_ASSERT(idx < cnt);
203 if (pEntities ==
nullptr || pWorld ==
nullptr || component == EntityBad || idx >= cnt)
206 const auto entity = pEntities[idx];
207 if (sparse.pStore !=
nullptr)
209 sparse.funcMut(
const_cast<void*
>(sparse.pStore), entity), sparse.elemSize, ComponentRawViewFlag_Valid};
211 return world_mut_raw(*pWorld, entity, component);
214 GAIA_NODISCARD
constexpr size_t size() const noexcept {
221 template <
typename U>
222 struct EntityTermViewGetPointer {
223 const U* pData =
nullptr;
226 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx)
const {
227 GAIA_ASSERT(idx < cnt);
231 GAIA_NODISCARD
constexpr size_t size() const noexcept {
235 GAIA_NODISCARD
const U* data() const noexcept {
242 template <
typename U>
243 struct EntityTermViewGetEntity {
244 const Entity* pEntities =
nullptr;
245 World* pWorld =
nullptr;
246 Entity
id = EntityBad;
248 mutable const Archetype* pLastArchetype =
nullptr;
249 mutable Entity cachedOwner = EntityBad;
250 mutable bool cachedDirect =
false;
252 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx)
const {
253 GAIA_ASSERT(idx < cnt);
254 return world_query_entity_arg_by_id_cached_const<const U&>(
255 *pWorld, pEntities[idx],
id, pLastArchetype, cachedOwner, cachedDirect);
258 GAIA_NODISCARD
constexpr size_t size() const noexcept {
262 GAIA_NODISCARD
const U* data() const noexcept {
269 template <
typename U>
270 struct EntityTermViewSetPointer {
274 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx) {
275 GAIA_ASSERT(idx < cnt);
279 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx)
const {
280 GAIA_ASSERT(idx < cnt);
281 return static_cast<const U&
>(pData[idx]);
284 GAIA_NODISCARD
constexpr size_t size() const noexcept {
288 GAIA_NODISCARD U* data() noexcept {
292 GAIA_NODISCARD
const U* data() const noexcept {
299 template <
typename U,
bool WriteIm>
300 struct EntityTermViewSetEntity {
301 const Entity* pEntities =
nullptr;
302 World* pWorld =
nullptr;
303 Entity
id = EntityBad;
306 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx) {
307 GAIA_ASSERT(idx < cnt);
308 if constexpr (WriteIm)
309 return world_query_entity_arg_by_id<U&>(*pWorld, pEntities[idx],
id);
311 return world_query_entity_arg_by_id_raw<U&>(*pWorld, pEntities[idx],
id);
314 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx)
const {
315 GAIA_ASSERT(idx < cnt);
316 return world_query_entity_arg_by_id<const U&>(*pWorld, pEntities[idx],
id);
319 GAIA_NODISCARD
constexpr size_t size() const noexcept {
323 GAIA_NODISCARD U* data() noexcept {
327 GAIA_NODISCARD
const U* data() const noexcept {
333 template <
typename U>
334 struct EntityTermViewGetSparse {
335 const Entity* pEntities =
nullptr;
336 World* pWorld =
nullptr;
337 const void* pStore =
nullptr;
338 Entity
id = EntityBad;
341 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx)
const {
342 GAIA_ASSERT(idx < cnt);
343 const auto entity = pEntities[idx];
344 if (world_typed_sparse_store_has<U>(pStore, entity))
345 return world_typed_sparse_store_get<U>(pStore, entity);
346 return world_query_entity_arg_by_id<const U&>(*pWorld, entity,
id);
349 GAIA_NODISCARD
constexpr size_t size() const noexcept {
353 GAIA_NODISCARD
const U* data() const noexcept {
359 template <
typename U>
360 struct EntityTermViewSetSparse {
361 const Entity* pEntities =
nullptr;
362 World* pWorld =
nullptr;
363 void* pStore =
nullptr;
364 Entity
id = EntityBad;
367 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx) {
368 GAIA_ASSERT(idx < cnt);
369 const auto entity = pEntities[idx];
370 if (world_typed_sparse_store_has<U>(pStore, entity))
371 return world_typed_sparse_store_mut<U>(pStore, entity);
372 return world_query_entity_arg_by_id_raw<U&>(*pWorld, entity,
id);
375 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx)
const {
376 GAIA_ASSERT(idx < cnt);
377 const auto entity = pEntities[idx];
378 if (world_typed_sparse_store_has<U>(pStore, entity))
379 return world_typed_sparse_store_get<U>(pStore, entity);
380 return world_query_entity_arg_by_id<const U&>(*pWorld, entity,
id);
383 GAIA_NODISCARD
constexpr size_t size() const noexcept {
387 GAIA_NODISCARD U* data() noexcept {
391 GAIA_NODISCARD
const U* data() const noexcept {
398 template <
typename U>
399 struct EntityTermViewGet {
400 const U* pData =
nullptr;
401 const Entity* pEntities =
nullptr;
402 World* pWorld =
nullptr;
403 Entity
id = EntityBad;
405 const U* pDataInherited =
nullptr;
406 mutable const Archetype* pLastArchetype =
nullptr;
407 mutable Entity cachedOwner = EntityBad;
408 mutable bool cachedDirect =
false;
410 static EntityTermViewGet pointer(
const U* pData, uint32_t cnt) {
411 return {pData,
nullptr,
nullptr, EntityBad, cnt,
nullptr,
nullptr, EntityBad,
false};
414 static EntityTermViewGet entity(
const Entity* pEntities, World* pWorld, Entity
id, uint32_t cnt) {
415 return {
nullptr, pEntities, pWorld, id, cnt,
nullptr,
nullptr, EntityBad,
false};
418 static EntityTermViewGet inherited(
const U* pDataInherited, uint32_t cnt) {
419 return {
nullptr,
nullptr,
nullptr, EntityBad, cnt, pDataInherited,
nullptr, EntityBad,
false};
422 static EntityTermViewGet entity_chunk_stable(
423 const Entity* pEntities,
const Chunk* pChunk, World* pWorld, Entity
id, uint16_t rowBase, uint32_t cnt) {
424 uint32_t compIdx = BadIndex;
425 const U* pDataInherited =
nullptr;
427 world_init_query_entity_arg_by_id_chunk_stable_const<U>(
428 *pWorld, *pChunk, pEntities,
id, direct, compIdx, pDataInherited);
429 const U* pData =
nullptr;
431 pData =
reinterpret_cast<const U*
>(pChunk->comp_ptr(compIdx, rowBase));
433 return {pData,
nullptr, pWorld, id, cnt, pDataInherited,
nullptr, EntityBad,
false};
436 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx)
const {
437 GAIA_ASSERT(idx < cnt);
438 if (pData !=
nullptr)
440 if (pDataInherited !=
nullptr) {
441 GAIA_ASSERT(pDataInherited !=
nullptr);
442 return *pDataInherited;
445 return world_query_entity_arg_by_id_cached_const<const U&>(
446 *pWorld, pEntities[idx],
id, pLastArchetype, cachedOwner, cachedDirect);
449 GAIA_NODISCARD
constexpr size_t size() const noexcept {
453 GAIA_NODISCARD
const U* data() const noexcept {
460 template <
typename U>
461 struct EntityTermViewSet {
463 const Entity* pEntities =
nullptr;
464 World* pWorld =
nullptr;
465 Entity
id = EntityBad;
469 static EntityTermViewSet pointer(U* pData, uint32_t cnt) {
470 return {pData,
nullptr,
nullptr, EntityBad, cnt,
true};
473 static EntityTermViewSet
474 entity(
const Entity* pEntities, World* pWorld, Entity
id, uint32_t cnt,
bool writeIm =
true) {
475 return {
nullptr, pEntities, pWorld, id, cnt, writeIm};
478 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx) {
479 GAIA_ASSERT(idx < cnt);
480 if (pData !=
nullptr)
484 return EntityTermViewSetEntity<U, true>{pEntities, pWorld, id, cnt}[idx];
485 return EntityTermViewSetEntity<U, false>{pEntities, pWorld, id, cnt}[idx];
488 GAIA_NODISCARD
decltype(
auto)
operator[](
size_t idx)
const {
489 GAIA_ASSERT(idx < cnt);
490 if (pData !=
nullptr)
491 return static_cast<const U&
>(pData[idx]);
493 return world_query_entity_arg_by_id<const U&>(*pWorld, pEntities[idx],
id);
496 GAIA_NODISCARD
constexpr size_t size() const noexcept {
500 GAIA_NODISCARD U* data() noexcept {
504 GAIA_NODISCARD
const U* data() const noexcept {
511 template <
typename U>
512 struct SoATermRowWriteProxyPointer {
513 using raw_view_policy = mem::data_view_policy_soa<U::gaia_Data_Layout, U>;
515 uint8_t* pData =
nullptr;
516 uint32_t dataSize = 0;
519 GAIA_NODISCARD
operator U()
const {
520 return raw_view_policy::get(std::span<const uint8_t>{pData, dataSize}, idx);
523 SoATermRowWriteProxyPointer& operator=(
const U& value) {
524 raw_view_policy::set(std::span<uint8_t>{pData, dataSize}, idx) = value;
531 template <
typename U,
bool WriteIm>
532 struct SoATermRowWriteProxyEntity {
533 const Entity* pEntities =
nullptr;
534 World* pWorld =
nullptr;
535 Entity
id = EntityBad;
538 GAIA_NODISCARD
operator U()
const {
539 return world_query_entity_arg_by_id<const U&>(*pWorld, pEntities[idx],
id);
542 SoATermRowWriteProxyEntity& operator=(
const U& value) {
543 if constexpr (WriteIm)
544 world_query_entity_arg_by_id<U&>(*pWorld, pEntities[idx],
id) = value;
546 world_query_entity_arg_by_id_raw<U&>(*pWorld, pEntities[idx],
id) = value;
553 template <
typename U,
size_t Item>
554 struct SoATermFieldReadProxyPointer {
555 using view_policy = mem::data_view_policy_soa_get<U::gaia_Data_Layout, U>;
556 using value_type =
typename view_policy::template data_view_policy_idx_info<Item>::const_value_type;
558 const value_type* pData =
nullptr;
561 GAIA_NODISCARD value_type operator[](
size_t idx)
const {
562 GAIA_ASSERT(idx < cnt);
566 GAIA_NODISCARD
constexpr size_t size() const noexcept {
573 template <
typename U,
size_t Item>
574 struct SoATermFieldReadProxyEntity {
575 using view_policy = mem::data_view_policy_soa_get<U::gaia_Data_Layout, U>;
576 using value_type =
typename view_policy::template data_view_policy_idx_info<Item>::const_value_type;
578 const Entity* pEntities =
nullptr;
579 World* pWorld =
nullptr;
580 Entity
id = EntityBad;
583 GAIA_NODISCARD value_type operator[](
size_t idx)
const {
584 GAIA_ASSERT(idx < cnt);
585 const U value = world_query_entity_arg_by_id<const U&>(*pWorld, pEntities[idx],
id);
586 return std::get<Item>(meta::struct_to_tuple(value));
589 GAIA_NODISCARD
constexpr size_t size() const noexcept {
596 template <
typename U,
size_t Item>
597 struct SoATermFieldWriteProxyPointer {
598 using view_policy = mem::data_view_policy_soa_set<U::gaia_Data_Layout, U>;
599 using value_type =
typename view_policy::template data_view_policy_idx_info<Item>::value_type;
601 value_type* pData =
nullptr;
604 GAIA_NODISCARD value_type& operator[](
size_t idx) {
605 GAIA_ASSERT(idx < cnt);
609 GAIA_NODISCARD
const value_type& operator[](
size_t idx)
const {
610 GAIA_ASSERT(idx < cnt);
614 GAIA_NODISCARD
constexpr size_t size() const noexcept {
621 template <
typename U,
size_t Item,
bool WriteIm>
622 struct SoATermFieldWriteProxyEntity {
623 using view_policy = mem::data_view_policy_soa_set<U::gaia_Data_Layout, U>;
624 using value_type =
typename view_policy::template data_view_policy_idx_info<Item>::value_type;
627 struct ElementProxy {
628 const Entity* pEntities =
nullptr;
629 World* pWorld =
nullptr;
630 Entity
id = EntityBad;
633 GAIA_NODISCARD
operator value_type()
const {
634 const U value = world_query_entity_arg_by_id<const U&>(*pWorld, pEntities[idx],
id);
635 return std::get<Item>(meta::struct_to_tuple(value));
638 ElementProxy& operator=(
const value_type& value) {
639 auto data = world_query_entity_arg_by_id<const U&>(*pWorld, pEntities[idx],
id);
640 auto tuple = meta::struct_to_tuple(data);
641 std::get<Item>(tuple) = value;
642 if constexpr (WriteIm)
643 world_query_entity_arg_by_id<U&>(*pWorld, pEntities[idx],
id) = meta::tuple_to_struct<U>(GAIA_MOV(tuple));
645 world_query_entity_arg_by_id_raw<U&>(*pWorld, pEntities[idx],
id) =
646 meta::tuple_to_struct<U>(GAIA_MOV(tuple));
650 template <
typename V>
651 ElementProxy& operator+=(V&& value) {
652 const value_type current =
operator value_type();
653 return operator=(current + GAIA_FWD(value));
656 template <
typename V>
657 ElementProxy& operator-=(V&& value) {
658 const value_type current =
operator value_type();
659 return operator=(current - GAIA_FWD(value));
662 template <
typename V>
663 ElementProxy& operator*=(V&& value) {
664 const value_type current =
operator value_type();
665 return operator=(current * GAIA_FWD(value));
668 template <
typename V>
669 ElementProxy& operator/=(V&& value) {
670 const value_type current =
operator value_type();
671 return operator=(current / GAIA_FWD(value));
675 const Entity* pEntities =
nullptr;
676 World* pWorld =
nullptr;
677 Entity
id = EntityBad;
680 GAIA_NODISCARD ElementProxy operator[](
size_t idx)
const {
681 GAIA_ASSERT(idx < cnt);
682 return ElementProxy{pEntities, pWorld, id, (uint32_t)idx};
685 GAIA_NODISCARD
constexpr size_t size() const noexcept {
692 template <
typename U>
693 struct SoATermViewGetPointer {
694 using raw_view_policy = mem::data_view_policy_soa<U::gaia_Data_Layout, U>;
695 using read_view_policy = mem::data_view_policy_soa_get<U::gaia_Data_Layout, U>;
697 const uint8_t* pData =
nullptr;
698 uint32_t dataSize = 0;
699 uint32_t idxBase = 0;
702 GAIA_NODISCARD U operator[](
size_t idx)
const {
703 GAIA_ASSERT(idx < cnt);
704 return raw_view_policy::get(std::span<const uint8_t>{pData, dataSize}, idxBase + idx);
707 template <
size_t Item>
708 GAIA_NODISCARD
auto get()
const {
709 const auto field = read_view_policy{std::span<const uint8_t>{pData, dataSize}}.template get<Item>();
710 return SoATermFieldReadProxyPointer<U, Item>{field.data() + idxBase, cnt};
713 GAIA_NODISCARD
constexpr size_t size() const noexcept {
720 template <
typename U>
721 struct SoATermViewGetEntity {
722 const Entity* pEntities =
nullptr;
723 World* pWorld =
nullptr;
724 Entity
id = EntityBad;
727 GAIA_NODISCARD U operator[](
size_t idx)
const {
728 GAIA_ASSERT(idx < cnt);
729 return world_query_entity_arg_by_id<const U&>(*pWorld, pEntities[idx],
id);
732 template <
size_t Item>
733 GAIA_NODISCARD
auto get()
const {
734 return SoATermFieldReadProxyEntity<U, Item>{pEntities, pWorld, id, cnt};
737 GAIA_NODISCARD
constexpr size_t size() const noexcept {
744 template <
typename U>
745 struct SoATermViewSetPointer {
746 using raw_view_policy = mem::data_view_policy_soa<U::gaia_Data_Layout, U>;
747 using read_view_policy = mem::data_view_policy_soa_get<U::gaia_Data_Layout, U>;
748 using write_view_policy = mem::data_view_policy_soa_set<U::gaia_Data_Layout, U>;
750 uint8_t* pData =
nullptr;
751 uint32_t dataSize = 0;
752 uint32_t idxBase = 0;
755 GAIA_NODISCARD
auto operator[](
size_t idx) {
756 GAIA_ASSERT(idx < cnt);
757 return SoATermRowWriteProxyPointer<U>{pData, dataSize, idxBase + (uint32_t)idx};
760 GAIA_NODISCARD U operator[](
size_t idx)
const {
761 GAIA_ASSERT(idx < cnt);
762 return raw_view_policy::get(std::span<const uint8_t>{pData, dataSize}, idxBase + idx);
765 template <
size_t Item>
766 GAIA_NODISCARD
auto get()
const {
767 const auto field = read_view_policy{std::span<const uint8_t>{pData, dataSize}}.template get<Item>();
768 return SoATermFieldReadProxyPointer<U, Item>{field.data() + idxBase, cnt};
771 template <
size_t Item>
772 GAIA_NODISCARD
auto set() {
773 auto field = write_view_policy{std::span<uint8_t>{pData, dataSize}}.template set<Item>();
774 return SoATermFieldWriteProxyPointer<U, Item>{field.data() + idxBase, cnt};
777 GAIA_NODISCARD
constexpr size_t size() const noexcept {
784 template <
typename U,
bool WriteIm>
785 struct SoATermViewSetEntity {
786 const Entity* pEntities =
nullptr;
787 World* pWorld =
nullptr;
788 Entity
id = EntityBad;
791 GAIA_NODISCARD
auto operator[](
size_t idx) {
792 GAIA_ASSERT(idx < cnt);
793 return SoATermRowWriteProxyEntity<U, WriteIm>{pEntities, pWorld, id, (uint32_t)idx};
796 GAIA_NODISCARD U operator[](
size_t idx)
const {
797 GAIA_ASSERT(idx < cnt);
798 return world_query_entity_arg_by_id<const U&>(*pWorld, pEntities[idx],
id);
801 template <
size_t Item>
802 GAIA_NODISCARD
auto get()
const {
803 return SoATermFieldReadProxyEntity<U, Item>{pEntities, pWorld, id, cnt};
806 template <
size_t Item>
807 GAIA_NODISCARD
auto set() {
808 return SoATermFieldWriteProxyEntity<U, Item, WriteIm>{pEntities, pWorld, id, cnt};
811 GAIA_NODISCARD
constexpr size_t size() const noexcept {
818 template <
typename U>
819 struct SoATermRowWriteProxy {
820 uint8_t* pData =
nullptr;
821 uint32_t dataSize = 0;
822 const Entity* pEntities =
nullptr;
823 World* pWorld =
nullptr;
824 Entity
id = EntityBad;
828 GAIA_NODISCARD
operator U()
const {
829 if (pData !=
nullptr)
830 return (U)SoATermRowWriteProxyPointer<U>{pData, dataSize, idx};
833 return (U)SoATermRowWriteProxyEntity<U, true>{pEntities, pWorld, id, idx};
834 return (U)SoATermRowWriteProxyEntity<U, false>{pEntities, pWorld, id, idx};
837 SoATermRowWriteProxy& operator=(
const U& value) {
838 if (pData !=
nullptr) {
839 SoATermRowWriteProxyPointer<U>{pData, dataSize, idx} = value;
841 SoATermRowWriteProxyEntity<U, true>{pEntities, pWorld, id, idx} = value;
843 SoATermRowWriteProxyEntity<U, false>{pEntities, pWorld, id, idx} = value;
850 template <
typename U,
size_t Item>
851 struct SoATermFieldReadProxy {
852 using value_type =
typename SoATermFieldReadProxyPointer<U, Item>::value_type;
854 const value_type* pData =
nullptr;
855 const Entity* pEntities =
nullptr;
856 World* pWorld =
nullptr;
857 Entity
id = EntityBad;
860 GAIA_NODISCARD value_type operator[](
size_t idx)
const {
861 GAIA_ASSERT(idx < cnt);
862 if (pData !=
nullptr)
863 return SoATermFieldReadProxyPointer<U, Item>{pData, cnt}[idx];
865 return SoATermFieldReadProxyEntity<U, Item>{pEntities, pWorld, id, cnt}[idx];
868 GAIA_NODISCARD
constexpr size_t size() const noexcept {
875 template <
typename U,
size_t Item>
876 struct SoATermFieldWriteProxy {
877 using value_type =
typename SoATermFieldWriteProxyPointer<U, Item>::value_type;
879 value_type* pData =
nullptr;
880 const Entity* pEntities =
nullptr;
881 World* pWorld =
nullptr;
882 Entity
id = EntityBad;
888 struct ElementProxy {
889 value_type* pData =
nullptr;
890 const Entity* pEntities =
nullptr;
891 World* pWorld =
nullptr;
892 Entity
id = EntityBad;
896 GAIA_NODISCARD
operator value_type()
const {
897 if (pData !=
nullptr)
898 return SoATermFieldWriteProxyPointer<U, Item>{pData, idx + 1}[idx];
901 return SoATermFieldWriteProxyEntity<U, Item, true>{pEntities, pWorld, id, idx + 1}[idx];
902 return SoATermFieldWriteProxyEntity<U, Item, false>{pEntities, pWorld, id, idx + 1}[idx];
905 ElementProxy& operator=(
const value_type& value) {
906 if (pData !=
nullptr) {
907 SoATermFieldWriteProxyPointer<U, Item>{pData, idx + 1}[idx] = value;
912 SoATermFieldWriteProxyEntity<U, Item, true>{pEntities, pWorld, id, idx + 1}[idx] = value;
914 SoATermFieldWriteProxyEntity<U, Item, false>{pEntities, pWorld, id, idx + 1}[idx] = value;
918 template <
typename V>
919 ElementProxy& operator+=(V&& value) {
920 const value_type current =
operator value_type();
921 return operator=(current + GAIA_FWD(value));
924 template <
typename V>
925 ElementProxy& operator-=(V&& value) {
926 const value_type current =
operator value_type();
927 return operator=(current - GAIA_FWD(value));
930 template <
typename V>
931 ElementProxy& operator*=(V&& value) {
932 const value_type current =
operator value_type();
933 return operator=(current * GAIA_FWD(value));
936 template <
typename V>
937 ElementProxy& operator/=(V&& value) {
938 const value_type current =
operator value_type();
939 return operator=(current / GAIA_FWD(value));
943 GAIA_NODISCARD ElementProxy operator[](
size_t idx)
const {
944 GAIA_ASSERT(idx < cnt);
945 return ElementProxy{pData, pEntities, pWorld, id, (uint32_t)idx, writeIm};
948 GAIA_NODISCARD
constexpr size_t size() const noexcept {
955 template <
typename U>
956 struct SoATermViewGet {
957 const uint8_t* pData =
nullptr;
958 uint32_t dataSize = 0;
959 const Entity* pEntities =
nullptr;
960 World* pWorld =
nullptr;
961 Entity
id = EntityBad;
962 uint32_t idxBase = 0;
965 GAIA_NODISCARD U operator[](
size_t idx)
const {
966 GAIA_ASSERT(idx < cnt);
967 if (pData !=
nullptr)
968 return SoATermViewGetPointer<U>{pData, dataSize, idxBase, cnt}[idx];
970 return SoATermViewGetEntity<U>{pEntities, pWorld, id, cnt}[idx];
973 template <
size_t Item>
974 GAIA_NODISCARD
auto get()
const {
975 if (pData !=
nullptr) {
976 const auto field = SoATermViewGetPointer<U>{pData, dataSize, idxBase, cnt}.template get<Item>();
977 return SoATermFieldReadProxy<U, Item>{field.pData,
nullptr, pWorld, id, cnt};
980 const auto field = SoATermViewGetEntity<U>{pEntities, pWorld, id, cnt}.template get<Item>();
981 return SoATermFieldReadProxy<U, Item>{
nullptr, field.pEntities, field.pWorld, field.id, field.cnt};
984 GAIA_NODISCARD
constexpr size_t size() const noexcept {
991 template <
typename U>
992 struct SoATermViewSet {
993 uint8_t* pData =
nullptr;
994 uint32_t dataSize = 0;
995 const Entity* pEntities =
nullptr;
996 World* pWorld =
nullptr;
997 Entity
id = EntityBad;
998 uint32_t idxBase = 0;
1000 bool writeIm =
true;
1002 GAIA_NODISCARD
auto operator[](
size_t idx) {
1003 GAIA_ASSERT(idx < cnt);
1004 return SoATermRowWriteProxy<U>{pData, dataSize, pEntities, pWorld, id, idxBase + (uint32_t)idx, writeIm};
1007 GAIA_NODISCARD U operator[](
size_t idx)
const {
1008 GAIA_ASSERT(idx < cnt);
1009 if (pData !=
nullptr)
1010 return SoATermViewSetPointer<U>{pData, dataSize, idxBase, cnt}[idx];
1012 return SoATermViewSetEntity<U, true>{pEntities, pWorld, id, cnt}[idx];
1015 template <
size_t Item>
1016 GAIA_NODISCARD
auto get()
const {
1017 if (pData !=
nullptr) {
1018 const auto field = SoATermViewSetPointer<U>{pData, dataSize, idxBase, cnt}.template get<Item>();
1019 return SoATermFieldReadProxy<U, Item>{field.pData,
nullptr, pWorld, id, cnt};
1022 const auto field = SoATermViewSetEntity<U, true>{pEntities, pWorld, id, cnt}.template get<Item>();
1023 return SoATermFieldReadProxy<U, Item>{
nullptr, field.pEntities, field.pWorld, field.id, field.cnt};
1026 template <
size_t Item>
1027 GAIA_NODISCARD
auto set() {
1028 if (pData !=
nullptr) {
1029 auto field = SoATermViewSetPointer<U>{pData, dataSize, idxBase, cnt}.template set<Item>();
1030 return SoATermFieldWriteProxy<U, Item>{field.pData,
nullptr, pWorld, id, cnt};
1034 const auto field = SoATermViewSetEntity<U, true>{pEntities, pWorld, id, cnt}.template set<Item>();
1035 return SoATermFieldWriteProxy<U, Item>{
nullptr, field.pEntities, field.pWorld, field.id, field.cnt,
true};
1038 const auto field = SoATermViewSetEntity<U, false>{pEntities, pWorld, id, cnt}.template set<Item>();
1039 return SoATermFieldWriteProxy<U, Item>{
nullptr, field.pEntities, field.pWorld, field.id, field.cnt,
false};
1042 GAIA_NODISCARD
constexpr size_t size() const noexcept {
1047 class ChunkIterImpl {
1048 friend struct ChunkIterTypedOps;
1051 using CompIndicesBitView = core::bit_view<ChunkHeader::MAX_COMPONENTS_BITS>;
1054 const World* m_pWorld =
nullptr;
1056 const Archetype* m_pArchetype =
nullptr;
1058 Chunk* m_pChunk =
nullptr;
1060 const uint8_t* m_pCompIndices =
nullptr;
1062 InheritedTermDataView m_inheritedData;
1064 const Entity* m_pTermIdMapping =
nullptr;
1066 bool m_writeIm =
true;
1068 Constraints m_constraints = Constraints::EnabledOnly;
1070 uint8_t m_touchedCompIndices[ChunkHeader::MAX_COMPONENTS];
1071 uint8_t m_touchedCompCnt = 0;
1073 Entity m_touchedTerms[ChunkHeader::MAX_COMPONENTS];
1074 uint8_t m_touchedTermCnt = 0;
1076 Entity m_entitySnapshot[ChunkHeader::MAX_CHUNK_ENTITIES];
1077 bool m_entitySnapshotValid =
false;
1083 GroupId m_groupId = 0;
1085 void* m_pCtx =
nullptr;
1088 ChunkIterImpl() =
default;
1089 ~ChunkIterImpl() =
default;
1090 ChunkIterImpl(ChunkIterImpl&&) noexcept = default;
1091 ChunkIterImpl& operator=(ChunkIterImpl&&) noexcept = default;
1092 ChunkIterImpl(const ChunkIterImpl&) = delete;
1093 ChunkIterImpl& operator=(const ChunkIterImpl&) = delete;
1095 void set_world(const World* pWorld) {
1096 GAIA_ASSERT(pWorld !=
nullptr);
1100 GAIA_NODISCARD World* world() {
1101 GAIA_ASSERT(m_pWorld !=
nullptr);
1102 return const_cast<World*
>(m_pWorld);
1105 GAIA_NODISCARD
const World* world()
const {
1106 GAIA_ASSERT(m_pWorld !=
nullptr);
1110 void set_archetype(
const Archetype* pArchetype) {
1111 GAIA_ASSERT(pArchetype !=
nullptr);
1112 m_pArchetype = pArchetype;
1120 GAIA_NODISCARD
const Archetype* archetype()
const {
1121 GAIA_ASSERT(m_pArchetype !=
nullptr);
1122 return m_pArchetype;
1125 void set_chunk(Chunk* pChunk) {
1126 GAIA_ASSERT(pChunk !=
nullptr);
1128 m_entitySnapshotValid =
false;
1129 m_from = start_index(m_pChunk, m_constraints);
1130 m_to = end_index(m_pChunk, m_constraints);
1133 void set_chunk(Chunk* pChunk, uint16_t from, uint16_t to) {
1134 if (from == 0 && to == 0) {
1139 GAIA_ASSERT(pChunk !=
nullptr);
1141 m_entitySnapshotValid =
false;
1146 GAIA_NODISCARD
const Chunk* chunk()
const {
1147 GAIA_ASSERT(m_pChunk !=
nullptr);
1151 void set_comp_indices(
const uint8_t* pCompIndices) {
1152 m_pCompIndices = pCompIndices;
1155 void set_inherited_data(InheritedTermDataView inheritedData) {
1156 m_inheritedData = inheritedData;
1159 void set_term_ids(
const Entity* pTermIds) {
1160 m_pTermIdMapping = pTermIds;
1163 GAIA_NODISCARD
const uint8_t* comp_indices()
const {
1164 return m_pCompIndices;
1167 GAIA_NODISCARD InheritedTermDataView inherited_data()
const {
1168 return m_inheritedData;
1171 GAIA_NODISCARD
const Entity* term_ids()
const {
1172 return m_pTermIdMapping;
1175 void set_write_im(
bool value) {
1177 clear_touched_writes();
1180 void set_constraints(Constraints constraints) {
1181 m_constraints = constraints;
1182 if (m_pChunk !=
nullptr) {
1183 m_from = start_index(m_pChunk, m_constraints);
1184 m_to = end_index(m_pChunk, m_constraints);
1185 m_entitySnapshotValid =
false;
1193 void init_query_state(
const World* pWorld, Constraints constraints,
bool writeIm) {
1195 m_constraints = constraints;
1196 m_writeIm = writeIm;
1197 clear_touched_writes();
1206 void set_query_chunk(
1207 const Archetype* pArchetype,
const uint8_t* pCompIndices, Chunk* pChunk, uint16_t from, uint16_t to) {
1208 GAIA_ASSERT(pArchetype !=
nullptr);
1209 GAIA_ASSERT(pChunk !=
nullptr);
1210 if (m_pArchetype != pArchetype)
1211 m_pArchetype = pArchetype;
1212 if (m_pCompIndices != pCompIndices)
1213 m_pCompIndices = pCompIndices;
1215 m_entitySnapshotValid =
false;
1220 GAIA_NODISCARD
bool write_im()
const {
1224 GAIA_NODISCARD Constraints constraints()
const {
1225 return m_constraints;
1228 void clear_touched_writes() {
1229 m_touchedCompCnt = 0;
1230 m_touchedTermCnt = 0;
1233 GAIA_NODISCARD
const Entity* entity_snapshot() {
1234 if (!m_entitySnapshotValid) {
1235 const auto cnt = size();
1236 GAIA_ASSERT(cnt <= ChunkHeader::MAX_CHUNK_ENTITIES);
1238 const auto entities = m_pChunk->entity_view();
1240 m_entitySnapshot[i] = entities[from() + i];
1243 m_entitySnapshotValid =
true;
1246 return m_entitySnapshot;
1249 GAIA_NODISCARD
auto touched_comp_indices()
const {
1250 return std::span<const uint8_t>{m_touchedCompIndices, m_touchedCompCnt};
1253 GAIA_NODISCARD
auto touched_terms()
const {
1254 return std::span<const Entity>{m_touchedTerms, m_touchedTermCnt};
1257 GAIA_NODISCARD
auto entity_rows() {
1258 if (m_entitySnapshotValid)
1259 return std::span<const Entity>{m_entitySnapshot, size()};
1261 return std::span<const Entity>{m_pChunk->entity_view().data() + from(), size()};
1264 template <
typename U>
1265 GAIA_NODISCARD
auto entity_view_set(Entity termId,
bool writeIm) {
1266 return EntityTermViewSet<U>::entity(entity_snapshot(), world(), termId, size(), writeIm);
1270 template <
typename U>
1271 GAIA_NODISCARD
static auto entity_view_set_empty(
bool writeIm) {
1272 return EntityTermViewSet<U>::entity(
nullptr,
nullptr, EntityBad, 0, writeIm);
1275 template <
typename U>
1276 GAIA_NODISCARD
auto entity_soa_view_set(Entity termId,
bool writeIm) {
1277 return SoATermViewSet<U>{
nullptr, 0, entity_snapshot(), world(), termId, 0, size(), writeIm};
1281 template <
typename U>
1282 GAIA_NODISCARD
static auto entity_soa_view_set_empty(
bool writeIm) {
1283 return SoATermViewSet<U>{
nullptr, 0,
nullptr,
nullptr, EntityBad, 0, 0, writeIm};
1286 void set_group_id(GroupId groupId) {
1287 m_groupId = groupId;
1290 GAIA_NODISCARD GroupId group_id()
const {
1302 void ctx(
void* pCtx) {
1308 GAIA_NODISCARD
void* ctx()
const {
1313 GAIA_NODISCARD CommandBufferST& cmd_buffer_st()
const {
1314 auto* pWorld =
const_cast<World*
>(m_pWorld);
1315 return cmd_buffer_st_get(*pWorld);
1318 GAIA_NODISCARD CommandBufferMT& cmd_buffer_mt()
const {
1319 auto* pWorld =
const_cast<World*
>(m_pWorld);
1320 return cmd_buffer_mt_get(*pWorld);
1323 GAIA_NODISCARD IterTermDesc resolved_term_desc(uint32_t termIdx, IterTermDesc desc)
const {
1324 if (m_pTermIdMapping !=
nullptr) {
1325 const auto mappedTermId = m_pTermIdMapping[termIdx];
1326 if (mappedTermId != EntityBad)
1327 desc.termId = mappedTermId;
1330 if (!desc.storageKnown && !desc.isEntity && desc.termId != EntityBad)
1331 desc.usesSparseStorage = world_component_uses_sparse_storage(*world(), desc.termId);
1336 void touch_comp_idx(uint8_t compIdx) {
1337 GAIA_ASSERT(compIdx != 0xFF);
1338 GAIA_FOR(m_touchedCompCnt) {
1339 if (m_touchedCompIndices[i] == compIdx)
1343 GAIA_ASSERT(m_touchedCompCnt < ChunkHeader::MAX_COMPONENTS);
1344 m_touchedCompIndices[m_touchedCompCnt++] = compIdx;
1347 GAIA_NODISCARD
bool touch_term(Entity term) {
1348 GAIA_ASSERT(term != EntityBad);
1349 GAIA_FOR(m_touchedTermCnt) {
1350 if (m_touchedTerms[i] == term)
1354 if (m_touchedTermCnt >= ChunkHeader::MAX_COMPONENTS)
1357 m_touchedTerms[m_touchedTermCnt++] = term;
1361 GAIA_NODISCARD
bool touch_term_desc(
const IterTermDesc& desc) {
1364 if (desc.usesSparseStorage)
1365 return touch_term(desc.termId);
1366 touch_comp_idx((uint8_t)m_pChunk->comp_idx(desc.termId));
1373 GAIA_NODISCARD
bool touch_raw_component(Entity component) {
1374 if (!world_component_uses_sparse_storage(*world(), component)) {
1375 const auto compIdx = core::get_index(m_pChunk->ids_view(), component);
1376 if (compIdx != BadIndex) {
1377 touch_comp_idx((uint8_t)compIdx);
1382 return touch_term(component);
1388 GAIA_NODISCARD
bool owns_raw_component(Entity component) {
1389 const auto* pEntities = entity_snapshot();
1391 if (!world_mut_raw(*world(), pEntities[i], component).valid())
1398 GAIA_NODISCARD RawTermViewGet raw_term_view(uint32_t termIdx)
const {
1399 if (m_pCompIndices ==
nullptr || m_pChunk ==
nullptr)
1402 const auto compIdx = m_pCompIndices[termIdx];
1403 if (compIdx == 0xFF)
1406 const auto recs = m_pChunk->comp_rec_view();
1407 if (compIdx >= recs.size())
1410 const auto term = m_pChunk->ids_view()[compIdx];
1411 const auto& rec = recs[compIdx];
1412 if (rec.comp.soa() != 0)
1415 const auto elemSize = rec.comp.size();
1416 const auto row = (uint32_t)(from() * (1U - (uint32_t)term.kind()));
1417 const auto* pData = elemSize != 0 ? m_pChunk->comp_ptr(compIdx, row) :
nullptr;
1418 return {pData, elemSize, size(), ComponentRawViewFlag_Valid};
1428 GAIA_NODISCARD
bool raw_term_field_info(
1429 uint32_t termIdx, uint32_t fieldIdx, uint8_t& compIdx,
const ComponentCacheItem*& pItem)
const {
1430 if (m_pCompIndices ==
nullptr || m_pChunk ==
nullptr || size() == 0)
1433 compIdx = m_pCompIndices[termIdx];
1434 if (compIdx == 0xFF)
1437 const auto recs = m_pChunk->comp_rec_view();
1438 if (compIdx >= recs.size())
1441 const auto& rec = recs[compIdx];
1443 return pItem !=
nullptr && pItem->entity.kind() == EntityKind::EK_Gen &&
1444 rec.comp.storage_type() == DataStorageType::Table && rec.comp.soa() != 0 &&
1445 fieldIdx < rec.comp.soa() && pItem->soaSizes[fieldIdx] != 0;
1452 GAIA_NODISCARD RawTermViewGet raw_term_field_view(uint32_t termIdx, uint32_t fieldIdx)
const {
1454 const ComponentCacheItem* pItem;
1455 if (!raw_term_field_info(termIdx, fieldIdx, compIdx, pItem))
1458 const auto& rec = m_pChunk->comp_rec_view()[compIdx];
1459 const std::span<const uint8_t> fieldSizes{pItem->soaSizes, rec.comp.soa()};
1460 const auto* pData = mem::data_view_policy_soa_erased::get(
1461 m_pChunk->comp_ptr(compIdx), rec.comp.alig(), fieldSizes, fieldIdx, from(), m_pChunk->capacity());
1462 return {pData, pItem->soaSizes[fieldIdx], size(), ComponentRawViewFlag_Valid};
1470 GAIA_NODISCARD RawTermViewSet raw_term_field_view_mut(uint32_t termIdx, uint32_t fieldIdx,
bool trackWrite) {
1472 const ComponentCacheItem* pItem;
1473 if (!raw_term_field_info(termIdx, fieldIdx, compIdx, pItem))
1477 touch_comp_idx(compIdx);
1479 m_pChunk->update_world_version(compIdx);
1482 const auto& rec = m_pChunk->comp_rec_view()[compIdx];
1483 const std::span<const uint8_t> fieldSizes{pItem->soaSizes, rec.comp.soa()};
1484 auto* pData = mem::data_view_policy_soa_erased::set(
1485 m_pChunk->comp_ptr_mut(compIdx), rec.comp.alig(), fieldSizes, fieldIdx, from(), m_pChunk->capacity());
1486 return {pData, pItem->soaSizes[fieldIdx], size(), ComponentRawViewFlag_Valid};
1489 GAIA_NODISCARD RawTermViewSet raw_term_view_mut(uint32_t termIdx,
bool trackWrite) {
1490 if (m_pCompIndices ==
nullptr || m_pChunk ==
nullptr)
1493 const auto compIdx = m_pCompIndices[termIdx];
1494 if (compIdx == 0xFF)
1497 const auto recs = m_pChunk->comp_rec_view();
1498 if (compIdx >= recs.size())
1501 const auto term = m_pChunk->ids_view()[compIdx];
1502 const auto& rec = recs[compIdx];
1503 if (rec.comp.soa() != 0)
1507 touch_comp_idx(compIdx);
1509 m_pChunk->update_world_version(compIdx);
1512 const auto elemSize = rec.comp.size();
1513 const auto row = (uint32_t)(from() * (1U - (uint32_t)term.kind()));
1514 auto* pData = elemSize != 0 ? m_pChunk->comp_ptr_mut(compIdx, row) :
nullptr;
1515 return {pData, elemSize, size(), ComponentRawViewFlag_Valid};
1522 GAIA_NODISCARD RawTermViewSetEntity raw_term_view_any_mut(Entity component,
bool trackWrite) {
1523 if (component == EntityBad || m_pChunk ==
nullptr || size() == 0)
1526 const auto* pEntities = entity_snapshot();
1527 RawSparseStoreOps sparse{};
1528 if (world_bind_raw_sparse_store(*world(), component, sparse)) {
1530 if (!sparse.funcHas(sparse.pStore, pEntities[i]))
1533 }
else if (!owns_raw_component(component))
1535 if (trackWrite && !touch_raw_component(component))
1538 return {pEntities, world(), component, size(), sparse};
1544 GAIA_NODISCARD RawTermViewGet view_raw(uint32_t termIdx)
const {
1545 return raw_term_view(termIdx);
1555 GAIA_NODISCARD RawTermViewGet view_raw_field(uint32_t termIdx, uint32_t fieldIdx)
const {
1556 return raw_term_field_view(termIdx, fieldIdx);
1566 GAIA_NODISCARD RawTermViewSet view_raw_field_mut(uint32_t termIdx, uint32_t fieldIdx) {
1567 return raw_term_field_view_mut(termIdx, fieldIdx,
true);
1577 GAIA_NODISCARD RawTermViewSet sview_raw_field_mut(uint32_t termIdx, uint32_t fieldIdx) {
1578 return raw_term_field_view_mut(termIdx, fieldIdx,
false);
1585 GAIA_NODISCARD RawTermViewSet view_raw_mut(uint32_t termIdx) {
1586 return raw_term_view_mut(termIdx,
true);
1593 GAIA_NODISCARD RawTermViewSet sview_raw_mut(uint32_t termIdx) {
1594 return raw_term_view_mut(termIdx,
false);
1602 GAIA_NODISCARD RawTermViewGetEntity view_raw_any(Entity component)
const {
1603 if (component == EntityBad || m_pChunk ==
nullptr || size() == 0)
1606 const auto* pEntities = m_pChunk->entity_view().data() + from();
1607 RawSparseStoreOps sparse{};
1608 if (!world_bind_raw_sparse_store(*world(), component, sparse) &&
1609 !world_get_raw(*world(), pEntities[0], component).valid())
1612 return {pEntities, world(), component, size(), sparse};
1621 GAIA_NODISCARD RawTermViewSetEntity view_raw_any_mut(Entity component) {
1622 return raw_term_view_any_mut(component,
true);
1630 GAIA_NODISCARD RawTermViewSetEntity sview_raw_any_mut(Entity component) {
1631 return raw_term_view_any_mut(component,
false);
1636 void modify_raw(uint32_t termIdx) {
1637 if (m_pCompIndices ==
nullptr || m_pChunk ==
nullptr)
1640 const auto compIdx = m_pCompIndices[termIdx];
1641 if (compIdx == 0xFF || compIdx >= m_pChunk->comp_rec_view().size())
1644 const auto& rec = m_pChunk->comp_rec_view()[compIdx];
1645 if (rec.comp.soa() != 0) {
1646 uint8_t fieldCompIdx;
1647 const ComponentCacheItem* pItem;
1648 if (!raw_term_field_info(termIdx, 0, fieldCompIdx, pItem))
1652 touch_comp_idx(compIdx);
1660 GAIA_NODISCARD
bool modify_raw(Entity component) {
1661 if (component == EntityBad || m_pChunk ==
nullptr || size() == 0 || !owns_raw_component(component))
1664 return touch_raw_component(component);
1673 template <
typename T>
1674 GAIA_NODISCARD
auto view_any()
const {
1675 return ChunkIterTypedOps::template view_any<T>(*
this);
1685 template <
typename T>
1686 GAIA_NODISCARD
auto view_any(uint32_t termIdx) {
1687 return ChunkIterTypedOps::template view_any<T>(*
this, termIdx);
1697 template <
typename T>
1698 GAIA_NODISCARD
auto view()
const {
1699 return ChunkIterTypedOps::template view<T>(*
this);
1709 template <
typename T>
1710 GAIA_NODISCARD
auto view(uint32_t termIdx)
const {
1711 return ChunkIterTypedOps::template view<T>(*
this, termIdx);
1720 template <
typename T>
1721 GAIA_NODISCARD
auto view_any_mut() {
1722 return ChunkIterTypedOps::template view_any_mut<T>(*
this);
1730 template <
typename T>
1731 GAIA_NODISCARD
auto view_mut() {
1732 return ChunkIterTypedOps::template view_mut<T>(*
this);
1742 template <
typename T>
1743 GAIA_NODISCARD
auto view_mut(uint32_t termIdx) {
1744 return ChunkIterTypedOps::template view_mut<T>(*
this, termIdx);
1754 template <
typename T>
1755 GAIA_NODISCARD
auto view_any_mut(uint32_t termIdx) {
1756 return ChunkIterTypedOps::template view_any_mut<T>(*
this, termIdx);
1766 template <
typename T>
1767 GAIA_NODISCARD
auto sview_any_mut() {
1768 return ChunkIterTypedOps::template sview_any_mut<T>(*
this);
1776 template <
typename T>
1777 GAIA_NODISCARD
auto sview_mut() {
1778 return ChunkIterTypedOps::template sview_mut<T>(*
this);
1788 template <
typename T>
1789 GAIA_NODISCARD
auto sview_mut(uint32_t termIdx) {
1790 return ChunkIterTypedOps::template sview_mut<T>(*
this, termIdx);
1801 template <
typename T>
1802 GAIA_NODISCARD
auto sview_any_mut(uint32_t termIdx) {
1803 return ChunkIterTypedOps::template sview_any_mut<T>(*
this, termIdx);
1809 template <
typename T,
bool TriggerHooks>
1811 m_pChunk->template modify<T, TriggerHooks>();
1820 template <
typename T>
1821 GAIA_NODISCARD
auto view_auto() {
1822 using UOriginal =
typename actual_type_t<T>::TypeOriginal;
1823 if constexpr (core::is_mut_v<UOriginal>)
1824 return view_mut<T>();
1835 template <
typename T>
1836 GAIA_NODISCARD
auto view_auto_any() {
1837 using UOriginal =
typename actual_type_t<T>::TypeOriginal;
1838 if constexpr (core::is_mut_v<UOriginal>)
1839 return view_any_mut<T>();
1841 return view_any<T>();
1851 template <
typename T>
1852 GAIA_NODISCARD
auto sview_auto_any() {
1853 using UOriginal =
typename actual_type_t<T>::TypeOriginal;
1854 if constexpr (core::is_mut_v<UOriginal>)
1855 return sview_any_mut<T>();
1857 return view_any<T>();
1867 template <
typename T>
1868 GAIA_NODISCARD
auto sview_auto() {
1869 using UOriginal =
typename actual_type_t<T>::TypeOriginal;
1870 if constexpr (core::is_mut_v<UOriginal>)
1871 return sview_mut<T>();
1878 GAIA_NODISCARD
bool enabled(uint32_t index)
const {
1879 const auto row = (uint16_t)(from() + index);
1880 return m_pChunk->enabled(row);
1886 GAIA_NODISCARD
bool has(Entity entity)
const {
1887 return m_pChunk->has(entity);
1893 GAIA_NODISCARD
bool has(Pair pair)
const {
1894 return m_pChunk->has((Entity)pair);
1900 template <
typename T>
1901 GAIA_NODISCARD
bool has()
const {
1902 return m_pChunk->template has<T>();
1905 GAIA_NODISCARD
static uint16_t start_index(Chunk* pChunk, Constraints constraints)
noexcept {
1906 if (constraints == Constraints::EnabledOnly)
1907 return pChunk->size_disabled();
1911 GAIA_NODISCARD
static uint16_t end_index(Chunk* pChunk, Constraints constraints)
noexcept {
1912 if (constraints == Constraints::DisabledOnly)
1913 return pChunk->size_disabled();
1914 return pChunk->size();
1917 GAIA_NODISCARD
static uint16_t size(Chunk* pChunk, Constraints constraints)
noexcept {
1918 if (constraints == Constraints::EnabledOnly)
1919 return pChunk->size_enabled();
1920 if (constraints == Constraints::DisabledOnly)
1921 return pChunk->size_disabled();
1922 return pChunk->size();
1926 GAIA_NODISCARD uint16_t size() const noexcept {
1927 return (uint16_t)(to() - from());
1931 GAIA_NODISCARD uint16_t row_begin() const noexcept {
1936 GAIA_NODISCARD uint16_t row_end() const noexcept {
1943 template <
typename T>
1944 uint32_t acc_index(uint32_t idx)
const noexcept {
1945 using U =
typename actual_type_t<T>::Type;
1946 if constexpr (mem::is_soa_layout_v<U>)
1947 return idx + from();
1954 GAIA_NODISCARD uint16_t from() const noexcept {
1959 GAIA_NODISCARD uint16_t to() const noexcept {
1968 class GAIA_API
Iter:
public detail::ChunkIterImpl {
1971 static constexpr Constraints ConstraintMode = Constraints::EnabledOnly;
1973 using detail::ChunkIterImpl::size;
1976 set_constraints(ConstraintMode);
1983 return detail::ChunkIterImpl::start_index(pChunk, ConstraintMode);
1990 return detail::ChunkIterImpl::end_index(pChunk, ConstraintMode);
1996 GAIA_NODISCARD
static uint16_t
size(
Chunk* pChunk)
noexcept {
1997 return detail::ChunkIterImpl::size(pChunk, ConstraintMode);
2003 return m_pChunk->size_enabled();
2010 return m_pChunk->size_disabled();
2042 void set_range(uint16_t from, uint16_t cnt) {
2043 GAIA_ASSERT(from < m_pChunk->size());
2044 GAIA_ASSERT(from + cnt <= m_pChunk->size());
2052 GAIA_ASSERT(pWorld !=
nullptr);
2059 GAIA_ASSERT(m_pWorld !=
nullptr);
2060 return const_cast<World*
>(m_pWorld);
2066 GAIA_ASSERT(m_pWorld !=
nullptr);
2073 GAIA_ASSERT(pArchetype !=
nullptr);
2074 m_pArchetype = pArchetype;
2085 GAIA_ASSERT(m_pArchetype !=
nullptr);
2086 return m_pArchetype;
2092 GAIA_ASSERT(pChunk !=
nullptr);
2099 GAIA_ASSERT(m_pChunk !=
nullptr);
2106 auto* pWorld =
const_cast<World*
>(m_pWorld);
2107 return cmd_buffer_st_get(*pWorld);
2113 auto* pWorld =
const_cast<World*
>(m_pWorld);
2114 return cmd_buffer_mt_get(*pWorld);
2121 template <
typename T>
2123 return m_pChunk->template view<T>(from(), to());
2130 template <
typename T>
2132 return m_pChunk->template view_mut<T>(from(), to());
2140 template <
typename T>
2142 return m_pChunk->template sview_mut<T>(from(), to());
2148 template <
typename T,
bool TriggerHooks>
2150 m_pChunk->template modify<T, TriggerHooks>();
2158 template <
typename T>
2160 return m_pChunk->template view_auto<T>(from(), to());
2169 template <
typename T>
2171 return m_pChunk->template sview_auto<T>(from(), to());
2177 GAIA_NODISCARD
bool enabled(uint32_t index)
const {
2178 const auto row = (uint16_t)(from() + index);
2179 return m_pChunk->
enabled(row);
2186 return m_pChunk->
has(entity);
2199 template <
typename T>
2200 GAIA_NODISCARD
bool has()
const {
2201 return m_pChunk->template has<T>();
2206 GAIA_NODISCARD uint16_t
size() const noexcept {
2212 GAIA_NODISCARD uint16_t from() const noexcept {
2217 GAIA_NODISCARD uint16_t to() const noexcept {
2218 return m_from + m_cnt;
2224#include "gaia/ecs/chunk_iterator_typed.inl"
Fixed-shape group of chunks storing entities that share the same component layout....
Definition archetype.h:97
Fixed-capacity archetype storage unit holding entities and their component columns.
Definition chunk.h:36
bool enabled(uint16_t row) const
Checks if the entity is enabled.
Definition chunk.h:1432
GAIA_NODISCARD bool has(Entity entity) const
Checks if a component/entity entity is present in the chunk.
Definition chunk.h:1527
Iterator used when copying entities.
Definition chunk_iterator.h:2015
uint16_t m_from
Row of the first entity we iterate from.
Definition chunk_iterator.h:2027
GAIA_NODISCARD CommandBufferST & cmd_buffer_st() const
Returns the world's single-threaded command buffer.
Definition chunk_iterator.h:2105
GAIA_NODISCARD auto view() const
Returns a read-only entity or component view.
Definition chunk_iterator.h:2122
void set_world(const World *pWorld)
Associates the iterator with its owning world.
Definition chunk_iterator.h:2051
GAIA_NODISCARD const Chunk * chunk() const
Returns the associated source chunk.
Definition chunk_iterator.h:2098
GAIA_NODISCARD CommandBufferMT & cmd_buffer_mt() const
Returns the world's multi-threaded command buffer.
Definition chunk_iterator.h:2112
GAIA_NODISCARD auto sview_auto()
Returns either a mutable or immutable entity/component view based on the requested type....
Definition chunk_iterator.h:2170
GAIA_NODISCARD auto sview_mut()
Returns a mutable component view. Doesn't update the world version when the access is acquired.
Definition chunk_iterator.h:2141
GAIA_NODISCARD World * world()
Returns mutable access to the associated world.
Definition chunk_iterator.h:2058
void set_archetype(const Archetype *pArchetype)
Associates the iterator with the source archetype.
Definition chunk_iterator.h:2072
GAIA_NODISCARD bool has() const
Checks if component T is present in the chunk.
Definition chunk_iterator.h:2200
GAIA_NODISCARD auto view_mut()
Returns a mutable entity or component view.
Definition chunk_iterator.h:2131
GAIA_NODISCARD bool has(Pair pair) const
Checks if relationship pair pair is present in the chunk.
Definition chunk_iterator.h:2192
uint16_t m_cnt
The number of entities accessible via the iterator.
Definition chunk_iterator.h:2029
GAIA_NODISCARD auto view_auto()
Returns either a mutable or immutable entity/component view based on the requested type....
Definition chunk_iterator.h:2159
GAIA_NODISCARD bool has(Entity entity) const
Checks if entity entity is present in the chunk.
Definition chunk_iterator.h:2185
void modify()
Marks the component T as modified. Best used with sview to manually trigger an update at user's whim....
Definition chunk_iterator.h:2149
GAIA_NODISCARD const Archetype * archetype() const
Returns the associated source archetype.
Definition chunk_iterator.h:2084
GAIA_NODISCARD const World * world() const
Returns read-only access to the associated world.
Definition chunk_iterator.h:2065
void set_chunk(Chunk *pChunk)
Associates the iterator with a source chunk.
Definition chunk_iterator.h:2091
GAIA_NODISCARD uint16_t size() const noexcept
Returns the number of entities accessible via the iterator.
Definition chunk_iterator.h:2206
GAIA_NODISCARD bool enabled(uint32_t index) const
Checks if the entity at the current iterator index is enabled.
Definition chunk_iterator.h:2177
Iterator for iterating entity subsets selected by Constraints. Disabled entities always precede enabl...
Definition chunk_iterator.h:1968
static GAIA_NODISCARD uint16_t size(Chunk *pChunk) noexcept
Returns the number of enabled rows in a chunk.
Definition chunk_iterator.h:1996
static GAIA_NODISCARD uint16_t end_index(Chunk *pChunk) noexcept
Returns the end of the enabled row range in a chunk.
Definition chunk_iterator.h:1989
GAIA_NODISCARD uint16_t size_disabled() const noexcept
Returns the number of disabled entities accessible via the iterator. Can be read also as "the index o...
Definition chunk_iterator.h:2009
GAIA_NODISCARD uint16_t size_enabled() const noexcept
Returns the number of enabled entities accessible via the iterator.
Definition chunk_iterator.h:2002
static GAIA_NODISCARD uint16_t start_index(Chunk *pChunk) noexcept
Returns the first enabled row in a chunk.
Definition chunk_iterator.h:1982
Owns entities, components, archetypes, queries, observers, and systems.
Definition world.h:80
Buffer for deferred execution of some operations on entities.
Definition command_buffer.h:52
Wrapper for two Entities forming a relationship pair.
Definition id.h:614
Wrapper for two types forming a relationship pair. Depending on what types are used to form a pair it...
Definition id.h:262
Provides packed access to fixed-width unsigned values stored in a byte span.
Definition bit_utils.h:13
Identifier of an entity or component instance in the world. Packs the entity index,...
Definition id.h:296
Prebound operations for one runtime sparse component store.
Definition chunk_iterator.h:24
uint32_t elemSize
Size of one stored component value in bytes.
Definition chunk_iterator.h:34
bool(* funcHas)(const void *, Entity)
Tests whether an entity has a value in the store.
Definition chunk_iterator.h:32
const void * pStore
Type-erased sparse store instance.
Definition chunk_iterator.h:26