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_delegate*
>(iter->binding_ctx);
212 ecs_assert(self !=
nullptr, ECS_INTERNAL_ERROR, NULL);
222 static void free(
void *obj) {
223 _::free_obj<each_delegate>(
static_cast<each_delegate*
>(obj));
227 static void run_add(ecs_iter_t *iter) {
230 iter->binding_ctx = ctx->on_add;
235 static void run_remove(ecs_iter_t *iter) {
238 iter->binding_ctx = ctx->on_remove;
243 static void run_set(ecs_iter_t *iter) {
246 iter->binding_ctx = ctx->on_set;
251 static bool instanced() {
258 template <
template<
typename X,
typename =
int>
class ColumnType,
259 typename... Args, if_t<
260 sizeof...(Components) ==
sizeof...(Args) && PassEntity> = 0>
261 static void invoke_callback(
262 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
264 ECS_TABLE_LOCK(iter->world, iter->table);
267 size_t count =
static_cast<size_t>(iter->count);
270 "no entities returned, use each() without flecs::entity argument");
272 for (
size_t i = 0; i < count; i ++) {
274 (ColumnType< remove_reference_t<Components> >(comps, i)
278 ECS_TABLE_UNLOCK(iter->world, iter->table);
283 template <
template<
typename X,
typename =
int>
class ColumnType,
284 typename... Args,
int Enabled = PassIter, if_t<
285 sizeof...(Components) ==
sizeof...(Args) && Enabled> = 0>
286 static void invoke_callback(
287 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
289 size_t count =
static_cast<size_t>(iter->count);
296 flecs::iter it(iter);
298 ECS_TABLE_LOCK(iter->world, iter->table);
300 for (
size_t i = 0; i < count; i ++) {
301 func(it, i, (ColumnType< remove_reference_t<Components> >(comps, i)
305 ECS_TABLE_UNLOCK(iter->world, iter->table);
309 template <
template<
typename X,
typename =
int>
class ColumnType,
310 typename... Args, if_t<
311 sizeof...(Components) ==
sizeof...(Args) && !PassEntity && !PassIter> = 0>
312 static void invoke_callback(
313 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
315 size_t count =
static_cast<size_t>(iter->count);
322 flecs::iter it(iter);
324 ECS_TABLE_LOCK(iter->world, iter->table);
326 for (
size_t i = 0; i < count; i ++) {
327 func( (ColumnType< remove_reference_t<Components> >(comps, i)
331 ECS_TABLE_UNLOCK(iter->world, iter->table);
334 template <
template<
typename X,
typename =
int>
class ColumnType,
335 typename... Args, if_t<
sizeof...(Components) !=
sizeof...(Args) > = 0>
336 static void invoke_callback(ecs_iter_t *iter,
const Func& func,
337 size_t index, Terms& columns, Args... comps)
339 invoke_callback<ColumnType>(
340 iter, func, index + 1, columns, comps..., columns[index]);
350 static constexpr bool PassEntity =
355 static constexpr bool PassIter =
359 "each() must have at least one argument");
361 using Terms =
typename term_ptrs<Components ...>::array;
363 template < if_not_t< is_same< decay_t<Func>, decay_t<Func>& >::value > = 0>
365 : m_func(FLECS_MOV(func)) { }
376 if (terms.populate(iter)) {
377 return invoke_callback< each_ref_column >(iter, m_func, 0, terms.m_terms);
379 return invoke_callback< each_column >(iter, m_func, 0, terms.m_terms);
384 static bool instanced() {
391 template <
template<
typename X,
typename =
int>
class ColumnType,
392 typename... Args, if_t<
393 sizeof...(Components) ==
sizeof...(Args) && PassEntity> = 0>
395 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
397 ECS_TABLE_LOCK(iter->world, iter->table);
400 size_t count =
static_cast<size_t>(iter->count);
404 "no entities returned, use find() without flecs::entity argument");
406 for (
size_t i = 0; i < count; i ++) {
408 (ColumnType< remove_reference_t<Components> >(comps, i)
416 ECS_TABLE_UNLOCK(iter->world, iter->table);
423 template <
template<
typename X,
typename =
int>
class ColumnType,
424 typename... Args,
int Enabled = PassIter, if_t<
425 sizeof...(Components) ==
sizeof...(Args) && Enabled> = 0>
427 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
429 size_t count =
static_cast<size_t>(iter->count);
436 flecs::iter it(iter);
439 ECS_TABLE_LOCK(iter->world, iter->table);
441 for (
size_t i = 0; i < count; i ++) {
442 if (func(it, i, (ColumnType< remove_reference_t<Components> >(comps, i)
450 ECS_TABLE_UNLOCK(iter->world, iter->table);
456 template <
template<
typename X,
typename =
int>
class ColumnType,
457 typename... Args, if_t<
458 sizeof...(Components) ==
sizeof...(Args) && !PassEntity && !PassIter> = 0>
460 ecs_iter_t *iter,
const Func& func,
size_t, Terms&, Args... comps)
462 size_t count =
static_cast<size_t>(iter->count);
469 flecs::iter it(iter);
472 ECS_TABLE_LOCK(iter->world, iter->table);
474 for (
size_t i = 0; i < count; i ++) {
475 if (func( (ColumnType< remove_reference_t<Components> >(comps, i)
483 ECS_TABLE_UNLOCK(iter->world, iter->table);
488 template <
template<
typename X,
typename =
int>
class ColumnType,
489 typename... Args, if_t<
sizeof...(Components) !=
sizeof...(Args) > = 0>
490 static flecs::entity invoke_callback(ecs_iter_t *iter,
const Func& func,
491 size_t index, Terms& columns, Args... comps)
493 return invoke_callback<ColumnType>(
494 iter, func, index + 1, columns, comps..., columns[index]);
509 using Terms =
typename term_ptrs<Components ...>::array;
512 template < if_not_t< is_same< decay_t<Func>, decay_t<Func>& >::value > = 0>
514 : m_func(FLECS_MOV(func)) { }
522 void invoke(ecs_iter_t *iter)
const {
524 terms.populate(iter);
525 invoke_callback(iter, m_func, 0, terms.m_terms);
529 static void run(ecs_iter_t *iter) {
530 auto self =
static_cast<const iter_delegate*
>(iter->binding_ctx);
531 ecs_assert(self !=
nullptr, ECS_INTERNAL_ERROR, NULL);
536 static bool instanced() {
541 template <
typename... Args, if_t<!
sizeof...(Args) && IterOnly> = 0>
542 static void invoke_callback(ecs_iter_t *iter,
const Func& func,
543 size_t, Terms&, Args...)
545 flecs::iter it(iter);
547 ECS_TABLE_LOCK(iter->world, iter->table);
551 ECS_TABLE_UNLOCK(iter->world, iter->table);
554 template <
typename... Targs, if_t<!IterOnly &&
555 (
sizeof...(Targs) ==
sizeof...(Components))> = 0>
556 static void invoke_callback(ecs_iter_t *iter,
const Func& func,
size_t,
557 Terms&, Targs... comps)
559 flecs::iter it(iter);
561 ECS_TABLE_LOCK(iter->world, iter->table);
563 func(it, (
static_cast<
566 actual_type_t<Components>
> >* >
569 ECS_TABLE_UNLOCK(iter->world, iter->table);
572 template <
typename... Targs, if_t<!IterOnly &&
573 (
sizeof...(Targs) !=
sizeof...(Components)) > = 0>
574 static void invoke_callback(ecs_iter_t *iter,
const Func& func,
575 size_t index, Terms& columns, Targs... comps)
577 invoke_callback(iter, func, index + 1, columns, comps...,
592 : m_func(FLECS_MOV(func)) { }
595 static void run(ecs_iter_t *iter) {
599 template <typename F, if_t<arity<F>::value == 1> = 0>
600 static void invoke(ecs_iter_t *iter) {
602 ecs_assert(self !=
nullptr, ECS_INTERNAL_ERROR, NULL);
606 template <typename F, if_t<arity<F>::value == 0> = 0>
607 static void invoke(ecs_iter_t *iter) {
609 ecs_assert(self !=
nullptr, ECS_INTERNAL_ERROR, NULL);
619 : m_func(FLECS_MOV(func)) { }
622 static void run(ecs_iter_t *iter) {
627 template <typename F, if_t<arity<F>::value == 1> = 0>
628 static void invoke(ecs_iter_t *iter) {
631 ecs_assert(self !=
nullptr, ECS_INTERNAL_ERROR, NULL);
632 ecs_assert(iter->param !=
nullptr, ECS_INVALID_OPERATION,
633 "entity observer invoked without payload");
635 Event *data =
static_cast<Event*
>(iter->param);
639 template <typename F, if_t<arity<F>::value == 2> = 0>
640 static void invoke(ecs_iter_t *iter) {
643 ecs_assert(self !=
nullptr, ECS_INTERNAL_ERROR, NULL);
644 ecs_assert(iter->param !=
nullptr, ECS_INVALID_OPERATION,
645 "entity observer invoked without payload");
647 Event *data =
static_cast<Event*
>(iter->param);
669 static bool const_args() {
670 static flecs::array<bool,
sizeof...(Args)> is_const_args ({
671 flecs::is_const<flecs::remove_reference_t<Args>>::value...
674 for (
auto is_const : is_const_args) {
702 for (int32_t
column : columns) {
724 template <
typename Func>
725 static bool invoke_read(world_t *
world, entity_t e,
const Func& func) {
737 bool has_components = get_ptrs(
world, r,
table, ptrs);
738 if (has_components) {
739 invoke_callback(func, 0, ptrs);
744 return has_components;
747 template <
typename Func>
748 static bool invoke_write(world_t *
world, entity_t e,
const Func& func) {
760 bool has_components = get_ptrs(
world, r,
table, ptrs);
761 if (has_components) {
762 invoke_callback(func, 0, ptrs);
767 return has_components;
770 template <
typename Func>
771 static bool invoke_get(world_t *
world, entity_t e,
const Func& func) {
773 return invoke_read(
world, e, func);
775 return invoke_write(
world, e, func);
792 template <
typename Func>
793 static bool invoke_get_mut(world_t *
world, entity_t
id,
const Func& func) {
823 elem = store_added(added, elem, prev, next, w.
id<Args>()),
831 ids.array = added.ptr();
832 ids.count =
static_cast<ecs_size_t
>(elem);
837 if (!get_ptrs(w, r,
table, ptrs)) {
845 get_mut_ptrs(
world,
id, ptrs);
848 invoke_callback(func, 0, ptrs);
864 template <
typename Func,
typename ... TArgs,
865 if_t<
sizeof...(TArgs) ==
sizeof...(Args)> = 0>
866 static void invoke_callback(
867 const Func& f,
size_t,
ArrayType&, TArgs&& ... comps)
869 f(*
static_cast<typename base_arg_type<Args>::type*
>(comps)...);
872 template <
typename Func,
typename ... TArgs,
873 if_t<
sizeof...(TArgs) !=
sizeof...(Args)> = 0>
874 static void invoke_callback(
const Func& f,
size_t arg,
ArrayType& ptrs,
877 invoke_callback(f, arg + 1, ptrs, comps..., ptrs[arg]);
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.