3#include "gaia/config/config.h"
9#include "gaia/ecs/id.h"
10#include "gaia/ecs/query.h"
12#if GAIA_OBSERVERS_ENABLED
19 inline constexpr const char* sc_observer_query_func_str =
"Observer_exec";
20 util::str_view entity_name(
const World& world, Entity entity);
31 enum class ObserverEvent : uint8_t {
39 struct ObserverContext {
44 Archetype* archetype_prev;
45 uint32_t index_in_chunk;
52 enum class ExecKind : uint8_t { DirectQuery, DirectFast, DiffLocal, DiffPropagated, DiffFallback };
53 enum class FastPath : uint8_t { None, SinglePositiveTerm, SingleNegativeTerm, Disabled };
54 using TObserverIterFunc = std::function<void(Iter&)>;
57 enum class DispatchKind : uint8_t { LocalTargets, PropagatedTraversal, GlobalFallback };
60 Entity bindingVar = EntityBad;
62 Entity bindingRelation = EntityBad;
64 Entity traversalRelation = EntityBad;
67 DispatchKind dispatchKind = DispatchKind::LocalTargets;
69 QueryTravKind travKind = QueryTravKind::None;
73 uint8_t travDepth = QueryTermOptions::TravDepthUnlimited;
75 QueryEntityArray traversalTriggerTerms{};
77 uint8_t traversalTriggerTermCount = 0;
79 QueryEntityArray traversalRelations{};
81 uint8_t traversalRelationCount = 0;
85 FastPath fastPath = FastPath::None;
87 uint8_t termCount = 0;
89 ExecKind execKind = ExecKind::DirectQuery;
93 void refresh_exec_kind() {
95 switch (diff.dispatchKind) {
96 case DiffPlan::DispatchKind::LocalTargets:
97 execKind = ExecKind::DiffLocal;
99 case DiffPlan::DispatchKind::PropagatedTraversal:
100 execKind = ExecKind::DiffPropagated;
102 case DiffPlan::DispatchKind::GlobalFallback:
103 execKind = ExecKind::DiffFallback;
106 }
else if (fastPath == FastPath::SinglePositiveTerm || fastPath == FastPath::SingleNegativeTerm)
107 execKind = ExecKind::DirectFast;
109 execKind = ExecKind::DirectQuery;
112 GAIA_NODISCARD ExecKind exec_kind()
const {
116 GAIA_NODISCARD
bool uses_diff_dispatch()
const {
117 switch (exec_kind()) {
118 case ExecKind::DiffLocal:
119 case ExecKind::DiffPropagated:
120 case ExecKind::DiffFallback:
122 case ExecKind::DirectQuery:
123 case ExecKind::DirectFast:
130 GAIA_NODISCARD
bool uses_direct_dispatch()
const {
131 return !uses_diff_dispatch();
134 GAIA_NODISCARD
bool uses_local_diff_targets()
const {
135 return exec_kind() == ExecKind::DiffLocal;
138 GAIA_NODISCARD
bool uses_propagated_diff_targets()
const {
139 return exec_kind() == ExecKind::DiffPropagated;
142 GAIA_NODISCARD
bool uses_fallback_diff_dispatch()
const {
143 return exec_kind() == ExecKind::DiffFallback;
146 GAIA_NODISCARD
bool is_fast_positive()
const {
147 return fastPath == FastPath::SinglePositiveTerm;
150 GAIA_NODISCARD
bool is_fast_negative()
const {
151 return fastPath == FastPath::SingleNegativeTerm;
154 void add_term_descriptor(QueryOpKind op,
bool allowFastPath) {
157 if (!allowFastPath) {
158 fastPath = FastPath::Disabled;
162 if (fastPath == FastPath::Disabled)
165 if (termCount != 1) {
166 fastPath = FastPath::Disabled;
171 case QueryOpKind::All:
172 case QueryOpKind::Any:
173 case QueryOpKind::Or:
174 fastPath = FastPath::SinglePositiveTerm;
176 case QueryOpKind::Not:
177 fastPath = FastPath::SingleNegativeTerm;
180 fastPath = FastPath::Disabled;
189 struct ObserverRuntimeData {
190 using TObserverIterFunc = std::function<void(Iter&)>;
192 ObserverRuntimeData() {
193 GAIA_FOR(MAX_ITEMS_IN_QUERY) {
194 queryTermIds[i] = EntityBad;
199 Entity entity = EntityBad;
201 TObserverIterFunc on_each_func;
207 QueryEntityArray queryTermIds{};
209 uint64_t lastMatchStamp = 0;
211 void exec(Iter& iter, EntitySpan targets);
217 Entity entity = EntityBad;
219 ObserverEvent
event = ObserverEvent::OnAdd;
222 template <
typename Serializer>
223 void save(Serializer& s)
const {
227 template <
typename Serializer>
228 void load(Serializer& s) {
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Definition observer.h:238