6 void world_notify_on_set_entity(World& world, Entity term, Entity entity);
9 void* world_typed_sparse_store_ptr(World& world, Entity component);
11 const T& world_typed_sparse_store_get(
const void* pStore, Entity entity);
13 T& world_typed_sparse_store_mut(
void* pStore, Entity entity);
15 bool world_typed_sparse_store_has(
const void* pStore, Entity entity);
17 template <typename T, bool IsEntity = std::is_same_v<typename actual_type_t<T>::Type, Entity>>
18 struct typed_query_arg_uses_sparse_storage: std::false_type {};
21 struct typed_query_arg_uses_sparse_storage<T, false>:
22 std::bool_constant<auto_storage_policy_v<typename actual_type_t<T>::Type> == DataStorageType::Sparse> {};
24 template <
typename... T>
25 inline constexpr bool typed_query_args_use_sparse_storage_v =
26 (typed_query_arg_uses_sparse_storage<T>::value || ...);
29 struct typed_query_arg_list_uses_sparse_storage;
31 template <
typename... T>
32 struct typed_query_arg_list_uses_sparse_storage<core::func_type_list<T...>>:
33 std::bool_constant<typed_query_args_use_sparse_storage_v<T...>> {};
36 inline constexpr bool typed_query_arg_list_uses_sparse_storage_v =
37 typed_query_arg_list_uses_sparse_storage<T>::value;
39 struct TypedQueryExecState {
40 uint32_t argCount = 0;
41 Entity argIds[MAX_ITEMS_IN_QUERY]{};
42 bool writeFlags[MAX_ITEMS_IN_QUERY]{};
43 void* sparseStores[MAX_ITEMS_IN_QUERY]{};
44 uint32_t firstWriteArg = MAX_ITEMS_IN_QUERY;
45 bool hasWriteArgs =
false;
46 bool needsInheritedArgIds =
false;
47 bool canUseDirectChunkEval =
false;
48 bool canUseSparseChunkEval =
false;
49 bool hasInheritedTerms =
false;
52 struct TypedQueryArgMeta {
53 Entity termId = EntityBad;
55 bool isEntity =
false;
57 bool usesSparseStorage =
false;
61 GAIA_NODISCARD
inline TypedQueryArgMeta typed_query_arg_meta(World& world) {
62 using Arg = std::remove_cv_t<std::remove_reference_t<T>>;
64 std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>> && !std::is_same_v<Arg, Entity>;
65 if constexpr (std::is_same_v<Arg, Entity>)
66 return TypedQueryArgMeta{EntityBad, isWrite,
true,
false,
false};
68 using FT =
typename component_type_t<Arg>::TypeFull;
70 return TypedQueryArgMeta{EntityBad, isWrite,
false,
true,
false};
72 const auto termId = world_query_arg_id<Arg>(world);
73 constexpr bool UsesSparseStorage =
74 auto_storage_policy_v<typename actual_type_t<Arg>::Type> == DataStorageType::Sparse;
75 return TypedQueryArgMeta{termId, isWrite,
false,
false, UsesSparseStorage};
80 template <
typename... T>
82 init_typed_query_arg_metas(TypedQueryArgMeta* pMetas, World& world, [[maybe_unused]] core::func_type_list<T...>) {
83 if constexpr (
sizeof...(T) > 0) {
84 const TypedQueryArgMeta descs[] = {typed_query_arg_meta<T>(world)...};
85 GAIA_FOR(
sizeof...(T)) {
89 return (uint32_t)
sizeof...(T);
92 template <
typename... T,
size_t... I>
93 inline void bind_typed_sparse_stores(
94 TypedQueryExecState& state, World& world, core::func_type_list<T...>, std::index_sequence<I...>) {
96 using U =
typename actual_type_t<T>::Type;
97 if constexpr (!std::is_same_v<U, Entity> && auto_storage_policy_v<U> == DataStorageType::Sparse)
98 state.sparseStores[I] = world_typed_sparse_store_ptr<U>(world, state.argIds[I]);
103 template <
typename... T>
104 inline void bind_typed_sparse_stores(TypedQueryExecState& state, World& world, core::func_type_list<T...> types) {
105 bind_typed_sparse_stores(state, world, types, std::index_sequence_for<T...>{});
108#if GAIA_ASSERT_ENABLED
109 template <
typename... T>
110 GAIA_NODISCARD
inline bool
111 typed_query_args_match_query(
const QueryInfo& queryInfo, [[maybe_unused]] core::func_type_list<T...>) {
112 if constexpr (
sizeof...(T) > 0)
113 return queryInfo.template has_all<T...>();
119 template <
typename... T,
typename Func,
size_t... I>
120 inline void invoke_typed_query_args_by_id(
121 World& world, Entity entity,
const Entity* pArgIds, Func& func, std::index_sequence<I...>) {
122 func(([&]() ->
decltype(
auto) {
123 using Arg = std::remove_cv_t<std::remove_reference_t<T>>;
124 if constexpr (std::is_same_v<Arg, Entity>)
126 else if constexpr (std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>)
127 return world_query_entity_arg_by_id_raw<T>(world, entity, pArgIds[I]);
129 return world_query_entity_arg_by_id<T>(world, entity, pArgIds[I]);
133 template <
typename Func,
typename... T>
134 inline void invoke_typed_query_args_by_id_erased(World& world, Entity entity,
const Entity* pArgIds,
void* pFunc) {
135 auto& func = *
static_cast<Func*
>(pFunc);
136 invoke_typed_query_args_by_id<T...>(world, entity, pArgIds, func, std::index_sequence_for<T...>{});
139 template <
typename Func,
typename... T>
140 GAIA_NODISCARD
inline auto typed_invoke_inherited_ptr(core::func_type_list<T...>) {
141 return &invoke_typed_query_args_by_id_erased<Func, T...>;
144 inline void finish_typed_query_args_by_id(World& world, Entity entity,
const TypedQueryExecState& state) {
145 if (state.firstWriteArg >= state.argCount)
148 Entity seenTerms[ChunkHeader::MAX_COMPONENTS]{};
149 uint32_t seenCnt = 0;
150 const auto finish_term = [&](Entity term,
bool sparseStoreBound) {
152 if (seenTerms[i] == term)
156 seenTerms[seenCnt++] = term;
157 if (sparseStoreBound)
158 world_notify_on_set_entity(world, term, entity);
160 world_finish_write(world, term, entity);
163 for (uint32_t i = state.firstWriteArg; i < state.argCount; ++i) {
164 if (state.writeFlags[i] && state.argIds[i] != EntityBad)
165 finish_term(state.argIds[i], state.sparseStores[i] !=
nullptr);
static constexpr bool value
True when the type derives from the pair base.
Definition id.h:287