Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
query_adapter_typed.inl
1#pragma once
2
3namespace gaia {
4 namespace ecs {
6 void world_notify_on_set_entity(World& world, Entity term, Entity entity);
7
8 template <typename T>
9 void* world_typed_sparse_store_ptr(World& world, Entity component);
10 template <typename T>
11 const T& world_typed_sparse_store_get(const void* pStore, Entity entity);
12 template <typename T>
13 T& world_typed_sparse_store_mut(void* pStore, Entity entity);
14 template <typename T>
15 bool world_typed_sparse_store_has(const void* pStore, Entity entity);
21 template <typename T>
22 T* world_typed_sparse_store_try_mut(void* pStore, Entity entity);
28 template <typename T>
29 const T* world_typed_sparse_store_try_get(const void* pStore, Entity entity);
30
31 template <typename T>
32 struct typed_query_arg_uses_sparse_storage: std::bool_constant<uses_ct_sparse_storage_v<T>> {};
33
34 template <typename... T>
35 inline constexpr bool typed_query_args_use_sparse_storage_v =
36 (typed_query_arg_uses_sparse_storage<T>::value || ...);
37
38 template <typename T>
39 struct typed_query_arg_list_uses_sparse_storage;
40
41 template <typename... T>
42 struct typed_query_arg_list_uses_sparse_storage<core::func_type_list<T...>>:
43 std::bool_constant<typed_query_args_use_sparse_storage_v<T...>> {};
44
45 template <typename T>
46 inline constexpr bool typed_query_arg_list_uses_sparse_storage_v =
47 typed_query_arg_list_uses_sparse_storage<T>::value;
48
49 struct TypedQueryExecState {
50 uint32_t argCount = 0;
51 Entity argIds[MAX_ITEMS_IN_QUERY]{};
52 bool writeFlags[MAX_ITEMS_IN_QUERY]{};
53 void* sparseStores[MAX_ITEMS_IN_QUERY]{};
54 uint32_t firstWriteArg = MAX_ITEMS_IN_QUERY;
55 bool hasWriteArgs = false;
56 bool needsInheritedArgIds = false;
57 bool canUseDirectChunkEval = false;
58 bool canUseSparseChunkEval = false;
59 bool hasInheritedTerms = false;
60 };
61
62 struct TypedQueryArgMeta {
63 Entity termId = EntityBad;
64 bool isWrite = false;
65 bool isEntity = false;
66 bool isPair = false;
67 bool usesSparseStorage = false;
68 };
69
70 template <typename T>
71 GAIA_NODISCARD inline TypedQueryArgMeta typed_query_arg_meta(World& world) {
72 using Arg = std::remove_cv_t<std::remove_reference_t<T>>;
73 const bool isWrite =
74 std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>> && !std::is_same_v<Arg, Entity>;
75 if constexpr (std::is_same_v<Arg, Entity>)
76 return TypedQueryArgMeta{EntityBad, isWrite, true, false, false};
77 else {
78 using FT = typename component_type_t<Arg>::TypeFull;
79 return TypedQueryArgMeta{
80 world_query_arg_id<Arg>(world), isWrite, false, is_pair<FT>::value, uses_ct_sparse_storage_v<Arg>};
81 }
82 }
83
84 template <typename... T>
85 inline uint32_t
86 init_typed_query_arg_metas(TypedQueryArgMeta* pMetas, World& world, [[maybe_unused]] core::func_type_list<T...>) {
87 if constexpr (sizeof...(T) > 0) {
88 const TypedQueryArgMeta descs[] = {typed_query_arg_meta<T>(world)...};
89 GAIA_FOR(sizeof...(T)) {
90 pMetas[i] = descs[i];
91 }
92 }
93 return (uint32_t)sizeof...(T);
94 }
95
96 template <typename... T, size_t... I>
97 inline void bind_typed_sparse_stores(
98 TypedQueryExecState& state, World& world, core::func_type_list<T...>, std::index_sequence<I...>) {
99 (([&]() {
100 using U = typename actual_type_t<T>::Type;
101 if constexpr (uses_ct_sparse_storage_v<T>)
102 state.sparseStores[I] = world_typed_sparse_store_ptr<U>(world, state.argIds[I]);
103 }()),
104 ...);
105 }
106
107 template <typename... T>
108 inline void bind_typed_sparse_stores(TypedQueryExecState& state, World& world, core::func_type_list<T...> types) {
109 bind_typed_sparse_stores(state, world, types, std::index_sequence_for<T...>{});
110 }
111
112#if GAIA_ASSERT_ENABLED
113 template <typename... T>
114 GAIA_NODISCARD inline bool
115 typed_query_args_match_query(const QueryInfo& queryInfo, [[maybe_unused]] core::func_type_list<T...>) {
116 if constexpr (sizeof...(T) > 0)
117 return queryInfo.template has_all<T...>();
118 else
119 return true;
120 }
121#endif
122
123 template <typename... T, typename Func, size_t... I>
124 inline void invoke_typed_query_args_by_id(
125 World& world, [[maybe_unused]] Entity entity, [[maybe_unused]] const Entity* pArgIds, Func& func,
126 std::index_sequence<I...>) {
127 func(([&]() -> decltype(auto) {
128 using Arg = std::remove_cv_t<std::remove_reference_t<T>>;
129 if constexpr (std::is_same_v<Arg, Entity>)
130 return entity;
131 else if constexpr (std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>)
132 return world_query_entity_arg_by_id_raw<T>(world, entity, pArgIds[I]);
133 else
134 return world_query_entity_arg_by_id<T>(world, entity, pArgIds[I]);
135 }())...);
136 }
137
138 template <typename Func, typename... T>
139 inline void invoke_typed_query_args_by_id_erased(World& world, Entity entity, const Entity* pArgIds, void* pFunc) {
140 auto& func = *static_cast<Func*>(pFunc);
141 invoke_typed_query_args_by_id<T...>(world, entity, pArgIds, func, std::index_sequence_for<T...>{});
142 }
143
144 template <typename Func, typename... T>
145 GAIA_NODISCARD inline auto typed_invoke_inherited_ptr(core::func_type_list<T...>) {
146 return &invoke_typed_query_args_by_id_erased<Func, T...>;
147 }
148
149 inline void finish_typed_query_args_by_id(World& world, Entity entity, const TypedQueryExecState& state) {
150 if (state.firstWriteArg >= state.argCount)
151 return;
152
153 Entity seenTerms[ChunkHeader::MAX_COMPONENTS]{};
154 uint32_t seenCnt = 0;
155 const auto finish_term = [&](Entity term, bool sparseStoreBound) {
156 GAIA_FOR(seenCnt) {
157 if (seenTerms[i] == term)
158 return;
159 }
160
161 seenTerms[seenCnt++] = term;
162 if (sparseStoreBound)
163 world_notify_on_set_entity(world, term, entity);
164 else
165 world_finish_write(world, term, entity);
166 };
167
168 for (uint32_t i = state.firstWriteArg; i < state.argCount; ++i) {
169 if (state.writeFlags[i] && state.argIds[i] != EntityBad)
170 finish_term(state.argIds[i], state.sparseStores[i] != nullptr);
171 }
172 }
174 } // namespace ecs
175} // namespace gaia
static constexpr bool value
True when the type derives from the pair base.
Definition id.h:222