17template<
typename Base,
typename ... Components>
20 : term_index_(term_index)
24 Base& query_flags(ecs_flags32_t flags) {
25 desc_->
flags |= flags;
29 Base& cache_kind(query_cache_kind_t kind) {
35 return cache_kind(flecs::QueryCacheAuto);
38 Base& expr(
const char *expr) {
39 ecs_check(expr_count_ == 0, ECS_INVALID_OPERATION,
40 "query_builder::expr() called more than once");
55 _::type_to_inout<T>());
65 Base& with(
const char *name) {
71 Base& with(
const char *first,
const char *second) {
73 *this->term_ =
flecs::term().first(first).second(second);
77 Base& with(entity_t r, entity_t o) {
83 Base& with(entity_t r,
const char *o) {
89 Base& with(
const char *r, entity_t o) {
95 template<
typename First>
100 template<
typename First>
101 Base& with(
const char *second) {
105 template<
typename First,
typename Second>
110 template <typename E, if_t< is_enum<E>::value > = 0>
111 Base& with(E value) {
113 auto o = enum_type<E>(this->world_v()).entity(value);
114 return this->with(r, o);
131 template <
typename ... Args>
132 Base& without(Args&&... args) {
133 return this->with(FLECS_FWD(args)...).not_();
136 template <
typename T,
typename ... Args>
137 Base& without(Args&&... args) {
138 return this->with<T>(FLECS_FWD(args)...).not_();
141 template <
typename First,
typename Second>
143 return this->with<First, Second>().not_();
153 template <
typename ... Args>
154 Base& write(Args&&... args) {
155 return this->with(FLECS_FWD(args)...).write();
158 template <
typename T,
typename ... Args>
159 Base& write(Args&&... args) {
160 return this->with<T>(FLECS_FWD(args)...).write();
163 template <
typename First,
typename Second>
165 return this->with<First, Second>().write();
173 template <
typename ... Args>
174 Base& read(Args&&... args) {
175 return this->with(FLECS_FWD(args)...).read();
178 template <
typename T,
typename ... Args>
179 Base& read(Args&&... args) {
180 return this->with<T>(FLECS_FWD(args)...).read();
183 template <
typename First,
typename Second>
185 return this->with<First, Second>().read();
190 return this->with(flecs::ScopeOpen).entity(0);
193 Base& scope_close() {
194 return this->with(flecs::ScopeClose).entity(0);
204 ECS_INVALID_OPERATION,
205 "query_builder::term() called without initializing term");
209 ECS_INVALID_PARAMETER,
"maximum number of terms exceeded");
211 this->set_term(&desc_->
terms[term_index_]);
223 template <
typename T>
226 for (
int i = 0; i < term_index_; i ++) {
231 if ((term_id == cur_term_id || (cur_term_id != 0 && term_id ==
ecs_get_typeid(this->world_v(), cur_term_id))) ||
232 (term_id == cur_term_pair || (cur_term_pair != 0 && term_id ==
ecs_get_typeid(this->world_v(), cur_term_pair)))) {
237 ecs_err(
"term not found");
244 ecs_assert(term_index >= 0, ECS_INVALID_PARAMETER, NULL);
245 int32_t prev_index = term_index_;
246 term_index_ = term_index;
248 term_index_ = prev_index;
250 ECS_INVALID_PARAMETER, NULL);
256 template <
typename T>
259#if !defined(FLECS_NDEBUG) || defined(FLECS_KEEP_ASSERT)
265 ecs_assert((term_id == cur_term_id || (cur_term_id != 0 && term_id ==
ecs_get_typeid(this->world_v(), cur_term_id))) ||
266 (term_id == cur_term_pair || (cur_term_pair != 0 && term_id ==
ecs_get_typeid(this->world_v(), cur_term_pair))),
267 ECS_INVALID_PARAMETER,
"term type mismatch");
290 template <
typename T>
291 Base&
order_by(
int(*compare)(flecs::entity_t,
const T*, flecs::entity_t,
const T*)) {
302 Base&
order_by(flecs::entity_t
component,
int(*compare)(flecs::entity_t,
const void*, flecs::entity_t,
const void*)) {
325 template <
typename T>
326 Base&
group_by(uint64_t(*group_by_action)(flecs::world_t*, flecs::table_t *
table, flecs::id_t
id,
void* ctx)) {
337 Base&
group_by(flecs::entity_t
component, uint64_t(*group_by_action)(flecs::world_t*, flecs::table_t *
table, flecs::id_t
id,
void* ctx)) {
348 template <
typename T>
359 return this->
group_by(component,
nullptr);
388 virtual flecs::world_t* world_v()
override = 0;
394 return *
static_cast<Base*
>(
this);
#define ecs_assert(condition, error_code,...)
Assert.
#define ecs_check(condition, error_code,...)
Check.
uint64_t ecs_id_t
Ids are the things that can be added to an entity.
uint64_t(* ecs_group_by_action_t)(ecs_world_t *world, ecs_table_t *table, ecs_id_t group_id, void *ctx)
Callback used for grouping tables in a query.
void(* ecs_group_delete_action_t)(ecs_world_t *world, uint64_t group_id, void *group_ctx, void *group_by_ctx)
Callback invoked when a query deletes an existing group.
void *(* ecs_group_create_action_t)(ecs_world_t *world, uint64_t group_id, void *group_by_ctx)
Callback invoked when a query creates a new group.
void(* ecs_ctx_free_t)(void *ctx)
Function to cleanup context data.
int(* ecs_order_by_action_t)(ecs_entity_t e1, const void *ptr1, ecs_entity_t e2, const void *ptr2)
Callback used for comparing components.
ecs_entity_t ecs_get_typeid(const ecs_world_t *world, ecs_id_t id)
Get the type for an id.
#define FLECS_TERM_COUNT_MAX
Maximum number of terms in queries.
bool ecs_term_is_initialized(const ecs_term_t *term)
Test whether a term is set.
ecs_query_cache_kind_t
Specify cache policy for query.
ecs_inout_kind_t
Specify read/write access for term.
Used with ecs_query_init().
ecs_id_t group_by
Component id to be used for grouping.
ecs_term_t terms[32]
Query terms.
ecs_ctx_free_t group_by_ctx_free
Function to free group_by_ctx.
void * group_by_ctx
Context to pass to group_by.
ecs_entity_t order_by
Component to sort on, used together with order_by_callback or order_by_table_callback.
ecs_order_by_action_t order_by_callback
Callback used for ordering query results.
ecs_group_create_action_t on_group_create
Callback that is invoked when a new group is created.
ecs_group_by_action_t group_by_callback
Callback used for grouping results.
ecs_group_delete_action_t on_group_delete
Callback that is invoked when an existing group is deleted.
ecs_flags32_t flags
Flags for enabling query features.
ecs_query_cache_kind_t cache_kind
Caching policy of query.
const char * expr
Query DSL expression (optional)
ecs_entity_t id
Entity id.
Type that describes a term (single element in a query).
ecs_id_t id
Component id to be matched by term.
ecs_term_ref_t second
Second element of pair.
int16_t inout
Access to contents matched by term.
ecs_term_ref_t first
Component or first element of pair.
Base & term_at(int32_t term_index)
Sets the current term to the one at the provided index and asserts that the type matches.
Base & group_by()
Group and sort matched tables.
Base & on_group_delete(ecs_group_delete_action_t action)
Specify on_group_delete action.
Base & group_by(flecs::entity_t component, uint64_t(*group_by_action)(flecs::world_t *, flecs::table_t *table, flecs::id_t id, void *ctx))
Group and sort matched tables.
Base & on_group_create(ecs_group_create_action_t action)
Specify on_group_create action.
Base & group_by(flecs::entity_t component)
Group and sort matched tables.
Base & group_by(uint64_t(*group_by_action)(flecs::world_t *, flecs::table_t *table, flecs::id_t id, void *ctx))
Group and sort matched tables.
Base & term_at(int32_t term_index)
Sets the current term to the one at the provided index.
Base & term()
Sets the current term to next one in term list.
Base & order_by(int(*compare)(flecs::entity_t, const T *, flecs::entity_t, const T *))
Sort the output of a query.
Base & group_by_ctx(void *ctx, ecs_ctx_free_t ctx_free=nullptr)
Specify context to be passed to group_by function.
Base & term_at()
Sets the current term to the one with the provided type.
Base & order_by(flecs::entity_t component, int(*compare)(flecs::entity_t, const void *, flecs::entity_t, const void *))
Sort the output of a query.
Base & read()
Short for inout_stage(flecs::In).
Base & write()
Short for inout_stage(flecs::Out).
Class that describes a term.