3#include "gaia/config/config.h"
7#include "gaia/ecs/id.h"
8#include "gaia/ecs/query.h"
9#include "gaia/util/move_func.h"
11#if GAIA_OBSERVERS_ENABLED
18 inline constexpr const char* sc_observer_query_func_str =
"Observer_exec";
19 util::str_view entity_name(
const World& world, Entity entity);
30 enum class ObserverEvent : uint8_t {
38 struct ObserverContext {
43 Archetype* archetype_prev;
44 uint32_t index_in_chunk;
51 enum class ExecKind : uint8_t { DirectQuery, DirectFast, DiffLocal, DiffPropagated, DiffFallback };
52 enum class FastPath : uint8_t { None, SinglePositiveTerm, SingleNegativeTerm, Disabled };
53 using TObserverIterFunc = util::MoveFunc<void(Iter&)>;
56 enum class DispatchKind : uint8_t { LocalTargets, PropagatedTraversal, GlobalFallback };
59 Entity bindingVar = EntityBad;
61 Entity bindingRelation = EntityBad;
63 Entity traversalRelation = EntityBad;
66 DispatchKind dispatchKind = DispatchKind::LocalTargets;
68 QueryTravKind travKind = QueryTravKind::None;
72 uint8_t travDepth = QueryTermOptions::TravDepthUnlimited;
74 QueryEntityArray traversalTriggerTerms{};
76 uint8_t traversalTriggerTermCount = 0;
78 QueryEntityArray traversalRelations{};
80 uint8_t traversalRelationCount = 0;
84 FastPath fastPath = FastPath::None;
86 uint8_t termCount = 0;
88 ExecKind execKind = ExecKind::DirectQuery;
92 void refresh_exec_kind() {
94 switch (diff.dispatchKind) {
95 case DiffPlan::DispatchKind::LocalTargets:
96 execKind = ExecKind::DiffLocal;
98 case DiffPlan::DispatchKind::PropagatedTraversal:
99 execKind = ExecKind::DiffPropagated;
101 case DiffPlan::DispatchKind::GlobalFallback:
102 execKind = ExecKind::DiffFallback;
105 }
else if (fastPath == FastPath::SinglePositiveTerm || fastPath == FastPath::SingleNegativeTerm)
106 execKind = ExecKind::DirectFast;
108 execKind = ExecKind::DirectQuery;
111 GAIA_NODISCARD ExecKind exec_kind()
const {
115 GAIA_NODISCARD
bool uses_diff_dispatch()
const {
116 switch (exec_kind()) {
117 case ExecKind::DiffLocal:
118 case ExecKind::DiffPropagated:
119 case ExecKind::DiffFallback:
121 case ExecKind::DirectQuery:
122 case ExecKind::DirectFast:
129 GAIA_NODISCARD
bool uses_direct_dispatch()
const {
130 return !uses_diff_dispatch();
133 GAIA_NODISCARD
bool uses_local_diff_targets()
const {
134 return exec_kind() == ExecKind::DiffLocal;
137 GAIA_NODISCARD
bool uses_propagated_diff_targets()
const {
138 return exec_kind() == ExecKind::DiffPropagated;
141 GAIA_NODISCARD
bool uses_fallback_diff_dispatch()
const {
142 return exec_kind() == ExecKind::DiffFallback;
145 GAIA_NODISCARD
bool is_fast_positive()
const {
146 return fastPath == FastPath::SinglePositiveTerm;
149 GAIA_NODISCARD
bool is_fast_negative()
const {
150 return fastPath == FastPath::SingleNegativeTerm;
153 void add_term_descriptor(QueryOpKind op,
bool allowFastPath) {
156 if (!allowFastPath) {
157 fastPath = FastPath::Disabled;
161 if (fastPath == FastPath::Disabled)
164 if (termCount != 1) {
165 fastPath = FastPath::Disabled;
170 case QueryOpKind::All:
171 case QueryOpKind::Any:
172 case QueryOpKind::Or:
173 fastPath = FastPath::SinglePositiveTerm;
175 case QueryOpKind::Not:
176 fastPath = FastPath::SingleNegativeTerm;
179 fastPath = FastPath::Disabled;
188 struct ObserverRuntimeData {
189 using TObserverIterFunc = util::MoveFunc<void(Iter&)>;
191 ObserverRuntimeData() {
192 GAIA_FOR(MAX_ITEMS_IN_QUERY) {
193 queryTermIds[i] = EntityBad;
198 Entity entity = EntityBad;
200 TObserverIterFunc on_each_func;
206 QueryEntityArray queryTermIds{};
208 uint64_t lastMatchStamp = 0;
210 void exec(Iter& iter, EntitySpan targets);
216 Entity entity = EntityBad;
218 ObserverEvent
event = ObserverEvent::OnAdd;
221 template <
typename Serializer>
222 void save(Serializer& s)
const {
226 template <
typename Serializer>
227 void load(Serializer& s) {
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Definition observer.h:237