46 bool populate(
const ecs_iter_t *iter) {
47 return populate(iter, 0,
static_cast<
49 remove_pointer_t<Components>
>
57 bool populate(
const ecs_iter_t*,
size_t) {
return false; }
59 template <
typename T,
typename... Targs>
60 bool populate(
const ecs_iter_t *iter,
size_t index, T, Targs... comps) {
61 m_terms[index].ptr = iter->ptrs[index];
62 bool is_ref = iter->sources && iter->sources[index] != 0;
63 m_terms[index].is_ref = is_ref;
64 is_ref |= populate(iter, index + 1, comps ...);
176 static constexpr bool PassEntity =
181 static constexpr bool PassIter =
185 "each() must have at least one argument");
187 using Terms =
typename term_ptrs<Components ...>::array;
189 template < if_not_t< is_same< decay_t<Func>, decay_t<Func>& >::value > = 0>
191 : m_func(FLECS_MOV(func)) { }
199 void invoke(ecs_iter_t *iter)
const {
202 if (terms.populate(iter)) {
203 invoke_callback< each_ref_column >(iter, m_func, 0, terms.m_terms);
205 invoke_callback< each_column >(iter, m_func, 0, terms.m_terms);
210 static void run(ecs_iter_t *iter) {
211 auto self =
static_cast<const each_invoker*
>(iter->binding_ctx);
212 ecs_assert(self !=
nullptr, ECS_INTERNAL_ERROR, NULL);
217 static void run_add(ecs_iter_t *iter) {
220 iter->binding_ctx = ctx->on_add;
225 static void run_remove(ecs_iter_t *iter) {
228 iter->binding_ctx = ctx->on_remove;
233 static void run_set(ecs_iter_t *iter) {
236 iter->binding_ctx = ctx->on_set;
241 static bool instanced() {
248 template <
template<
typename X,
typename =
int>
class ColumnType,
249 typename... Args, if_t<
250 sizeof...(Components) ==
sizeof...(Args) && PassEntity> = 0>
251 static void invoke_callback(
252 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
254 ECS_TABLE_LOCK(iter->world, iter->table);
257 size_t count =
static_cast<size_t>(iter->count);
260 "no entities returned, use each() without flecs::entity argument");
262 for (
size_t i = 0; i < count; i ++) {
264 (ColumnType< remove_reference_t<Components> >(comps, i)
268 ECS_TABLE_UNLOCK(iter->world, iter->table);
273 template <
template<
typename X,
typename =
int>
class ColumnType,
274 typename... Args,
int Enabled = PassIter, if_t<
275 sizeof...(Components) ==
sizeof...(Args) && Enabled> = 0>
276 static void invoke_callback(
277 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
279 size_t count =
static_cast<size_t>(iter->count);
286 flecs::iter it(iter);
288 ECS_TABLE_LOCK(iter->world, iter->table);
290 for (
size_t i = 0; i < count; i ++) {
291 func(it, i, (ColumnType< remove_reference_t<Components> >(comps, i)
295 ECS_TABLE_UNLOCK(iter->world, iter->table);
299 template <
template<
typename X,
typename =
int>
class ColumnType,
300 typename... Args, if_t<
301 sizeof...(Components) ==
sizeof...(Args) && !PassEntity && !PassIter> = 0>
302 static void invoke_callback(
303 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
305 size_t count =
static_cast<size_t>(iter->count);
312 flecs::iter it(iter);
314 ECS_TABLE_LOCK(iter->world, iter->table);
316 for (
size_t i = 0; i < count; i ++) {
317 func( (ColumnType< remove_reference_t<Components> >(comps, i)
321 ECS_TABLE_UNLOCK(iter->world, iter->table);
324 template <
template<
typename X,
typename =
int>
class ColumnType,
325 typename... Args, if_t<
sizeof...(Components) !=
sizeof...(Args) > = 0>
326 static void invoke_callback(ecs_iter_t *iter,
const Func& func,
327 size_t index, Terms& columns, Args... comps)
329 invoke_callback<ColumnType>(
330 iter, func, index + 1, columns, comps..., columns[index]);
340 static constexpr bool PassEntity =
345 static constexpr bool PassIter =
349 "each() must have at least one argument");
351 using Terms =
typename term_ptrs<Components ...>::array;
353 template < if_not_t< is_same< decay_t<Func>, decay_t<Func>& >::value > = 0>
355 : m_func(FLECS_MOV(func)) { }
366 if (terms.populate(iter)) {
367 return invoke_callback< each_ref_column >(iter, m_func, 0, terms.m_terms);
369 return invoke_callback< each_column >(iter, m_func, 0, terms.m_terms);
374 static bool instanced() {
381 template <
template<
typename X,
typename =
int>
class ColumnType,
382 typename... Args, if_t<
383 sizeof...(Components) ==
sizeof...(Args) && PassEntity> = 0>
385 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
387 ECS_TABLE_LOCK(iter->world, iter->table);
390 size_t count =
static_cast<size_t>(iter->count);
394 "no entities returned, use find() without flecs::entity argument");
396 for (
size_t i = 0; i < count; i ++) {
398 (ColumnType< remove_reference_t<Components> >(comps, i)
406 ECS_TABLE_UNLOCK(iter->world, iter->table);
413 template <
template<
typename X,
typename =
int>
class ColumnType,
414 typename... Args,
int Enabled = PassIter, if_t<
415 sizeof...(Components) ==
sizeof...(Args) && Enabled> = 0>
417 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
419 size_t count =
static_cast<size_t>(iter->count);
426 flecs::iter it(iter);
429 ECS_TABLE_LOCK(iter->world, iter->table);
431 for (
size_t i = 0; i < count; i ++) {
432 if (func(it, i, (ColumnType< remove_reference_t<Components> >(comps, i)
440 ECS_TABLE_UNLOCK(iter->world, iter->table);
446 template <
template<
typename X,
typename =
int>
class ColumnType,
447 typename... Args, if_t<
448 sizeof...(Components) ==
sizeof...(Args) && !PassEntity && !PassIter> = 0>
450 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
452 size_t count =
static_cast<size_t>(iter->count);
459 flecs::iter it(iter);
462 ECS_TABLE_LOCK(iter->world, iter->table);
464 for (
size_t i = 0; i < count; i ++) {
465 if (func( (ColumnType< remove_reference_t<Components> >(comps, i)
473 ECS_TABLE_UNLOCK(iter->world, iter->table);
478 template <
template<
typename X,
typename =
int>
class ColumnType,
479 typename... Args, if_t<
sizeof...(Components) !=
sizeof...(Args) > = 0>
480 static flecs::entity invoke_callback(ecs_iter_t *iter,
const Func& func,
481 size_t index, Terms& columns, Args... comps)
483 return invoke_callback<ColumnType>(
484 iter, func, index + 1, columns, comps..., columns[index]);
499 using Terms =
typename term_ptrs<Components ...>::array;
502 template < if_not_t< is_same< decay_t<Func>, decay_t<Func>& >::value > = 0>
504 : m_func(FLECS_MOV(func)) { }
512 void invoke(ecs_iter_t *iter)
const {
514 terms.populate(iter);
515 invoke_callback(iter, m_func, 0, terms.m_terms);
519 static void run(ecs_iter_t *iter) {
520 auto self =
static_cast<const iter_invoker*
>(iter->binding_ctx);
521 ecs_assert(self !=
nullptr, ECS_INTERNAL_ERROR, NULL);
526 static bool instanced() {
531 template <
typename... Args, if_t<!
sizeof...(Args) && IterOnly> = 0>
532 static void invoke_callback(ecs_iter_t *iter,
const Func& func,
533 size_t, Terms&, Args...)
535 flecs::iter it(iter);
537 ECS_TABLE_LOCK(iter->world, iter->table);
541 ECS_TABLE_UNLOCK(iter->world, iter->table);
544 template <
typename... Targs, if_t<!IterOnly &&
545 (
sizeof...(Targs) ==
sizeof...(Components))> = 0>
546 static void invoke_callback(ecs_iter_t *iter,
const Func& func,
size_t,
547 Terms&, Targs... comps)
549 flecs::iter it(iter);
551 ECS_TABLE_LOCK(iter->world, iter->table);
553 func(it, (
static_cast<
556 actual_type_t<Components>
> >* >
559 ECS_TABLE_UNLOCK(iter->world, iter->table);
562 template <
typename... Targs, if_t<!IterOnly &&
563 (
sizeof...(Targs) !=
sizeof...(Components)) > = 0>
564 static void invoke_callback(ecs_iter_t *iter,
const Func& func,
565 size_t index, Terms& columns, Targs... comps)
567 invoke_callback(iter, func, index + 1, columns, comps...,
589 static bool const_args() {
590 static flecs::array<bool,
sizeof...(Args)> is_const_args ({
591 flecs::is_const<flecs::remove_reference_t<Args>>::value...
594 for (
auto is_const : is_const_args) {
622 for (int32_t
column : columns) {
644 template <
typename Func>
645 static bool invoke_read(world_t *
world, entity_t e,
const Func& func) {
658 if ((has_components = get_ptrs(
world, r,
table, ptrs))) {
659 invoke_callback(func, 0, ptrs);
664 return has_components;
667 template <
typename Func>
668 static bool invoke_write(world_t *
world, entity_t e,
const Func& func) {
681 if ((has_components = get_ptrs(
world, r,
table, ptrs))) {
682 invoke_callback(func, 0, ptrs);
687 return has_components;
690 template <
typename Func>
691 static bool invoke_get(world_t *
world, entity_t e,
const Func& func) {
693 return invoke_read(
world, e, func);
695 return invoke_write(
world, e, func);
712 template <
typename Func>
713 static bool invoke_get_mut(world_t *
world, entity_t
id,
const Func& func) {
743 elem = store_added(added, elem, prev, next, w.
id<Args>()),
751 ids.array = added.ptr();
752 ids.count =
static_cast<ecs_size_t
>(elem);
757 if (!get_ptrs(w, r,
table, ptrs)) {
765 get_mut_ptrs(
world,
id, ptrs);
768 invoke_callback(func, 0, ptrs);
784 template <
typename Func,
typename ... TArgs,
785 if_t<
sizeof...(TArgs) ==
sizeof...(Args)> = 0>
786 static void invoke_callback(
787 const Func& f,
size_t,
ArrayType&, TArgs&& ... comps)
789 f(*
static_cast<typename base_arg_type<Args>::type*
>(comps)...);
792 template <
typename Func,
typename ... TArgs,
793 if_t<
sizeof...(TArgs) !=
sizeof...(Args)> = 0>
794 static void invoke_callback(
const Func& f,
size_t arg,
ArrayType& ptrs,
797 invoke_callback(f, arg + 1, ptrs, comps..., ptrs[arg]);
ecs_table_t * ecs_table_add_id(ecs_world_t *world, ecs_table_t *table, ecs_id_t id)
Get table that has all components of current table plus the specified id.
bool ecs_commit(ecs_world_t *world, ecs_entity_t entity, ecs_record_t *record, ecs_table_t *table, const ecs_type_t *added, const ecs_type_t *removed)
Commit (move) entity to a table.