code: updated flecs to 2.4.1

isolation_bkp/dynres
Dominik Madarász 2021-08-15 18:32:11 +02:00
parent 2b891f1cb1
commit 148ddcd2c0
5 changed files with 523 additions and 300 deletions

View File

@ -10,6 +10,7 @@ typedef enum {
// NOTE(zaklaus): Special actions // NOTE(zaklaus): Special actions
RPKIND_SPAWN_CAR, RPKIND_SPAWN_CAR,
RPKIND_PLACE_ICE_RINK, RPKIND_PLACE_ICE_RINK,
RPKIND_SPAWN_CIRCLING_DRIVER,
} replay_kind; } replay_kind;
typedef struct { typedef struct {
@ -150,6 +151,7 @@ void debug_replay_run(void) {
} }
void ActPlaceIceRink(); void ActPlaceIceRink();
void ActSpawnCirclingDriver(void);
void debug_replay_update(void) { void debug_replay_update(void) {
if (!is_playing) return; if (!is_playing) return;
@ -178,6 +180,9 @@ void debug_replay_update(void) {
case RPKIND_PLACE_ICE_RINK: { case RPKIND_PLACE_ICE_RINK: {
ActPlaceIceRink(); ActPlaceIceRink();
}break; }break;
case RPKIND_SPAWN_CIRCLING_DRIVER: {
ActSpawnCirclingDriver();
}break;
default: { default: {
ZPL_PANIC("unreachable"); ZPL_PANIC("unreachable");
}break; }break;

View File

@ -112,6 +112,7 @@ static debug_item items[] = {
.items = (debug_item[]) { .items = (debug_item[]) {
{ .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar }, { .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar },
{ .kind = DITEM_BUTTON, .name = "place ice rink", .on_click = ActPlaceIceRink }, { .kind = DITEM_BUTTON, .name = "place ice rink", .on_click = ActPlaceIceRink },
{ .kind = DITEM_BUTTON, .name = "spawn circling driver", .on_click = ActSpawnCirclingDriver },
{ {
.kind = DITEM_LIST, .kind = DITEM_LIST,
.name = "demo npcs", .name = "demo npcs",

View File

@ -18,6 +18,30 @@ ActSpawnCar(void) {
debug_replay_special_action(RPKIND_SPAWN_CAR); debug_replay_special_action(RPKIND_SPAWN_CAR);
} }
void
ActSpawnCirclingDriver(void) {
ecs_entity_t plr = camera_get().ent_id;
ecs_entity_t ve = vehicle_spawn();
ecs_entity_t e = entity_spawn(EKIND_DEMO_NPC);
Position const *origin = ecs_get(world_ecs(), plr, Position);
Position *veh_dest = ecs_get_mut(world_ecs(), ve, Position, NULL);
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
*veh_dest = *origin;
*dest = *origin;
Input *input = ecs_get_mut(world_ecs(), e, Input, NULL);
input->x = input->y = 1.0f;
input->use = false;
Vehicle *veh = ecs_get_mut(world_ecs(), ve, Vehicle, NULL);
veh->seats[0] = e;
ecs_set(world_ecs(), e, IsInVehicle, { .veh = ve });
debug_replay_special_action(RPKIND_SPAWN_CIRCLING_DRIVER);
}
void void
ActPlaceIceRink(void) { ActPlaceIceRink(void) {
ecs_entity_t plr = camera_get().ent_id; ecs_entity_t plr = camera_get().ent_id;

View File

@ -2948,8 +2948,9 @@ void dtor_component(
if (cdata && (dtor = cdata->lifecycle.dtor)) { if (cdata && (dtor = cdata->lifecycle.dtor)) {
void *ctx = cdata->lifecycle.ctx; void *ctx = cdata->lifecycle.ctx;
int16_t size = column->size; int16_t size = column->size;
int16_t alignment = column->alignment; int16_t alignment = column->alignment;
ecs_assert(column->data != NULL, ECS_INTERNAL_ERROR, NULL);
void *ptr = ecs_vector_get_t(column->data, size, alignment, row); void *ptr = ecs_vector_get_t(column->data, size, alignment, row);
ecs_assert(ptr != NULL, ECS_INTERNAL_ERROR, NULL); ecs_assert(ptr != NULL, ECS_INTERNAL_ERROR, NULL);
@ -4549,6 +4550,9 @@ bool flecs_table_match_filter(
const ecs_table_t *table, const ecs_table_t *table,
const ecs_filter_t * filter) const ecs_filter_t * filter)
{ {
ecs_assert(world != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
if (!filter) { if (!filter) {
return true; return true;
} }
@ -4767,13 +4771,13 @@ void* get_base_component(
ecs_type_t type = table->type; ecs_type_t type = table->type;
ecs_id_t *ids = ecs_vector_first(type, ecs_id_t); ecs_id_t *ids = ecs_vector_first(type, ecs_id_t);
int32_t i = tr_isa->column, count = tr_isa->count; int32_t i = tr_isa->column, end = tr_isa->count + tr_isa->column;
void *ptr = NULL; void *ptr = NULL;
do { do {
ecs_id_t pair = ids[i]; ecs_id_t pair = ids[i ++];
ecs_entity_t base = ecs_pair_object(world, pair); ecs_entity_t base = ecs_pair_object(world, pair);
ecs_record_t *r = ecs_eis_get(world, base); ecs_record_t *r = ecs_eis_get(world, base);
if (!r) { if (!r) {
continue; continue;
@ -4794,8 +4798,7 @@ void* get_base_component(
int32_t row = flecs_record_to_row(r->row, &is_monitored); int32_t row = flecs_record_to_row(r->row, &is_monitored);
ptr = get_component_w_index(table, tr->column, row); ptr = get_component_w_index(table, tr->column, row);
} }
i ++; } while (!ptr && (i < end));
} while (!ptr && (i < count));
return ptr; return ptr;
} }
@ -6275,7 +6278,7 @@ ecs_entity_t ecs_new_id(
} }
ecs_assert(!unsafe_world->stats.max_id || ecs_assert(!unsafe_world->stats.max_id ||
entity <= unsafe_world->stats.max_id, ecs_entity_t_lo(entity) <= unsafe_world->stats.max_id,
ECS_OUT_OF_RANGE, NULL); ECS_OUT_OF_RANGE, NULL);
return entity; return entity;
@ -6444,7 +6447,7 @@ ecs_table_t *traverse_from_expr(
if (ptr) { if (ptr) {
ecs_term_t term = {0}; ecs_term_t term = {0};
while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))){ while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))){
if (!ecs_term_is_set(&term)) { if (!ecs_term_is_initialized(&term)) {
break; break;
} }
@ -6530,7 +6533,7 @@ void defer_from_expr(
if (ptr) { if (ptr) {
ecs_term_t term = {0}; ecs_term_t term = {0};
while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))) { while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))) {
if (!ecs_term_is_set(&term)) { if (!ecs_term_is_initialized(&term)) {
break; break;
} }
@ -7891,6 +7894,8 @@ ecs_entity_t ecs_get_case(
ecs_assert(ecs_is_valid(world, entity), ECS_INVALID_PARAMETER, NULL); ecs_assert(ecs_is_valid(world, entity), ECS_INVALID_PARAMETER, NULL);
ecs_assert(ecs_is_valid(world, sw_id), ECS_INVALID_PARAMETER, NULL); ecs_assert(ecs_is_valid(world, sw_id), ECS_INVALID_PARAMETER, NULL);
world = ecs_get_world(world);
ecs_entity_info_t info; ecs_entity_info_t info;
ecs_table_t *table; ecs_table_t *table;
if (!flecs_get_info(world, entity, &info) || !(table = info.table)) { if (!flecs_get_info(world, entity, &info) || !(table = info.table)) {
@ -11270,7 +11275,7 @@ int ecs_plecs_from_str(
} }
while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))) { while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))) {
if (!ecs_term_is_set(&term)) { if (!ecs_term_is_initialized(&term)) {
break; break;
} }
@ -12203,10 +12208,7 @@ ecs_data_t* duplicate_data(
ecs_entity_t component = components[i]; ecs_entity_t component = components[i];
ecs_column_t *column = &result->columns[i]; ecs_column_t *column = &result->columns[i];
if (component > ECS_HI_COMPONENT_ID) { component = ecs_get_typeid(world, component);
column->data = NULL;
continue;
}
const ecs_type_info_t *cdata = flecs_get_c_info(world, component); const ecs_type_info_t *cdata = flecs_get_c_info(world, component);
int16_t size = column->size; int16_t size = column->size;
@ -12287,7 +12289,6 @@ ecs_snapshot_t* snapshot_create(
} }
ecs_table_leaf_t *l = ecs_vector_add(&result->tables, ecs_table_leaf_t); ecs_table_leaf_t *l = ecs_vector_add(&result->tables, ecs_table_leaf_t);
l->table = t; l->table = t;
l->type = t->type; l->type = t->type;
l->data = duplicate_data(world, t, data); l->data = duplicate_data(world, t, data);
@ -16601,6 +16602,12 @@ bool ecs_id_match(
return false; return false;
} }
bool ecs_id_is_pair(
ecs_id_t id)
{
return ECS_HAS_ROLE(id, PAIR);
}
bool ecs_id_is_wildcard( bool ecs_id_is_wildcard(
ecs_id_t id) ecs_id_t id)
{ {
@ -16620,7 +16627,7 @@ bool ecs_term_id_is_set(
return id->entity != 0 || id->name != NULL; return id->entity != 0 || id->name != NULL;
} }
bool ecs_term_is_set( bool ecs_term_is_initialized(
const ecs_term_t *term) const ecs_term_t *term)
{ {
return term->id != 0 || ecs_term_id_is_set(&term->pred); return term->id != 0 || ecs_term_id_is_set(&term->pred);
@ -16819,7 +16826,7 @@ int ecs_filter_init(
} else { } else {
terms = (ecs_term_t*)desc->terms; terms = (ecs_term_t*)desc->terms;
for (i = 0; i < ECS_TERM_CACHE_SIZE; i ++) { for (i = 0; i < ECS_TERM_CACHE_SIZE; i ++) {
if (!ecs_term_is_set(&terms[i])) { if (!ecs_term_is_initialized(&terms[i])) {
break; break;
} }
@ -16848,7 +16855,7 @@ int ecs_filter_init(
const char *ptr = desc->expr; const char *ptr = desc->expr;
ecs_term_t term = {0}; ecs_term_t term = {0};
while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))){ while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))){
if (!ecs_term_is_set(&term)) { if (!ecs_term_is_initialized(&term)) {
break; break;
} }
@ -16925,6 +16932,42 @@ error:
return -1; return -1;
} }
void ecs_filter_copy(
ecs_filter_t *dst,
const ecs_filter_t *src)
{
if (src) {
*dst = *src;
if (src->terms == src->term_cache) {
dst->terms = dst->term_cache;
} else {
/* Copying allocated term arrays is unsupported at this moment */
ecs_abort(ECS_UNSUPPORTED, NULL);
}
} else {
ecs_os_memset_t(dst, 0, ecs_filter_t);
}
}
void ecs_filter_move(
ecs_filter_t *dst,
ecs_filter_t *src)
{
if (src) {
*dst = *src;
if (src->terms == src->term_cache) {
dst->terms = dst->term_cache;
}
src->terms = NULL;
src->term_count = 0;
} else {
ecs_os_memset_t(dst, 0, ecs_filter_t);
}
}
void ecs_filter_fini( void ecs_filter_fini(
ecs_filter_t *filter) ecs_filter_t *filter)
{ {
@ -17195,6 +17238,10 @@ bool flecs_filter_match_table(
result = !result; result = !result;
} }
if (oper == EcsOptional) {
result = true;
}
if (is_or) { if (is_or) {
or_result |= result; or_result |= result;
} else if (!result) { } else if (!result) {
@ -17215,16 +17262,14 @@ bool flecs_filter_match_table(
int32_t t_i = term->index; int32_t t_i = term->index;
void **ptr = ptrs ? &ptrs[t_i] : NULL; void **ptr = ptrs ? &ptrs[t_i] : NULL;
bool has_data = populate_from_column(world, table, term->id, column, populate_from_column(world, table, term->id, column,
source, &ids[t_i], &types[t_i], &subjects[t_i], &sizes[t_i], source, &ids[t_i], &types[t_i], &subjects[t_i], &sizes[t_i],
ptr); ptr);
if (!source) { if (column != -1) {
if (has_data) { columns[t_i] = column + 1;
columns[t_i] = column + 1; } else {
} else { columns[t_i] = 0;
columns[t_i] = 0;
}
} }
} }
} }
@ -17427,7 +17472,7 @@ ecs_iter_t ecs_filter_iter(
const ecs_filter_t *filter) const ecs_filter_t *filter)
{ {
ecs_assert(world != NULL, ECS_INVALID_PARAMETER, NULL); ecs_assert(world != NULL, ECS_INVALID_PARAMETER, NULL);
ecs_iter_t it = { ecs_iter_t it = {
.world = world .world = world
}; };
@ -19717,8 +19762,6 @@ add_pair:
references = add_ref(world, query, references, term, references = add_ref(world, query, references, term,
component, entity); component, entity);
table_data.columns[c] = -ecs_vector_count(references); table_data.columns[c] = -ecs_vector_count(references);
} else {
table_data.columns[c] = 0;
} }
table_data.subjects[c] = entity; table_data.subjects[c] = entity;
@ -19729,9 +19772,7 @@ add_pair:
const EcsComponent *cptr = ecs_get(world, type_id, EcsComponent); const EcsComponent *cptr = ecs_get(world, type_id, EcsComponent);
if (!cptr || !cptr->size) { if (!cptr || !cptr->size) {
int32_t column = table_data.columns[c]; int32_t column = table_data.columns[c];
if (column > 0) { if (column < 0) {
table_data.columns[c] = 0;
} else if (column) {
ecs_ref_t *r = ecs_vector_get( ecs_ref_t *r = ecs_vector_get(
references, ecs_ref_t, -column - 1); references, ecs_ref_t, -column - 1);
r->component = 0; r->component = 0;
@ -21877,11 +21918,12 @@ void mark_columns_dirty(
for (i = 0; i < count; i ++) { for (i = 0; i < count; i ++) {
ecs_term_t *term = &terms[i]; ecs_term_t *term = &terms[i];
ecs_term_id_t *subj = &term->args[0]; ecs_term_id_t *subj = &term->args[0];
if (term->inout != EcsIn && (term->inout != EcsInOutDefault || if (term->inout != EcsIn && (term->inout != EcsInOutDefault ||
(subj->entity == EcsThis && subj->set.mask == EcsSelf))) (subj->entity == EcsThis && subj->set.mask == EcsSelf)))
{ {
int32_t table_column = table_data->columns[c]; int32_t table_column = table_data->columns[c];
if (table_column > 0) { if (table_column > 0 && table_column <= table->column_count) {
table->dirty_state[table_column] ++; table->dirty_state[table_column] ++;
} }
} }
@ -23708,6 +23750,7 @@ bool ecs_term_is_owned(
int32_t term) int32_t term)
{ {
ecs_assert(it->is_valid, ECS_INVALID_PARAMETER, NULL); ecs_assert(it->is_valid, ECS_INVALID_PARAMETER, NULL);
ecs_assert(term > 0, ECS_INVALID_PARAMETER, NULL);
return it->subjects == NULL || it->subjects[term - 1] == 0; return it->subjects == NULL || it->subjects[term - 1] == 0;
} }
@ -23716,6 +23759,7 @@ bool ecs_term_is_readonly(
int32_t term_index) int32_t term_index)
{ {
ecs_assert(it->is_valid, ECS_INVALID_PARAMETER, NULL); ecs_assert(it->is_valid, ECS_INVALID_PARAMETER, NULL);
ecs_assert(term_index > 0, ECS_INVALID_PARAMETER, NULL);
ecs_query_t *query = it->query; ecs_query_t *query = it->query;
@ -23743,10 +23787,21 @@ bool ecs_term_is_readonly(
} }
} }
} }
return false; return false;
} }
bool ecs_term_is_set(
const ecs_iter_t *it,
int32_t term)
{
ecs_assert(it->is_valid, ECS_INVALID_PARAMETER, NULL);
ecs_assert(it->columns != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(term > 0, ECS_INVALID_PARAMETER, NULL);
return it->columns[term - 1] != 0;
}
ecs_entity_t ecs_term_source( ecs_entity_t ecs_term_source(
const ecs_iter_t *it, const ecs_iter_t *it,
int32_t term) int32_t term)
@ -24179,7 +24234,7 @@ ecs_entity_t ecs_trigger_init(
goto error; goto error;
} }
if (!ecs_term_is_set(&term)) { if (!ecs_term_is_initialized(&term)) {
ecs_parser_error( ecs_parser_error(
name, expr, 0, "invalid empty trigger expression"); name, expr, 0, "invalid empty trigger expression");
goto error; goto error;

View File

@ -1109,6 +1109,8 @@ private:
int m_index; int m_index;
}; };
/* C++ class mainly used as wrapper around internal ecs_vector_t. Do not use
* this class as a replacement for STL datastructures! */
template <typename T> template <typename T>
class vector { class vector {
public: public:
@ -1150,6 +1152,10 @@ public:
ecs_vector_clear(m_vector); ecs_vector_clear(m_vector);
} }
void destruct() {
ecs_vector_free(m_vector);
}
void add(T& value) { void add(T& value) {
T* elem = static_cast<T*>(_ecs_vector_add(&m_vector, ECS_VECTOR_T(T))); T* elem = static_cast<T*>(_ecs_vector_add(&m_vector, ECS_VECTOR_T(T)));
*elem = value; *elem = value;
@ -1402,6 +1408,8 @@ void ecs_map_memory(
namespace flecs { namespace flecs {
/* C++ class mainly used as wrapper around internal ecs_map_t. Do not use
* this class as a replacement for STL datastructures! */
template <typename K, typename T> template <typename K, typename T>
class map { class map {
public: public:
@ -1437,6 +1445,10 @@ public:
reinterpret_cast<ecs_map_key_t>(key))); reinterpret_cast<ecs_map_key_t>(key)));
} }
void destruct() {
ecs_map_free(m_map);
}
private: private:
void init(size_t count) { void init(size_t count) {
m_map = ecs_map_new(T, static_cast<ecs_size_t>(count)); m_map = ecs_map_new(T, static_cast<ecs_size_t>(count));
@ -2549,6 +2561,7 @@ struct ecs_iter_t {
ecs_table_t *table; /**< Current table */ ecs_table_t *table; /**< Current table */
ecs_data_t *data; ecs_data_t *data;
ecs_id_t *ids; ecs_id_t *ids;
ecs_type_t *types; ecs_type_t *types;
int32_t *columns; int32_t *columns;
@ -6061,7 +6074,7 @@ bool ecs_term_id_is_set(
* @return True when set, false when not set. * @return True when set, false when not set.
*/ */
FLECS_API FLECS_API
bool ecs_term_is_set( bool ecs_term_is_initialized(
const ecs_term_t *term); const ecs_term_t *term);
/** Test whether a term is a trivial term. /** Test whether a term is a trivial term.
@ -6166,6 +6179,15 @@ bool ecs_id_match(
ecs_id_t id, ecs_id_t id,
ecs_id_t pattern); ecs_id_t pattern);
/** Utility to check if id is a pair.
*
* @param id The id.
* @return True if id is a pair.
*/
FLECS_API
bool ecs_id_is_pair(
ecs_id_t id);
/** Utility to check if id is a wildcard. /** Utility to check if id is a wildcard.
* *
* @param id The id. * @param id The id.
@ -6272,6 +6294,18 @@ FLECS_API
bool ecs_filter_next( bool ecs_filter_next(
ecs_iter_t *iter); ecs_iter_t *iter);
/** Move resources of one filter to another. */
FLECS_API
void ecs_filter_move(
ecs_filter_t *dst,
ecs_filter_t *src);
/** Copy resources of one filter to another. */
FLECS_API
void ecs_filter_copy(
ecs_filter_t *dst,
const ecs_filter_t *src);
/** @} */ /** @} */
/** /**
@ -6673,6 +6707,20 @@ bool ecs_term_is_readonly(
const ecs_iter_t *it, const ecs_iter_t *it,
int32_t index); int32_t index);
/** Test whether term is set.
* This function returns false for terms with the Not operator and for terms
* with the Optional operator if the matched entities (table) do not have the
* (component) id of the term.
*
* @param it The iterator.
* @param term The term.
* @return True if term is set, false if it is not set.
*/
FLECS_API
bool ecs_term_is_set(
const ecs_iter_t *it,
int32_t term);
/** Test whether the term is owned /** Test whether the term is owned
* This operation returns whether the term is owned by the currently iterated * This operation returns whether the term is owned by the currently iterated
* entity. This function will return false when the term is owned by another * entity. This function will return false when the term is owned by another
@ -9248,13 +9296,15 @@ class type;
class pipeline; class pipeline;
class iter; class iter;
class term; class term;
class filter;
class filter_iterator; class filter_iterator;
class child_iterator; class child_iterator;
class world_filter; class world_filter;
class snapshot_filter; class snapshot_filter;
class query_base; class query_base;
template<typename ... Components>
class filter;
template<typename ... Components> template<typename ... Components>
class query; class query;
@ -9264,6 +9314,9 @@ class system;
template<typename ... Components> template<typename ... Components>
class observer; class observer;
template <typename ... Components>
class filter_builder;
template <typename ... Components> template <typename ... Components>
class query_builder; class query_builder;
@ -9448,6 +9501,7 @@ using std::is_const;
using std::is_pointer; using std::is_pointer;
using std::is_reference; using std::is_reference;
using std::is_volatile; using std::is_volatile;
using std::is_same;
// Apply cv modifiers from source type to destination type // Apply cv modifiers from source type to destination type
@ -9966,6 +10020,7 @@ struct function_traits
} // _ } // _
template <typename T> template <typename T>
struct is_callable { struct is_callable {
static constexpr bool value = _::function_traits<T>::is_callable; static constexpr bool value = _::function_traits<T>::is_callable;
@ -9982,6 +10037,23 @@ using return_type_t = typename _::function_traits<T>::return_type;
template <typename T> template <typename T>
using arg_list_t = typename _::function_traits<T>::args; using arg_list_t = typename _::function_traits<T>::args;
template<typename Func, typename ... Args>
struct first_arg_impl;
template<typename Func, typename T, typename ... Args>
struct first_arg_impl<Func, _::arg_list<T, Args ...> > {
using type = T;
};
template<typename Func>
struct first_arg {
using type = typename first_arg_impl<Func, arg_list_t<Func>>::type;
};
template <typename Func>
using first_arg_t = typename first_arg<Func>::type;
} // flecs } // flecs
namespace flecs namespace flecs
{ {
@ -10826,14 +10898,14 @@ public:
*/ */
bool is_owned(int32_t index) const { bool is_owned(int32_t index) const {
return ecs_term_is_owned(m_iter, index); return ecs_term_is_owned(m_iter, index);
} }
/** Returns whether term is set. /** Returns whether term is set.
* *
* @param index The term index. * @param index The term index.
*/ */
bool is_set(int32_t index) const { bool is_set(int32_t index) const {
return ecs_term_w_size(m_iter, 0, index) != NULL; return ecs_term_is_set(m_iter, index);
} }
/** Returns whether term is readonly. /** Returns whether term is readonly.
@ -11744,89 +11816,6 @@ public:
*/ */
void use(flecs::entity entity, const char *alias = nullptr); void use(flecs::entity entity, const char *alias = nullptr);
/** Delete all entities matching a filter.
*
* @param filter The filter to use for matching.
*/
void delete_entities(flecs::filter filter) const;
/** Add component to all entities matching a filter.
*
* @tparam T The component to add.
* @param filter The filter to use for matching.
*/
template <typename T>
void add(flecs::filter filter) const;
/** Add type to all entities.
*
* @param type The type to add.
*/
void add(flecs::type type) const;
/** Add type to all entities matching a filter.
*
* @param type The type to add.
* @param filter The filter to use for matching.
*/
void add(flecs::type type, flecs::filter filter) const;
/** Add entity to all entities.
*
* @param entity The entity to add.
*/
void add(flecs::entity entity) const;
/** Add entity to all entities matching a filter.
*
* @param entity The entity to add.
* @param filter The filter to use for matching.
*/
void add(flecs::entity entity, flecs::filter filter) const;
/** Remove component from all entities matching a filter.
*
* @tparam T The component to remove.
* @param filter The filter to use for matching.
*/
template <typename T>
void remove(flecs::filter filter) const;
/** Remove type from all entities.
*
* @param type The component to remove.
*/
void remove(flecs::type type) const;
/** Remove type from all entities matching a filter.
*
* @tparam T The component to remove.
* @param filter The filter to use for matching.
*/
void remove(flecs::type type, flecs::filter filter) const;
/** Remove entity from all entities.
*
* @param entity The entity to remove.
*/
void remove(flecs::entity entity) const;
/** Remove entity from all entities matching a filter.
*
* @param entity The entity to remove.
* @param filter The filter to use for matching.
*/
void remove(flecs::entity entity, flecs::filter filter) const;
/** Create iterable filter for entities in world.
*
* @param filter The filter to create.
*/
world_filter filter(const flecs::filter& filter) const;
flecs::filter_iterator begin() const;
flecs::filter_iterator end() const;
/** Count entities matching a component. /** Count entities matching a component.
* *
* @tparam T The component to use for matching. * @tparam T The component to use for matching.
@ -11836,11 +11825,8 @@ public:
return ecs_count_id(m_world, _::cpp_type<T>::id(m_world)); return ecs_count_id(m_world, _::cpp_type<T>::id(m_world));
} }
/** Count entities matching a filter. flecs::filter_iterator begin() const;
* flecs::filter_iterator end() const;
* @param filter The filter to use for matching.
*/
int count(flecs::filter filter) const;
/** Enable locking. /** Enable locking.
* *
@ -11920,6 +11906,9 @@ public:
} }
/** Iterate over all entities with provided component. /** Iterate over all entities with provided component.
* The function parameter must match the following signature:
* void(*)(T&) or
* void(*)(flecs::entity, T&)
*/ */
template <typename T, typename Func> template <typename T, typename Func>
void each(Func&& func) const; void each(Func&& func) const;
@ -11929,6 +11918,14 @@ public:
template <typename Func> template <typename Func>
void each(flecs::id_t term_id, Func&& func) const; void each(flecs::id_t term_id, Func&& func) const;
/** Iterate over all entities with components in argument list of function.
* The function parameter must match the following signature:
* void(*)(T&, U&, ...) or
* void(*)(flecs::entity, T&, U&, ...)
*/
template <typename Func>
void each(Func&& func) const;
/** Create a prefab. /** Create a prefab.
*/ */
template <typename... Args> template <typename... Args>
@ -11973,6 +11970,16 @@ public:
template <typename... Comps, typename... Args> template <typename... Comps, typename... Args>
flecs::observer_builder<Comps...> observer(Args &&... args) const; flecs::observer_builder<Comps...> observer(Args &&... args) const;
/** Create a filter.
*/
template <typename... Comps, typename... Args>
flecs::filter<Comps...> filter(Args &&... args) const;
/** Create a filter builder.
*/
template <typename... Comps, typename... Args>
flecs::filter_builder<Comps...> filter_builder(Args &&... args) const;
/** Create a query. /** Create a query.
*/ */
template <typename... Comps, typename... Args> template <typename... Comps, typename... Args>
@ -15472,7 +15479,7 @@ public:
} }
bool is_set() { bool is_set() {
return ecs_term_is_set(&value); return ecs_term_is_initialized(&value);
} }
bool is_trivial() { bool is_trivial() {
@ -15522,7 +15529,7 @@ public:
ecs_assert(term_index > 0, ECS_INVALID_PARAMETER, NULL); ecs_assert(term_index > 0, ECS_INVALID_PARAMETER, NULL);
m_term_index = term_index - 1; m_term_index = term_index - 1;
this->term(); this->term();
ecs_assert(ecs_term_is_set(this->m_term), ECS_INVALID_PARAMETER, NULL); ecs_assert(ecs_term_is_initialized(this->m_term), ECS_INVALID_PARAMETER, NULL);
return *this; return *this;
} }
@ -15916,6 +15923,66 @@ private:
int32_t m_event_count; int32_t m_event_count;
}; };
// Filter builder
template<typename ... Components>
class filter_builder_base
: public filter_builder_i<filter_builder_base<Components...>, Components ...>
{
public:
filter_builder_base(flecs::world_t *world)
: filter_builder_i<filter_builder_base<Components...>, Components ...>(&m_desc)
, m_desc({})
, m_world(world)
{
this->populate_filter_from_pack();
}
filter_builder_base(const filter_builder_base& obj)
: filter_builder_i<filter_builder_base<Components...>, Components ...>(&m_desc, obj.m_term_index)
{
m_world = obj.m_world;
m_desc = obj.m_desc;
}
filter_builder_base(filter_builder_base&& obj)
: filter_builder_i<filter_builder_base<Components...>, Components ...>(&m_desc, obj.m_term_index)
{
m_world = obj.m_world;
m_desc = obj.m_desc;
}
operator filter<Components ...>() const;
operator ecs_filter_t() const {
ecs_filter_t f;
int res = ecs_filter_init(this->m_world, &f, &this->m_desc);
if (res != 0) {
ecs_abort(ECS_INVALID_PARAMETER, NULL);
}
return f;
}
filter<Components ...> build() const;
ecs_filter_desc_t m_desc;
flecs::world_t* world() override { return m_world; }
protected:
flecs::world_t *m_world;
};
template<typename ... Components>
class filter_builder final : public filter_builder_base<Components...> {
public:
filter_builder(flecs::world_t *world)
: filter_builder_base<Components ...>(world) { }
operator filter<>() const;
};
// Query builder // Query builder
template<typename ... Components> template<typename ... Components>
class query_builder_base class query_builder_base
@ -16025,7 +16092,7 @@ private:
if (is_trigger) { if (is_trigger) {
ecs_trigger_desc_t desc = {}; ecs_trigger_desc_t desc = {};
ecs_term_t term = m_desc.query.filter.terms[0]; ecs_term_t term = m_desc.query.filter.terms[0];
if (ecs_term_is_set(&term)) { if (ecs_term_is_initialized(&term)) {
desc.term = term; desc.term = term;
} else { } else {
desc.expr = m_desc.query.filter.expr; desc.expr = m_desc.query.filter.expr;
@ -16458,94 +16525,157 @@ flecs::entity import(world& world) {
} }
} // namespace flecs } // namespace flecs
namespace flecs namespace flecs
{ {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// A filter is used to match subsets of tables //// Ad hoc queries (filters)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
enum match_kind {
MatchAll = EcsMatchAll,
MatchAny = EcsMatchAny,
MatchExact = EcsMatchExact
};
class filter { class filter_base {
public: public:
filter() filter_base()
: m_world( nullptr ) : m_world(nullptr)
, m_filter{ } {} , m_filter({}) { }
explicit filter(const world& world) filter_base(world_t *world, ecs_filter_t *filter = NULL)
: m_world( world.c_ptr() ) : m_world(world) {
, m_filter{ } { } ecs_filter_move(&m_filter, filter);
}
filter& include(type type) {
m_filter.include = ecs_type_merge(m_world, m_filter.include, type.c_ptr(), nullptr);
return *this;
}
filter& include(entity entity) {
m_filter.include = ecs_type_add(m_world, m_filter.include, entity.id());
return *this;
}
template <typename T>
filter& include() {
m_filter.include = ecs_type_add(m_world, m_filter.include, _::cpp_type<T>::id(m_world));
return *this;
}
filter& include_kind(match_kind kind) {
m_filter.include_kind = static_cast<ecs_match_kind_t>(kind);
return *this;
}
type include() {
return type(m_world, m_filter.include);
}
filter& exclude(type type) {
m_filter.exclude = ecs_type_merge(m_world, m_filter.exclude, type.c_ptr(), nullptr);
return *this;
}
filter& exclude(entity entity) {
m_filter.exclude = ecs_type_add(m_world, m_filter.exclude, entity.id());
return *this;
}
template <typename T>
filter& exclude() {
m_filter.exclude = ecs_type_add(m_world, m_filter.exclude, _::cpp_type<T>::id(m_world));
return *this;
}
filter& exclude_kind(match_kind kind) {
m_filter.exclude_kind = static_cast<ecs_match_kind_t>(kind);
return *this;
}
type exclude() {
return type(m_world, m_filter.exclude);
}
/** Get pointer to C filter object.
*/
const filter_t* c_ptr() const { const filter_t* c_ptr() const {
if (m_world) { if (m_filter.term_count) {
return &m_filter; return &m_filter;
} else { } else {
return nullptr; return NULL;
} }
} }
private: filter_base(const filter_base& obj) {
this->m_world = obj.m_world;
ecs_filter_copy(&m_filter, &obj.m_filter);
}
filter_base& operator=(const filter_base& obj) {
this->m_world = obj.m_world;
ecs_filter_copy(&m_filter, &obj.m_filter);
return *this;
}
filter_base(filter_base&& obj) {
this->m_world = obj.m_world;
ecs_filter_move(&m_filter, &obj.m_filter);
}
filter_base& operator=(filter_base&& obj) {
this->m_world = obj.m_world;
ecs_filter_move(&m_filter, &obj.m_filter);
return *this;
}
/** Free the filter.
*/
~filter_base() {
ecs_filter_fini(&m_filter);
}
template <typename Func>
void iter(Func&& func) const {
ecs_iter_t it = ecs_filter_iter(m_world, &m_filter);
while (ecs_filter_next(&it)) {
_::iter_invoker<Func>(func).invoke(&it);
}
}
template <typename Func>
void each_term(const Func& func) {
for (int i = 0; i < m_filter.term_count; i ++) {
flecs::term t(m_world, m_filter.terms[i]);
func(t);
}
}
flecs::term term(int32_t index) {
return flecs::term(m_world, m_filter.terms[index]);
}
int32_t term_count() {
return m_filter.term_count;
}
flecs::string str() {
char *result = ecs_filter_str(m_world, &m_filter);
return flecs::string(result);
}
protected:
world_t *m_world; world_t *m_world;
filter_t m_filter; filter_t m_filter;
}; };
} // namespace flecs
template<typename ... Components>
class filter : public filter_base {
using Terms = typename _::term_ptrs<Components...>::array;
public:
filter() { }
filter(world_t *world, filter_t *f)
: filter_base(world, f) { }
explicit filter(const world& world, const char *expr = nullptr)
: filter_base(world.c_ptr())
{
auto qb = world.filter_builder<Components ...>()
.expr(expr);
if (!expr) {
qb.substitute_default();
}
flecs::filter_t f = qb;
ecs_filter_move(&m_filter, &f);
}
filter(const filter& obj) : filter_base(obj) { }
filter& operator=(const filter& obj) {
*this = obj;
return *this;
}
filter(filter&& obj) : filter_base(std::move(obj)) { }
filter& operator=(filter&& obj) {
filter_base(std::move(obj));
return *this;
}
template <typename Func>
void each(Func&& func) const {
iterate<_::each_invoker>(std::forward<Func>(func), ecs_filter_next);
}
template <typename Func>
void iter(Func&& func) const {
iterate<_::iter_invoker>(std::forward<Func>(func), ecs_filter_next);
}
private:
template < template<typename Func, typename ... Comps> class Invoker, typename Func, typename NextFunc, typename ... Args>
void iterate(Func&& func, NextFunc next, Args &&... args) const {
ecs_iter_t it = ecs_filter_iter(m_world, &m_filter);
while (next(&it, std::forward<Args>(args)...)) {
Invoker<Func, Components...>(std::move(func)).invoke(&it);
}
}
};
}
namespace flecs namespace flecs
{ {
@ -16596,15 +16726,17 @@ public:
m_snapshot = ecs_snapshot_take(m_world.c_ptr()); m_snapshot = ecs_snapshot_take(m_world.c_ptr());
} }
void take(flecs::filter filter) { template <typename F>
void take(const F& f) {
if (m_snapshot) { if (m_snapshot) {
ecs_snapshot_free(m_snapshot); ecs_snapshot_free(m_snapshot);
} }
ecs_iter_t it = ecs_filter_iter(m_world.c_ptr(), filter.c_ptr()); ecs_iter_t it = ecs_filter_iter(m_world, f.c_ptr());
m_snapshot = ecs_snapshot_take_w_iter(
&it, ecs_filter_next); printf("filter = %s\n", ecs_filter_str(m_world, f.c_ptr()));
} m_snapshot = ecs_snapshot_take_w_iter(&it, ecs_filter_next);
}
void restore() { void restore() {
if (m_snapshot) { if (m_snapshot) {
@ -16623,8 +16755,6 @@ public:
return m_snapshot; return m_snapshot;
} }
snapshot_filter filter(const filter& filter);
filter_iterator begin(); filter_iterator begin();
filter_iterator end(); filter_iterator end();
@ -16651,17 +16781,17 @@ public:
, m_iter{ } , m_iter{ }
, m_action(action) { } , m_action(action) { }
filter_iterator(const world& world, const filter& filter, ecs_iter_next_action_t action) filter_iterator(const world& world, ecs_iter_next_action_t action)
: m_world( world.c_ptr() ) : m_world( world.c_ptr() )
, m_iter( ecs_filter_iter(m_world, filter.c_ptr()) ) , m_iter( ecs_filter_iter(m_world, NULL) )
, m_action(action) , m_action(action)
{ {
m_has_next = m_action(&m_iter); m_has_next = m_action(&m_iter);
} }
filter_iterator(const world& world, const snapshot& snapshot, const filter& filter, ecs_iter_next_action_t action) filter_iterator(const world& world, const snapshot& snapshot, ecs_iter_next_action_t action)
: m_world( world.c_ptr() ) : m_world( world.c_ptr() )
, m_iter( ecs_snapshot_iter(snapshot.c_ptr(), filter.c_ptr()) ) , m_iter( ecs_snapshot_iter(snapshot.c_ptr(), NULL) )
, m_action(action) , m_action(action)
{ {
m_has_next = m_action(&m_iter); m_has_next = m_action(&m_iter);
@ -16723,18 +16853,18 @@ private:
ecs_iter_t m_iter; ecs_iter_t m_iter;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// Utility for creating a world-based filter iterator //// Utility for creating a world-based filter iterator
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class world_filter { class world_filter {
public: public:
world_filter(const world& world, const filter& filter) world_filter(const world& world)
: m_world( world ) : m_world( world ) { }
, m_filter( filter ) { }
inline filter_iterator begin() const { inline filter_iterator begin() const {
return filter_iterator(m_world, m_filter, ecs_filter_next); return filter_iterator(m_world, ecs_filter_next);
} }
inline filter_iterator end() const { inline filter_iterator end() const {
@ -16743,7 +16873,6 @@ public:
private: private:
const world& m_world; const world& m_world;
const filter& m_filter;
}; };
@ -16753,13 +16882,12 @@ private:
class snapshot_filter { class snapshot_filter {
public: public:
snapshot_filter(const world& world, const snapshot& snapshot, const filter& filter) snapshot_filter(const world& world, const snapshot& snapshot)
: m_world( world ) : m_world( world )
, m_snapshot( snapshot ) , m_snapshot( snapshot ) { }
, m_filter( filter ) { }
inline filter_iterator begin() const { inline filter_iterator begin() const {
return filter_iterator(m_world, m_snapshot, m_filter, ecs_snapshot_next); return filter_iterator(m_world, m_snapshot, ecs_snapshot_next);
} }
inline filter_iterator end() const { inline filter_iterator end() const {
@ -16769,7 +16897,6 @@ public:
private: private:
const world& m_world; const world& m_world;
const snapshot& m_snapshot; const snapshot& m_snapshot;
const filter& m_filter;
}; };
@ -16801,12 +16928,8 @@ private:
//// Filter fwd declared functions //// Filter fwd declared functions
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
inline snapshot_filter snapshot::filter(const flecs::filter& filter) {
return snapshot_filter(m_world, *this, filter);
}
inline filter_iterator snapshot::begin() { inline filter_iterator snapshot::begin() {
return filter_iterator(m_world, *this, flecs::filter(m_world), ecs_snapshot_next); return filter_iterator(m_world, *this, ecs_snapshot_next);
} }
inline filter_iterator snapshot::end() { inline filter_iterator snapshot::end() {
@ -17022,13 +17145,6 @@ public:
iterate<_::each_invoker>(std::forward<Func>(func), ecs_query_next); iterate<_::each_invoker>(std::forward<Func>(func), ecs_query_next);
} }
template <typename Func>
void each(const flecs::filter& filter, Func&& func) const {
const filter_t* filter_ptr = filter.c_ptr();
iterate<_::each_invoker>(std::forward<Func>(func),
ecs_query_next_w_filter, filter_ptr);
}
template <typename Func> template <typename Func>
void each_worker(int32_t stage_current, int32_t stage_count, Func&& func) const { void each_worker(int32_t stage_current, int32_t stage_count, Func&& func) const {
iterate<_::each_invoker>(std::forward<Func>(func), iterate<_::each_invoker>(std::forward<Func>(func),
@ -17040,13 +17156,6 @@ public:
iterate<_::iter_invoker>(std::forward<Func>(func), ecs_query_next); iterate<_::iter_invoker>(std::forward<Func>(func), ecs_query_next);
} }
template <typename Func>
void iter(const flecs::filter& filter, Func&& func) const {
const filter_t* filter_ptr = filter.c_ptr();
iterate<_::iter_invoker>(std::forward<Func>(func),
ecs_query_next_w_filter, filter_ptr);
}
template <typename Func> template <typename Func>
void iter_worker(int32_t stage_current, int32_t stage_count, Func&& func) const { void iter_worker(int32_t stage_current, int32_t stage_count, Func&& func) const {
iterate<_::iter_invoker>(std::forward<Func>(func), iterate<_::iter_invoker>(std::forward<Func>(func),
@ -17097,8 +17206,9 @@ public:
, m_stage_current(stage_current) , m_stage_current(stage_current)
, m_stage_count(stage_count) { } , m_stage_count(stage_count) { }
system_runner_fluent& filter(filter filter) { template <typename F>
m_filter = filter; system_runner_fluent& filter(const F& f) {
m_filter = f;
return *this; return *this;
} }
@ -17128,12 +17238,13 @@ public:
m_filter.c_ptr(), m_param); m_filter.c_ptr(), m_param);
} }
} }
private: private:
world_t *m_stage; world_t *m_stage;
entity_t m_id; entity_t m_id;
FLECS_FLOAT m_delta_time; FLECS_FLOAT m_delta_time;
void *m_param; void *m_param;
flecs::filter m_filter; flecs::filter<> m_filter;
int32_t m_offset; int32_t m_offset;
int32_t m_limit; int32_t m_limit;
int32_t m_stage_current; int32_t m_stage_current;
@ -17746,70 +17857,14 @@ inline flecs::id world::pair(entity_t r, entity_t o) const {
ecs_pair(r, o)); ecs_pair(r, o));
} }
inline void world::delete_entities(flecs::filter filter) const {
ecs_bulk_delete(m_world, filter.c_ptr());
}
template <typename T>
inline void world::add(flecs::filter filter) const {
ecs_bulk_add_remove_type(
m_world, _::cpp_type<T>::type(m_world), nullptr, filter.c_ptr());
}
inline void world::add(flecs::type t) const {
ecs_bulk_add_remove_type(m_world, t.c_ptr(), nullptr, nullptr);
}
inline void world::add(flecs::type t, flecs::filter filter) const {
ecs_bulk_add_remove_type(m_world, t.c_ptr(), nullptr, filter.c_ptr());
}
inline void world::add(class flecs::entity e) const {
ecs_bulk_add_remove_type(m_world, e.to_type().c_ptr(), nullptr, nullptr);
}
inline void world::add(class flecs::entity e, flecs::filter filter) const {
ecs_bulk_add_remove_type(m_world, e.to_type().c_ptr(), nullptr, filter.c_ptr());
}
template <typename T>
inline void world::remove(flecs::filter filter) const {
ecs_bulk_add_remove_type(
m_world, nullptr, _::cpp_type<T>::type(m_world), filter.c_ptr());
}
inline void world::remove(flecs::type t) const {
ecs_bulk_add_remove_type(m_world, nullptr, t.c_ptr(), nullptr);
}
inline void world::remove(flecs::type t, flecs::filter filter) const {
ecs_bulk_add_remove_type(m_world, nullptr, t.c_ptr(), filter.c_ptr());
}
inline void world::remove(class entity e) const {
ecs_bulk_add_remove_type(m_world, nullptr, e.to_type().c_ptr(), nullptr);
}
inline void world::remove(class entity e, flecs::filter filter) const {
ecs_bulk_add_remove_type(m_world, nullptr, e.to_type().c_ptr(), filter.c_ptr());
}
inline flecs::world_filter world::filter(const flecs::filter& filter) const {
return flecs::world_filter(*this, filter);
}
inline filter_iterator world::begin() const { inline filter_iterator world::begin() const {
return filter_iterator(*this, flecs::filter(*this), ecs_filter_next); return filter_iterator(*this, ecs_filter_next);
} }
inline filter_iterator world::end() const { inline filter_iterator world::end() const {
return filter_iterator(ecs_filter_next); return filter_iterator(ecs_filter_next);
} }
inline int world::count(flecs::filter filter) const {
return ecs_count_w_filter(m_world, filter.c_ptr());
}
/** All entities created in function are created in scope. All operations /** All entities created in function are created in scope. All operations
* called in function (such as lookup) are relative to scope. * called in function (such as lookup) are relative to scope.
*/ */
@ -17957,6 +18012,16 @@ inline flecs::observer_builder<Comps...> world::observer(Args &&... args) const
return flecs::observer_builder<Comps...>(*this, std::forward<Args>(args)...); return flecs::observer_builder<Comps...>(*this, std::forward<Args>(args)...);
} }
template <typename... Comps, typename... Args>
inline flecs::filter<Comps...> world::filter(Args &&... args) const {
return flecs::filter<Comps...>(*this, std::forward<Args>(args)...);
}
template <typename... Comps, typename... Args>
inline flecs::filter_builder<Comps...> world::filter_builder(Args &&... args) const {
return flecs::filter_builder<Comps...>(*this, std::forward<Args>(args)...);
}
template <typename... Comps, typename... Args> template <typename... Comps, typename... Args>
inline flecs::query<Comps...> world::query(Args &&... args) const { inline flecs::query<Comps...> world::query(Args &&... args) const {
return flecs::query<Comps...>(*this, std::forward<Args>(args)...); return flecs::query<Comps...>(*this, std::forward<Args>(args)...);
@ -18020,7 +18085,7 @@ inline void world::each(Func&& func) const {
while (ecs_term_next(&it)) { while (ecs_term_next(&it)) {
_::each_invoker<Func, T>(func).invoke(&it); _::each_invoker<Func, T>(func).invoke(&it);
} }
} }
template <typename Func> template <typename Func>
@ -18034,6 +18099,61 @@ inline void world::each(flecs::id_t term_id, Func&& func) const {
} }
} }
namespace _ {
// Each with entity parameter
template<typename Func, typename ... Args>
struct filter_invoker_w_ent;
template<typename Func, typename E, typename ... Args>
struct filter_invoker_w_ent<Func, arg_list<E, Args ...> >
{
filter_invoker_w_ent(const flecs::world& world, Func&& func) {
flecs::filter<Args ...> f(world);
f.each(std::move(func));
}
};
// Each without entity parameter
template<typename Func, typename ... Args>
struct filter_invoker_no_ent;
template<typename Func, typename ... Args>
struct filter_invoker_no_ent<Func, arg_list<Args ...> >
{
filter_invoker_no_ent(const flecs::world& world, Func&& func) {
flecs::filter<Args ...> f(world);
f.each(std::move(func));
}
};
// Switch between function with & without entity parameter
template<typename Func, typename T = int>
class filter_invoker;
template <typename Func>
class filter_invoker<Func, if_t<is_same<first_arg_t<Func>, flecs::entity>::value> > {
public:
filter_invoker(const flecs::world& world, Func&& func) {
filter_invoker_w_ent<Func, arg_list_t<Func>>(world, std::move(func));
}
};
template <typename Func>
class filter_invoker<Func, if_not_t<is_same<first_arg_t<Func>, flecs::entity>::value> > {
public:
filter_invoker(const flecs::world& world, Func&& func) {
filter_invoker_no_ent<Func, arg_list_t<Func>>(world, std::move(func));
}
};
}
template <typename Func>
inline void world::each(Func&& func) const {
_::filter_invoker<Func> f_invoker(*this, std::move(func));
}
} // namespace flecs } // namespace flecs
namespace flecs namespace flecs
@ -18046,6 +18166,24 @@ inline Base& term_builder_i<Base>::id(const flecs::type& type) {
return *this; return *this;
} }
template <typename ... Components>
inline filter_builder_base<Components...>::operator filter<Components ...>() const {
ecs_filter_t filter = *this;
return flecs::filter<Components...>(m_world, &filter);
}
template <typename ... Components>
inline filter_builder<Components ...>::operator filter<>() const {
ecs_filter_t filter = *this;
return flecs::filter<>(this->m_world, &filter);
}
template <typename ... Components>
inline filter<Components ...> filter_builder_base<Components...>::build() const {
ecs_filter_t filter = *this;
return flecs::filter<Components...>(m_world, &filter);
}
template <typename ... Components> template <typename ... Components>
inline query_builder_base<Components...>::operator query<Components ...>() const { inline query_builder_base<Components...>::operator query<Components ...>() const {
ecs_query_t *query = *this; ecs_query_t *query = *this;