1#include "gaia/config/config.h"
7#include "gaia/ecs/chunk_iterator.h"
8#include "gaia/ecs/id.h"
9#include "gaia/ecs/query.h"
10#include "gaia/mt/jobhandle.h"
12#if GAIA_SYSTEMS_ENABLED
17 inline constexpr const char* sc_system_query_func_str =
"System_exec";
18 util::str_view entity_name(
const World& world, Entity entity);
22 using TSystemExecFunc = std::function<void(Query&, QueryExecType)>;
25 Entity entity = EntityBad;
27 TSystemExecFunc on_each_func;
31 QueryExecType execType = QueryExecType::Default;
33 mt::JobHandle jobHandle = mt::JobNull;
40 if (jobHandle != (mt::JobHandle)mt::JobNull_t{}) {
41 auto& tp = mt::ThreadPool::get();
49 [[maybe_unused]]
auto& queryInfo = query.fetch();
52 const auto name = entity_name(*queryInfo.world(), entity);
53 const char* pScopeName = !name.empty() ? name.data() : sc_system_query_func_str;
54 GAIA_PROF_SCOPE2(pScopeName);
57 on_each_func(query, execType);
61 GAIA_NODISCARD mt::JobHandle job_handle() {
62 if (jobHandle == (mt::JobHandle)mt::JobNull_t{}) {
63 auto& tp = mt::ThreadPool::get();
65 syncJob.func = [&]() {
68 syncJob.flags = mt::JobCreationFlags::ManualDelete;
69 jobHandle = tp.add(syncJob);
75 template <
typename Serializer>
76 void save(Serializer& s)
const {
80 template <
typename Serializer>
81 void load(Serializer& s) {
91 GAIA_ASSERT(m_world.valid(m_entity));
95 auto ss = m_world.acc_mut(m_entity);
96 auto& sys = ss.smut<System_>();
100 const System_& data()
const {
101 auto ss = m_world.acc(m_entity);
102 const auto& sys = ss.get<System_>();
107 SystemBuilder(World& world, Entity entity): m_world(world), m_entity(entity) {}
114 SystemBuilder& kind(QueryCacheKind kind) {
116 data().query.kind(kind);
123 SystemBuilder& scope(QueryCacheScope scope) {
125 data().query.scope(scope);
131 SystemBuilder& add(QueryInput item) {
133 data().query.add(item);
139 SystemBuilder& is(Entity entity,
const QueryTermOptions& options = {}) {
140 return all(Pair(Is, entity), options);
145 SystemBuilder& in(Entity entity, QueryTermOptions options = {}) {
147 return all(Pair(Is, entity), options);
152 SystemBuilder& all(Entity entity,
const QueryTermOptions& options = {}) {
154 data().query.all(entity, options);
158 SystemBuilder& any(Entity entity,
const QueryTermOptions& options = {}) {
160 data().query.any(entity, options);
164 SystemBuilder& or_(Entity entity,
const QueryTermOptions& options = {}) {
166 data().query.or_(entity, options);
170 SystemBuilder& no(Entity entity,
const QueryTermOptions& options = {}) {
172 data().query.no(entity, options);
176 SystemBuilder& match_prefab() {
178 data().query.match_prefab();
182 SystemBuilder& changed(Entity entity) {
184 data().query.changed(entity);
188 template <
typename T>
189 SystemBuilder& all(
const QueryTermOptions& options) {
191 data().query.template all<T>(options);
195 template <
typename T>
196 SystemBuilder& any(
const QueryTermOptions& options) {
198 data().query.template any<T>(options);
202 template <
typename T>
203 SystemBuilder& or_(
const QueryTermOptions& options) {
205 data().query.template or_<T>(options);
209 template <
typename T>
210 SystemBuilder& no(
const QueryTermOptions& options) {
212 data().query.template no<T>(options);
218 template <
typename T>
219 SystemBuilder& all() {
221 data().query.all<T>();
225 template <
typename T>
226 SystemBuilder& any() {
228 data().query.any<T>();
232 template <
typename T>
233 SystemBuilder& or_() {
235 data().query.or_<T>();
239 template <
typename T>
240 SystemBuilder& no() {
242 data().query.no<T>();
246 template <
typename T>
247 SystemBuilder& changed() {
249 data().query.changed<T>();
257 SystemBuilder& depth_order(Entity relation = ChildOf) {
258 data().query.depth_order(relation);
264 template <
typename Rel>
265 SystemBuilder& depth_order() {
266 data().query.template depth_order<Rel>();
275 SystemBuilder& group_by(Entity entity, TGroupByFunc func = group_by_func_default) {
276 data().query.group_by(entity, func);
283 template <
typename T>
284 SystemBuilder& group_by(TGroupByFunc func = group_by_func_default) {
285 data().query.group_by<T>(func);
293 template <
typename Rel,
typename Tgt>
294 SystemBuilder& group_by(TGroupByFunc func = group_by_func_default) {
295 data().query.group_by<Rel, Tgt>(func);
304 SystemBuilder& group_dep(Entity relation) {
305 data().query.group_dep(relation);
312 template <
typename Rel>
313 SystemBuilder& group_dep() {
314 data().query.template group_dep<Rel>();
322 SystemBuilder& group_id(GroupId groupId) {
323 data().query.group_id(groupId);
329 SystemBuilder& group_id(Entity entity) {
330 GAIA_ASSERT(!entity.pair());
331 data().query.group_id(entity.id());
337 template <
typename T>
338 SystemBuilder& group_id() {
339 data().query.template group_id<T>();
345 SystemBuilder& name(
const char* name, uint32_t len = 0) {
346 m_world.name(m_entity, name, len);
350 SystemBuilder& name_raw(
const char* name, uint32_t len = 0) {
351 m_world.name_raw(m_entity, name, len);
357 SystemBuilder& mode(QueryExecType type) {
363 template <
typename Func>
364 SystemBuilder& on_each(Func func) {
368 using InputArgs =
decltype(core::func_args(&Func::operator()));
370 #if GAIA_ASSERT_ENABLED
375 !std::is_invocable_v<Func, IterAll&> &&
376 !std::is_invocable_v<Func, Iter&> &&
377 !std::is_invocable_v<Func, IterDisabled&>
379 auto& queryInfo = ctx.query.fetch();
380 GAIA_ASSERT(ctx.query.unpack_args_into_query_has_all(queryInfo, InputArgs{}));
384 ctx.on_each_func = [func](Query& query, QueryExecType execType) {
385 query.each(func, execType);
388 return (SystemBuilder&)*
this;
391 GAIA_NODISCARD Entity entity()
const {
400 GAIA_NODISCARD mt::JobHandle job_handle() {
402 return ctx.job_handle();
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9