Flecs v4.1
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
sparse_query.hpp
Go to the documentation of this file.
1
4#pragma once
5
6namespace flecs {
7
12namespace _ {
13
14inline void* field_at_sparse(
15 const ecs_sparse_t *sparse, size_t size, uint64_t entity, bool checked)
16{
17 return flecs_sparse_get_w_check(sparse, static_cast<ecs_size_t>(size),
18 entity, checked);
19}
20
21}
22
26template <typename ... Components>
28 static_assert(_::is_sparse_query<Components...>::value,
29 "all sparse_query components must have the dont_fragment trait and "
30 "must not declare the on_instantiate::inherit policy");
31
33 : world_(ECS_CONST_CAST(flecs::world_t*, ecs_get_world(world)))
34 , ids_{ _::type<Components>::id(world)... }
35 {
36 assert_policies();
37 }
38
42 template <typename Func>
43 void each(Func&& func) const {
44 each_impl(std::index_sequence_for<Components...>{}, func);
45 }
46
48 int32_t count() const {
49 int32_t result = 0;
50 each([&](Components&...) { result ++; });
51 return result;
52 }
53
55 operator flecs::query<Components...>() const;
56
57private:
58 template <size_t ... Is, typename Func>
59 void each_impl(std::index_sequence<Is...>, const Func& func) const {
60 constexpr size_t n = sizeof...(Components);
61
62 ecs_sparse_t *sparse[n] = { storage(ids_[Is])... };
63 for (size_t f = 0; f < n; f ++) {
64 if (!sparse[f]) {
65 return;
66 }
67 }
68
69 size_t lead = 0;
70 for (size_t f = 1; f < n; f ++) {
71 if (sparse[f]->count < sparse[lead]->count) {
72 lead = f;
73 }
74 }
75
76 const uint64_t *entities = flecs_sparse_ids(sparse[lead]);
77 int32_t count = sparse[lead]->count - 1;
78
79 for (int32_t i = 0; i < count; i ++) {
80 uint64_t e = entities[i];
81 void *ptrs[n];
82 if (!(... && (ptrs[Is] = flecs_sparse_get_w_check(
83 sparse[Is], ECS_SIZEOF(remove_reference_t<Components>), e,
84 Is != lead))))
85 {
86 continue;
87 }
88
89 const ecs_record_t *r = ecs_record_find(world_, e);
90 if (flecs_table_flags(r->table) &
91 (EcsTableNotQueryable|EcsTableIsPrefab|EcsTableIsDisabled))
92 {
93 continue;
94 }
95
96 if constexpr (std::is_invocable<
97 Func, flecs::entity, Components&...>::value)
98 {
99 func(flecs::entity(world_, e),
100 (*static_cast<remove_reference_t<Components>*>(
101 ptrs[Is]))...);
102 } else {
103 func((*static_cast<remove_reference_t<Components>*>(
104 ptrs[Is]))...);
105 }
106 }
107 }
108
109 ecs_sparse_t* storage(flecs::id_t id) const {
110 ecs_component_record_t *cr = flecs_components_get(world_, id);
111 return cr ? flecs_component_get_sparse(cr) : nullptr;
112 }
113
114 void assert_policies() const {
115 for (flecs::id_t id : ids_) {
116 (void)id;
117 ecs_assert(ecs_get_target(world_, id, flecs::OnInstantiate, 0) !=
118 flecs::Inherit, ECS_INVALID_OPERATION,
119 "sparse_query component has the OnInstantiate Inherit trait, "
120 "which sparse queries cannot match; add the on_instantiate "
121 "trait at compile time instead");
122 }
123 }
124
125 flecs::world_t *world_;
126 flecs::id_t ids_[sizeof...(Components)];
127};
128
131}
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_INVALID_OPERATION
Invalid operation error code.
Definition log.h:669
struct ecs_component_record_t ecs_component_record_t
Information about a (component) ID, such as type info and tables with the ID.
Definition flecs.h:498
struct ecs_record_t ecs_record_t
Information about an entity, like its table and row.
Definition flecs.h:495
ecs_id_t id_t
ID type.
Definition c_types.hpp:20
ecs_world_t world_t
World type.
Definition c_types.hpp:18
ecs_entity_t ecs_get_target(const ecs_world_t *world, ecs_entity_t entity, ecs_entity_t rel, int32_t index)
Get the target of a relationship.
const ecs_world_t * ecs_get_world(const ecs_poly_t *poly)
Get the world from a poly.
Entity.
Definition entity.hpp:30
Typed query.
Definition impl.hpp:262
Query that iterates sparse component storages directly.
int32_t count() const
Return the number of entities matched by the query.
void each(Func &&func) const
Iterate the query.
Trait that marks a component as Sparse at compile time.
Definition utils.hpp:187
The world.
Definition world.hpp:244