#define flecs_STATIC
#ifndef FLECS_H
#define FLECS_H
#ifndef ecs_float_t
#define ecs_float_t float
#endif
#ifndef ecs_ftime_t
#define ecs_ftime_t ecs_float_t
#endif
#define FLECS_NO_DEPRECATED_WARNINGS
#if defined(FLECS_DEBUG) && defined(FLECS_NDEBUG)
#error "invalid configuration: cannot both define FLECS_DEBUG and FLECS_NDEBUG"
#endif
#if defined(FLECS_DEBUG) && defined(NDEBUG)
#error "invalid configuration: cannot both define FLECS_DEBUG and NDEBUG"
#endif
#if !defined(FLECS_DEBUG) && !defined(FLECS_NDEBUG)
#if defined(NDEBUG)
#define FLECS_NDEBUG
#else
#define FLECS_DEBUG
#endif
#endif
#ifdef FLECS_SANITIZE
#define FLECS_DEBUG
#endif
#ifndef FLECS_CUSTOM_BUILD
#define FLECS_CPP
#define FLECS_MODULE
#define FLECS_PARSER
#define FLECS_PLECS
#define FLECS_RULES
#define FLECS_SNAPSHOT
#define FLECS_STATS
#define FLECS_MONITOR
#define FLECS_METRICS
#define FLECS_ALERTS
#define FLECS_SYSTEM
#define FLECS_PIPELINE
#define FLECS_TIMER
#define FLECS_META
#define FLECS_META_C
#define FLECS_UNITS
#define FLECS_EXPR
#define FLECS_JSON
#define FLECS_DOC
#define FLECS_COREDOC
#define FLECS_LOG
#define FLECS_APP
#define FLECS_OS_API_IMPL
#define FLECS_HTTP
#define FLECS_REST
#endif
#ifdef FLECS_LOW_FOOTPRINT
#define FLECS_HI_COMPONENT_ID (16)
#define FLECS_HI_ID_RECORD_ID (16)
#define FLECS_SPARSE_PAGE_BITS (6)
#define FLECS_ENTITY_PAGE_BITS (6)
#define FLECS_USE_OS_ALLOC
#endif
#ifndef FLECS_HI_COMPONENT_ID
#define FLECS_HI_COMPONENT_ID (256)
#endif
#ifndef FLECS_HI_ID_RECORD_ID
#define FLECS_HI_ID_RECORD_ID (1024)
#endif
#ifndef FLECS_SPARSE_PAGE_BITS
#define FLECS_SPARSE_PAGE_BITS (12)
#endif
#ifndef FLECS_ENTITY_PAGE_BITS
#define FLECS_ENTITY_PAGE_BITS (12)
#endif
#ifndef FLECS_ID_DESC_MAX
#define FLECS_ID_DESC_MAX (32)
#endif
#define FLECS_TERM_DESC_MAX (16)
#define FLECS_EVENT_DESC_MAX (8)
#define FLECS_VARIABLE_COUNT_MAX (64)
#define FLECS_QUERY_SCOPE_NESTING_MAX (8)
#ifndef FLECS_API_DEFINES_H
#define FLECS_API_DEFINES_H
#ifndef FLECS_API_FLAGS_H
#define FLECS_API_FLAGS_H
#ifdef __cplusplus
extern "C" {
#endif
#define EcsWorldQuitWorkers (1u << 0)
#define EcsWorldReadonly (1u << 1)
#define EcsWorldInit (1u << 2)
#define EcsWorldQuit (1u << 3)
#define EcsWorldFini (1u << 4)
#define EcsWorldMeasureFrameTime (1u << 5)
#define EcsWorldMeasureSystemTime (1u << 6)
#define EcsWorldMultiThreaded (1u << 7)
#define EcsOsApiHighResolutionTimer (1u << 0)
#define EcsOsApiLogWithColors (1u << 1)
#define EcsOsApiLogWithTimeStamp (1u << 2)
#define EcsOsApiLogWithTimeDelta (1u << 3)
#define EcsEntityIsId (1u << 31)
#define EcsEntityIsTarget (1u << 30)
#define EcsEntityIsTraversable (1u << 29)
#define EcsIdOnDeleteRemove (1u << 0)
#define EcsIdOnDeleteDelete (1u << 1)
#define EcsIdOnDeletePanic (1u << 2)
#define EcsIdOnDeleteMask\
(EcsIdOnDeletePanic|EcsIdOnDeleteRemove|EcsIdOnDeleteDelete)
#define EcsIdOnDeleteObjectRemove (1u << 3)
#define EcsIdOnDeleteObjectDelete (1u << 4)
#define EcsIdOnDeleteObjectPanic (1u << 5)
#define EcsIdOnDeleteObjectMask\
(EcsIdOnDeleteObjectPanic|EcsIdOnDeleteObjectRemove|\
EcsIdOnDeleteObjectDelete)
#define EcsIdExclusive (1u << 6)
#define EcsIdDontInherit (1u << 7)
#define EcsIdTraversable (1u << 8)
#define EcsIdTag (1u << 9)
#define EcsIdWith (1u << 10)
#define EcsIdUnion (1u << 11)
#define EcsIdAlwaysOverride (1u << 12)
#define EcsIdHasOnAdd (1u << 16)
#define EcsIdHasOnRemove (1u << 17)
#define EcsIdHasOnSet (1u << 18)
#define EcsIdHasUnSet (1u << 19)
#define EcsIdHasOnTableFill (1u << 20)
#define EcsIdHasOnTableEmpty (1u << 21)
#define EcsIdHasOnTableCreate (1u << 22)
#define EcsIdHasOnTableDelete (1u << 23)
#define EcsIdEventMask\
(EcsIdHasOnAdd|EcsIdHasOnRemove|EcsIdHasOnSet|EcsIdHasUnSet|\
EcsIdHasOnTableFill|EcsIdHasOnTableEmpty|EcsIdHasOnTableCreate|\
EcsIdHasOnTableDelete)
#define EcsIdMarkedForDelete (1u << 30)
#define ECS_ID_ON_DELETE(flags) \
((ecs_entity_t[]){0, EcsRemove, EcsDelete, 0, EcsPanic}\
[((flags) & EcsIdOnDeleteMask)])
#define ECS_ID_ON_DELETE_TARGET(flags) ECS_ID_ON_DELETE(flags >> 3)
#define ECS_ID_ON_DELETE_FLAG(id) (1u << ((id) - EcsRemove))
#define ECS_ID_ON_DELETE_TARGET_FLAG(id) (1u << (3 + ((id) - EcsRemove)))
#define EcsIterIsValid (1u << 0u)
#define EcsIterNoData (1u << 1u)
#define EcsIterIsInstanced (1u << 2u)
#define EcsIterHasShared (1u << 3u)
#define EcsIterTableOnly (1u << 4u)
#define EcsIterEntityOptional (1u << 5u)
#define EcsIterNoResults (1u << 6u)
#define EcsIterIgnoreThis (1u << 7u)
#define EcsIterMatchVar (1u << 8u)
#define EcsIterHasCondSet (1u << 10u)
#define EcsIterProfile (1u << 11u)
#define EcsEventTableOnly (1u << 4u)
#define EcsEventNoOnSet (1u << 16u)
#define EcsFilterMatchThis (1u << 1u)
#define EcsFilterMatchOnlyThis (1u << 2u)
#define EcsFilterMatchPrefab (1u << 3u)
#define EcsFilterMatchDisabled (1u << 4u)
#define EcsFilterMatchEmptyTables (1u << 5u)
#define EcsFilterMatchAnything (1u << 6u)
#define EcsFilterNoData (1u << 7u)
#define EcsFilterIsInstanced (1u << 8u)
#define EcsFilterPopulate (1u << 9u)
#define EcsFilterHasCondSet (1u << 10u)
#define EcsFilterUnresolvedByName (1u << 11u)
#define EcsFilterHasPred (1u << 12u)
#define EcsFilterHasScopes (1u << 13u)
#define EcsTableHasBuiltins (1u << 1u)
#define EcsTableIsPrefab (1u << 2u)
#define EcsTableHasIsA (1u << 3u)
#define EcsTableHasChildOf (1u << 4u)
#define EcsTableHasName (1u << 5u)
#define EcsTableHasPairs (1u << 6u)
#define EcsTableHasModule (1u << 7u)
#define EcsTableIsDisabled (1u << 8u)
#define EcsTableHasCtors (1u << 9u)
#define EcsTableHasDtors (1u << 10u)
#define EcsTableHasCopy (1u << 11u)
#define EcsTableHasMove (1u << 12u)
#define EcsTableHasUnion (1u << 13u)
#define EcsTableHasToggle (1u << 14u)
#define EcsTableHasOverrides (1u << 15u)
#define EcsTableHasOnAdd (1u << 16u)
#define EcsTableHasOnRemove (1u << 17u)
#define EcsTableHasOnSet (1u << 18u)
#define EcsTableHasUnSet (1u << 19u)
#define EcsTableHasOnTableFill (1u << 20u)
#define EcsTableHasOnTableEmpty (1u << 21u)
#define EcsTableHasOnTableCreate (1u << 22u)
#define EcsTableHasOnTableDelete (1u << 23u)
#define EcsTableHasTraversable (1u << 25u)
#define EcsTableHasTarget (1u << 26u)
#define EcsTableMarkedForDelete (1u << 30u)
#define EcsTableHasLifecycle (EcsTableHasCtors | EcsTableHasDtors)
#define EcsTableIsComplex (EcsTableHasLifecycle | EcsTableHasUnion | EcsTableHasToggle)
#define EcsTableHasAddActions (EcsTableHasIsA | EcsTableHasUnion | EcsTableHasCtors | EcsTableHasOnAdd | EcsTableHasOnSet)
#define EcsTableHasRemoveActions (EcsTableHasIsA | EcsTableHasDtors | EcsTableHasOnRemove | EcsTableHasUnSet)
#define EcsQueryHasRefs (1u << 1u)
#define EcsQueryIsSubquery (1u << 2u)
#define EcsQueryIsOrphaned (1u << 3u)
#define EcsQueryHasOutTerms (1u << 4u)
#define EcsQueryHasNonThisOutTerms (1u << 5u)
#define EcsQueryHasMonitor (1u << 6u)
#define EcsQueryTrivialIter (1u << 7u)
#define EcsAperiodicEmptyTables (1u << 1u)
#define EcsAperiodicComponentMonitors (1u << 2u)
#define EcsAperiodicEmptyQueries (1u << 4u)
#ifdef __cplusplus
}
#endif
#endif
#if defined(_WIN32) || defined(_MSC_VER)
#define ECS_TARGET_WINDOWS
#elif defined(__ANDROID__)
#define ECS_TARGET_ANDROID
#define ECS_TARGET_POSIX
#elif defined(__linux__)
#define ECS_TARGET_LINUX
#define ECS_TARGET_POSIX
#elif defined(__FreeBSD__)
#define ECS_TARGET_FREEBSD
#define ECS_TARGET_POSIX
#elif defined(__APPLE__) && defined(__MACH__)
#define ECS_TARGET_DARWIN
#define ECS_TARGET_POSIX
#elif defined(__EMSCRIPTEN__)
#define ECS_TARGET_EM
#define ECS_TARGET_POSIX
#endif
#if defined(__MINGW32__) || defined(__MINGW64__)
#define ECS_TARGET_MINGW
#endif
#if defined(_MSC_VER)
#ifndef __clang__
#define ECS_TARGET_MSVC
#endif
#endif
#if defined(__clang__)
#define ECS_TARGET_CLANG
#endif
#if defined(__GNUC__)
#define ECS_TARGET_GNU
#endif
#if defined(__clang__)
#if defined(__APPLE__)
#if __clang_major__ == 13
#if __clang_minor__ < 1
#define ECS_CLANG_VERSION 12
#else
#define ECS_CLANG_VERSION 13
#endif
#else
#define ECS_CLANG_VERSION __clang_major__
#endif
#else
#define ECS_CLANG_VERSION __clang_major__
#endif
#endif
#if defined(ECS_TARGET_CLANG)
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#pragma clang diagnostic ignored "-Wdeclaration-after-statement"
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#pragma clang diagnostic ignored "-Wcovered-switch-default"
#pragma clang diagnostic ignored "-Wbad-function-cast"
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#pragma clang diagnostic ignored "-Wunused-macros"
#if __clang_major__ == 13
#pragma clang diagnostic ignored "-Wreserved-identifier"
#endif
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
#pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
#elif defined(ECS_TARGET_GNU)
#ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
#pragma GCC diagnostic ignored "-Wbad-function-cast"
#endif
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#pragma GCC diagnostic ignored "-Wunused-macros"
#endif
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#ifndef FLECS_BAKE_CONFIG_H
#define FLECS_BAKE_CONFIG_H
#ifndef flecs_STATIC
#if defined(flecs_EXPORTS) && (defined(_MSC_VER) || defined(__MINGW32__))
#define FLECS_API __declspec(dllexport)
#elif defined(flecs_EXPORTS)
#define FLECS_API __attribute__((__visibility__("default")))
#elif defined(_MSC_VER)
#define FLECS_API __declspec(dllimport)
#else
#define FLECS_API
#endif
#else
#define FLECS_API
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __BAKE_LEGACY__
#define FLECS_LEGACY
#endif
#ifndef FLECS_NDEBUG
#define FLECS_DBG_API FLECS_API
#else
#define FLECS_DBG_API
#endif
#ifndef FLECS_LEGACY
#include <stdbool.h>
#endif
#ifndef NULL
#define NULL ((void*)0)
#endif
#if !defined(__cplusplus) && !defined(__bool_true_false_are_defined)
#undef bool
#undef true
#undef false
typedef char bool;
#define false 0
#define true !false
#endif
typedef uint8_t ecs_flags8_t;
typedef uint16_t ecs_flags16_t;
typedef uint32_t ecs_flags32_t;
typedef uint64_t ecs_flags64_t;
typedef int32_t ecs_size_t;
typedef struct ecs_allocator_t ecs_allocator_t;
#define ECS_SIZEOF(T) ECS_CAST(ecs_size_t, sizeof(T))
#ifdef __cplusplus
#define ECS_ALIGNOF(T) static_cast<int64_t>(alignof(T))
#elif defined(ECS_TARGET_MSVC)
#define ECS_ALIGNOF(T) (int64_t)__alignof(T)
#elif defined(ECS_TARGET_GNU)
#define ECS_ALIGNOF(T) (int64_t)__alignof__(T)
#else
#define ECS_ALIGNOF(T) ((int64_t)&((struct { char c; T d; } *)0)->d)
#endif
#ifndef FLECS_NO_DEPRECATED_WARNINGS
#if defined(ECS_TARGET_GNU)
#define ECS_DEPRECATED(msg) __attribute__((deprecated(msg)))
#elif defined(ECS_TARGET_MSVC)
#define ECS_DEPRECATED(msg) __declspec(deprecated(msg))
#else
#define ECS_DEPRECATED(msg)
#endif
#else
#define ECS_DEPRECATED(msg)
#endif
#define ECS_ALIGN(size, alignment) (ecs_size_t)((((((size_t)size) - 1) / ((size_t)alignment)) + 1) * ((size_t)alignment))
#define ECS_MAX(a, b) (((a) > (b)) ? a : b)
#define ECS_MIN(a, b) (((a) < (b)) ? a : b)
#ifndef __cplusplus
#define ECS_CAST(T, V) ((T)(V))
#else
#define ECS_CAST(T, V) (static_cast<T>(V))
#endif
#ifndef __cplusplus
#define ECS_CONST_CAST(type, value) ((type)(uintptr_t)(value))
#else
#define ECS_CONST_CAST(type, value) (const_cast<type>(value))
#endif
#ifndef __cplusplus
#define ECS_PTR_CAST(type, value) ((type)(uintptr_t)(value))
#else
#define ECS_PTR_CAST(type, value) (reinterpret_cast<type>(value))
#endif
#define ECS_EQ(a, b) (ecs_os_memcmp(&(a), &(b), sizeof(a)) == 0)
#define ECS_NEQ(a, b) (!ECS_EQ(a, b))
#define ECS_EQZERO(a) ECS_EQ(a, (uint64_t){0})
#define ECS_NEQZERO(a) ECS_NEQ(a, (uint64_t){0})
#define ECS_CONCAT(a, b) a ## b
#define ecs_world_t_magic (0x65637377)
#define ecs_stage_t_magic (0x65637373)
#define ecs_query_t_magic (0x65637371)
#define ecs_rule_t_magic (0x65637375)
#define ecs_table_t_magic (0x65637374)
#define ecs_filter_t_magic (0x65637366)
#define ecs_trigger_t_magic (0x65637372)
#define ecs_observer_t_magic (0x65637362)
#define ECS_ROW_MASK (0x0FFFFFFFu)
#define ECS_ROW_FLAGS_MASK (~ECS_ROW_MASK)
#define ECS_RECORD_TO_ROW(v) (ECS_CAST(int32_t, (ECS_CAST(uint32_t, v) & ECS_ROW_MASK)))
#define ECS_RECORD_TO_ROW_FLAGS(v) (ECS_CAST(uint32_t, v) & ECS_ROW_FLAGS_MASK)
#define ECS_ROW_TO_RECORD(row, flags) (ECS_CAST(uint32_t, (ECS_CAST(uint32_t, row) | (flags))))
#define ECS_ID_FLAGS_MASK (0xFFull << 60)
#define ECS_ENTITY_MASK (0xFFFFFFFFull)
#define ECS_GENERATION_MASK (0xFFFFull << 32)
#define ECS_GENERATION(e) ((e & ECS_GENERATION_MASK) >> 32)
#define ECS_GENERATION_INC(e) ((e & ~ECS_GENERATION_MASK) | ((0xFFFF & (ECS_GENERATION(e) + 1)) << 32))
#define ECS_COMPONENT_MASK (~ECS_ID_FLAGS_MASK)
#define ECS_HAS_ID_FLAG(e, flag) ((e) & ECS_##flag)
#define ECS_IS_PAIR(id) (((id) & ECS_ID_FLAGS_MASK) == ECS_PAIR)
#define ECS_PAIR_FIRST(e) (ecs_entity_t_hi(e & ECS_COMPONENT_MASK))
#define ECS_PAIR_SECOND(e) (ecs_entity_t_lo(e))
#define ECS_HAS_RELATION(e, rel) (ECS_HAS_ID_FLAG(e, PAIR) && (ECS_PAIR_FIRST(e) == rel))
#define ecs_id(T) FLECS_ID##T##ID_
#define ecs_entity_t_lo(value) ECS_CAST(uint32_t, value)
#define ecs_entity_t_hi(value) ECS_CAST(uint32_t, (value) >> 32)
#define ecs_entity_t_comb(lo, hi) ((ECS_CAST(uint64_t, hi) << 32) + ECS_CAST(uint32_t, lo))
#define ecs_pair(pred, obj) (ECS_PAIR | ecs_entity_t_comb(obj, pred))
#define ecs_pair_t(pred, obj) (ECS_PAIR | ecs_entity_t_comb(obj, ecs_id(pred)))
#define ecs_pair_first(world, pair) ecs_get_alive(world, ECS_PAIR_FIRST(pair))
#define ecs_pair_second(world, pair) ecs_get_alive(world, ECS_PAIR_SECOND(pair))
#define ecs_pair_relation ecs_pair_first
#define ecs_pair_object ecs_pair_second
#define ecs_poly_id(tag) ecs_pair(ecs_id(EcsPoly), tag)
#ifndef FLECS_NDEBUG
#define ECS_TABLE_LOCK(world, table) ecs_table_lock(world, table)
#define ECS_TABLE_UNLOCK(world, table) ecs_table_unlock(world, table)
#else
#define ECS_TABLE_LOCK(world, table)
#define ECS_TABLE_UNLOCK(world, table)
#endif
#define EcsIterNextYield (0)
#define EcsIterYield (-1)
#define EcsIterNext (1)
#ifndef FLECS_LEGACY
#define ECS_XTOR_IMPL(type, postfix, var, ...)\
void type##_##postfix(\
void *_ptr,\
int32_t _count,\
const ecs_type_info_t *type_info)\
{\
(void)_ptr;\
(void)_count;\
(void)type_info;\
for (int32_t i = 0; i < _count; i ++) {\
type *var = &((type*)_ptr)[i];\
(void)var;\
__VA_ARGS__\
}\
}
#define ECS_COPY_IMPL(type, dst_var, src_var, ...)\
void type##_##copy(\
void *_dst_ptr,\
const void *_src_ptr,\
int32_t _count,\
const ecs_type_info_t *type_info)\
{\
(void)_dst_ptr;\
(void)_src_ptr;\
(void)_count;\
(void)type_info;\
for (int32_t i = 0; i < _count; i ++) {\
type *dst_var = &((type*)_dst_ptr)[i];\
const type *src_var = &((const type*)_src_ptr)[i];\
(void)dst_var;\
(void)src_var;\
__VA_ARGS__\
}\
}
#define ECS_MOVE_IMPL(type, dst_var, src_var, ...)\
void type##_##move(\
void *_dst_ptr,\
void *_src_ptr,\
int32_t _count,\
const ecs_type_info_t *type_info)\
{\
(void)_dst_ptr;\
(void)_src_ptr;\
(void)_count;\
(void)type_info;\
for (int32_t i = 0; i < _count; i ++) {\
type *dst_var = &((type*)_dst_ptr)[i];\
type *src_var = &((type*)_src_ptr)[i];\
(void)dst_var;\
(void)src_var;\
__VA_ARGS__\
}\
}
#define ECS_HOOK_IMPL(type, func, var, ...)\
void func(ecs_iter_t *_it)\
{\
for (int32_t i = 0; i < _it->count; i ++) {\
ecs_entity_t entity = _it->entities[i];\
type *var = &((type*)_it->ptrs[0])[i];\
(void)entity;\
(void)var;\
__VA_ARGS__\
}\
}
#endif
#ifdef __cplusplus
}
#endif
#endif
#ifndef FLECS_VEC_H
#define FLECS_VEC_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ecs_vec_t {
void *array;
int32_t count;
int32_t size;
#ifdef FLECS_SANITIZE
ecs_size_t elem_size;
#endif
} ecs_vec_t;
FLECS_API
ecs_vec_t* ecs_vec_init(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size,
int32_t elem_count);
#define ecs_vec_init_t(allocator, vec, T, elem_count) \
ecs_vec_init(allocator, vec, ECS_SIZEOF(T), elem_count)
FLECS_API
void ecs_vec_init_if(
ecs_vec_t *vec,
ecs_size_t size);
#define ecs_vec_init_if_t(vec, T) \
ecs_vec_init_if(vec, ECS_SIZEOF(T))
FLECS_API
void ecs_vec_fini(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size);
#define ecs_vec_fini_t(allocator, vec, T) \
ecs_vec_fini(allocator, vec, ECS_SIZEOF(T))
FLECS_API
ecs_vec_t* ecs_vec_reset(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size);
#define ecs_vec_reset_t(allocator, vec, T) \
ecs_vec_reset(allocator, vec, ECS_SIZEOF(T))
FLECS_API
void ecs_vec_clear(
ecs_vec_t *vec);
FLECS_API
void* ecs_vec_append(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size);
#define ecs_vec_append_t(allocator, vec, T) \
ECS_CAST(T*, ecs_vec_append(allocator, vec, ECS_SIZEOF(T)))
FLECS_API
void ecs_vec_remove(
ecs_vec_t *vec,
ecs_size_t size,
int32_t elem);
#define ecs_vec_remove_t(vec, T, elem) \
ecs_vec_remove(vec, ECS_SIZEOF(T), elem)
FLECS_API
void ecs_vec_remove_last(
ecs_vec_t *vec);
FLECS_API
ecs_vec_t ecs_vec_copy(
struct ecs_allocator_t *allocator,
const ecs_vec_t *vec,
ecs_size_t size);
#define ecs_vec_copy_t(allocator, vec, T) \
ecs_vec_copy(allocator, vec, ECS_SIZEOF(T))
FLECS_API
void ecs_vec_reclaim(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size);
#define ecs_vec_reclaim_t(allocator, vec, T) \
ecs_vec_reclaim(allocator, vec, ECS_SIZEOF(T))
FLECS_API
void ecs_vec_set_size(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size,
int32_t elem_count);
#define ecs_vec_set_size_t(allocator, vec, T, elem_count) \
ecs_vec_set_size(allocator, vec, ECS_SIZEOF(T), elem_count)
FLECS_API
void ecs_vec_set_min_size(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size,
int32_t elem_count);
#define ecs_vec_set_min_size_t(allocator, vec, T, elem_count) \
ecs_vec_set_min_size(allocator, vec, ECS_SIZEOF(T), elem_count)
FLECS_API
void ecs_vec_set_min_count(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size,
int32_t elem_count);
#define ecs_vec_set_min_count_t(allocator, vec, T, elem_count) \
ecs_vec_set_min_count(allocator, vec, ECS_SIZEOF(T), elem_count)
FLECS_API
void ecs_vec_set_min_count_zeromem(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size,
int32_t elem_count);
#define ecs_vec_set_min_count_zeromem_t(allocator, vec, T, elem_count) \
ecs_vec_set_min_count_zeromem(allocator, vec, ECS_SIZEOF(T), elem_count)
FLECS_API
void ecs_vec_set_count(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size,
int32_t elem_count);
#define ecs_vec_set_count_t(allocator, vec, T, elem_count) \
ecs_vec_set_count(allocator, vec, ECS_SIZEOF(T), elem_count)
FLECS_API
void* ecs_vec_grow(
struct ecs_allocator_t *allocator,
ecs_vec_t *vec,
ecs_size_t size,
int32_t elem_count);
#define ecs_vec_grow_t(allocator, vec, T, elem_count) \
ecs_vec_grow(allocator, vec, ECS_SIZEOF(T), elem_count)
FLECS_API
int32_t ecs_vec_count(
const ecs_vec_t *vec);
FLECS_API
int32_t ecs_vec_size(
const ecs_vec_t *vec);
FLECS_API
void* ecs_vec_get(
const ecs_vec_t *vec,
ecs_size_t size,
int32_t index);
#define ecs_vec_get_t(vec, T, index) \
ECS_CAST(T*, ecs_vec_get(vec, ECS_SIZEOF(T), index))
FLECS_API
void* ecs_vec_first(
const ecs_vec_t *vec);
#define ecs_vec_first_t(vec, T) \
ECS_CAST(T*, ecs_vec_first(vec))
FLECS_API
void* ecs_vec_last(
const ecs_vec_t *vec,
ecs_size_t size);
#define ecs_vec_last_t(vec, T) \
ECS_CAST(T*, ecs_vec_last(vec, ECS_SIZEOF(T)))
#ifdef __cplusplus
}
#endif
#endif
#ifndef FLECS_SPARSE_H
#define FLECS_SPARSE_H
#ifdef __cplusplus
extern "C" {
#endif
#define FLECS_SPARSE_PAGE_SIZE (1 << FLECS_SPARSE_PAGE_BITS)
typedef struct ecs_sparse_t {
ecs_vec_t dense;
ecs_vec_t pages;
ecs_size_t size;
int32_t count;
uint64_t max_id;
struct ecs_allocator_t *allocator;
struct ecs_block_allocator_t *page_allocator;
} ecs_sparse_t;
FLECS_DBG_API
void flecs_sparse_init(
ecs_sparse_t *sparse,
struct ecs_allocator_t *allocator,
struct ecs_block_allocator_t *page_allocator,
ecs_size_t elem_size);
#define flecs_sparse_init_t(sparse, allocator, page_allocator, T)\
flecs_sparse_init(sparse, allocator, page_allocator, ECS_SIZEOF(T))
FLECS_DBG_API
void flecs_sparse_fini(
ecs_sparse_t *sparse);
FLECS_DBG_API
void flecs_sparse_clear(
ecs_sparse_t *sparse);
FLECS_DBG_API
void* flecs_sparse_add(
ecs_sparse_t *sparse,
ecs_size_t elem_size);
#define flecs_sparse_add_t(sparse, T)\
ECS_CAST(T*, flecs_sparse_add(sparse, ECS_SIZEOF(T)))
FLECS_DBG_API
uint64_t flecs_sparse_last_id(
const ecs_sparse_t *sparse);
FLECS_DBG_API
uint64_t flecs_sparse_new_id(
ecs_sparse_t *sparse);
FLECS_DBG_API
void flecs_sparse_remove(
ecs_sparse_t *sparse,
ecs_size_t elem_size,
uint64_t id);
#define flecs_sparse_remove_t(sparse, T, id)\
flecs_sparse_remove(sparse, ECS_SIZEOF(T), id)
FLECS_DBG_API
bool flecs_sparse_is_alive(
const ecs_sparse_t *sparse,
uint64_t id);
FLECS_DBG_API
void* flecs_sparse_get_dense(
const ecs_sparse_t *sparse,
ecs_size_t elem_size,
int32_t index);
#define flecs_sparse_get_dense_t(sparse, T, index)\
ECS_CAST(T*, flecs_sparse_get_dense(sparse, ECS_SIZEOF(T), index))
FLECS_DBG_API
int32_t flecs_sparse_count(
const ecs_sparse_t *sparse);
FLECS_DBG_API
void* flecs_sparse_get(
const ecs_sparse_t *sparse,
ecs_size_t elem_size,
uint64_t id);
#define flecs_sparse_get_t(sparse, T, index)\
ECS_CAST(T*, flecs_sparse_get(sparse, ECS_SIZEOF(T), index))
FLECS_DBG_API
void* flecs_sparse_try(
const ecs_sparse_t *sparse,
ecs_size_t elem_size,
uint64_t id);
#define flecs_sparse_try_t(sparse, T, index)\
ECS_CAST(T*, flecs_sparse_try(sparse, ECS_SIZEOF(T), index))
FLECS_DBG_API
void* flecs_sparse_get_any(
const ecs_sparse_t *sparse,
ecs_size_t elem_size,
uint64_t id);
#define flecs_sparse_get_any_t(sparse, T, index)\
ECS_CAST(T*, flecs_sparse_get_any(sparse, ECS_SIZEOF(T), index))
FLECS_DBG_API
void* flecs_sparse_ensure(
ecs_sparse_t *sparse,
ecs_size_t elem_size,
uint64_t id);
#define flecs_sparse_ensure_t(sparse, T, index)\
ECS_CAST(T*, flecs_sparse_ensure(sparse, ECS_SIZEOF(T), index))
FLECS_DBG_API
void* flecs_sparse_ensure_fast(
ecs_sparse_t *sparse,
ecs_size_t elem_size,
uint64_t id);
#define flecs_sparse_ensure_fast_t(sparse, T, index)\
ECS_CAST(T*, flecs_sparse_ensure_fast(sparse, ECS_SIZEOF(T), index))
FLECS_DBG_API
const uint64_t* flecs_sparse_ids(
const ecs_sparse_t *sparse);
FLECS_API
void ecs_sparse_init(
ecs_sparse_t *sparse,
ecs_size_t elem_size);
#define ecs_sparse_init_t(sparse, T)\
ecs_sparse_init(sparse, ECS_SIZEOF(T))
FLECS_API
void* ecs_sparse_add(
ecs_sparse_t *sparse,
ecs_size_t elem_size);
#define ecs_sparse_add_t(sparse, T)\
ECS_CAST(T*, ecs_sparse_add(sparse, ECS_SIZEOF(T)))
FLECS_API
uint64_t ecs_sparse_last_id(
const ecs_sparse_t *sparse);
FLECS_API
int32_t ecs_sparse_count(
const ecs_sparse_t *sparse);
FLECS_API
void flecs_sparse_set_generation(
ecs_sparse_t *sparse,
uint64_t id);
FLECS_API
void* ecs_sparse_get_dense(
const ecs_sparse_t *sparse,
ecs_size_t elem_size,
int32_t index);
#define ecs_sparse_get_dense_t(sparse, T, index)\
ECS_CAST(T*, ecs_sparse_get_dense(sparse, ECS_SIZEOF(T), index))
FLECS_API
void* ecs_sparse_get(
const ecs_sparse_t *sparse,
ecs_size_t elem_size,
uint64_t id);
#define ecs_sparse_get_t(sparse, T, index)\
ECS_CAST(T*, ecs_sparse_get(sparse, ECS_SIZEOF(T), index))
#ifdef __cplusplus
}
#endif
#endif
#ifndef FLECS_BLOCK_ALLOCATOR_H
#define FLECS_BLOCK_ALLOCATOR_H
typedef struct ecs_block_allocator_block_t {
void *memory;
struct ecs_block_allocator_block_t *next;
} ecs_block_allocator_block_t;
typedef struct ecs_block_allocator_chunk_header_t {
struct ecs_block_allocator_chunk_header_t *next;
} ecs_block_allocator_chunk_header_t;
typedef struct ecs_block_allocator_t {
ecs_block_allocator_chunk_header_t *head;
ecs_block_allocator_block_t *block_head;
ecs_block_allocator_block_t *block_tail;
int32_t chunk_size;
int32_t data_size;
int32_t chunks_per_block;
int32_t block_size;
int32_t alloc_count;
} ecs_block_allocator_t;
FLECS_API
void flecs_ballocator_init(
ecs_block_allocator_t *ba,
ecs_size_t size);
#define flecs_ballocator_init_t(ba, T)\
flecs_ballocator_init(ba, ECS_SIZEOF(T))
#define flecs_ballocator_init_n(ba, T, count)\
flecs_ballocator_init(ba, ECS_SIZEOF(T) * count)
FLECS_API
ecs_block_allocator_t* flecs_ballocator_new(
ecs_size_t size);
#define flecs_ballocator_new_t(T)\
flecs_ballocator_new(ECS_SIZEOF(T))
#define flecs_ballocator_new_n(T, count)\
flecs_ballocator_new(ECS_SIZEOF(T) * count)
FLECS_API
void flecs_ballocator_fini(
ecs_block_allocator_t *ba);
FLECS_API
void flecs_ballocator_free(
ecs_block_allocator_t *ba);
FLECS_API
void* flecs_balloc(
ecs_block_allocator_t *allocator);
FLECS_API
void* flecs_bcalloc(
ecs_block_allocator_t *allocator);
FLECS_API
void flecs_bfree(
ecs_block_allocator_t *allocator,
void *memory);
FLECS_API
void* flecs_brealloc(
ecs_block_allocator_t *dst,
ecs_block_allocator_t *src,
void *memory);
FLECS_API
void* flecs_bdup(
ecs_block_allocator_t *ba,
void *memory);
#endif
#ifndef FLECS_MAP_H
#define FLECS_MAP_H
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t ecs_map_data_t;
typedef ecs_map_data_t ecs_map_key_t;
typedef ecs_map_data_t ecs_map_val_t;
typedef struct ecs_bucket_entry_t {
ecs_map_key_t key;
ecs_map_val_t value;
struct ecs_bucket_entry_t *next;
} ecs_bucket_entry_t;
typedef struct ecs_bucket_t {
ecs_bucket_entry_t *first;
} ecs_bucket_t;
typedef struct ecs_map_t {
uint8_t bucket_shift;
bool shared_allocator;
ecs_bucket_t *buckets;
int32_t bucket_count;
int32_t count;
struct ecs_block_allocator_t *entry_allocator;
struct ecs_allocator_t *allocator;
} ecs_map_t;
typedef struct ecs_map_iter_t {
const ecs_map_t *map;
ecs_bucket_t *bucket;
ecs_bucket_entry_t *entry;
ecs_map_data_t *res;
} ecs_map_iter_t;
typedef struct ecs_map_params_t {
struct ecs_allocator_t *allocator;
struct ecs_block_allocator_t entry_allocator;
} ecs_map_params_t;
FLECS_API
void ecs_map_params_init(
ecs_map_params_t *params,
struct ecs_allocator_t *allocator);
FLECS_API
void ecs_map_params_fini(
ecs_map_params_t *params);
FLECS_API
void ecs_map_init(
ecs_map_t *map,
struct ecs_allocator_t *allocator);
FLECS_API
void ecs_map_init_w_params(
ecs_map_t *map,
ecs_map_params_t *params);
FLECS_API
void ecs_map_init_if(
ecs_map_t *map,
struct ecs_allocator_t *allocator);
FLECS_API
void ecs_map_init_w_params_if(
ecs_map_t *result,
ecs_map_params_t *params);
FLECS_API
void ecs_map_fini(
ecs_map_t *map);
FLECS_API
ecs_map_val_t* ecs_map_get(
const ecs_map_t *map,
ecs_map_key_t key);
FLECS_API
void* ecs_map_get_deref_(
const ecs_map_t *map,
ecs_map_key_t key);
FLECS_API
ecs_map_val_t* ecs_map_ensure(
ecs_map_t *map,
ecs_map_key_t key);
FLECS_API
void* ecs_map_ensure_alloc(
ecs_map_t *map,
ecs_size_t elem_size,
ecs_map_key_t key);
FLECS_API
void ecs_map_insert(
ecs_map_t *map,
ecs_map_key_t key,
ecs_map_val_t value);
FLECS_API
void* ecs_map_insert_alloc(
ecs_map_t *map,
ecs_size_t elem_size,
ecs_map_key_t key);
FLECS_API
ecs_map_val_t ecs_map_remove(
ecs_map_t *map,
ecs_map_key_t key);
FLECS_API
void ecs_map_remove_free(
ecs_map_t *map,
ecs_map_key_t key);
FLECS_API
void ecs_map_clear(
ecs_map_t *map);
#define ecs_map_count(map) ((map) ? (map)->count : 0)
#define ecs_map_is_init(map) ((map) ? (map)->bucket_shift != 0 : false)
FLECS_API
ecs_map_iter_t ecs_map_iter(
const ecs_map_t *map);
FLECS_API
bool ecs_map_next(
ecs_map_iter_t *iter);
FLECS_API
void ecs_map_copy(
ecs_map_t *dst,
const ecs_map_t *src);
#define ecs_map_get_ref(m, T, k) ECS_CAST(T**, ecs_map_get(m, k))
#define ecs_map_get_deref(m, T, k) ECS_CAST(T*, ecs_map_get_deref_(m, k))
#define ecs_map_ensure_ref(m, T, k) ECS_CAST(T**, ecs_map_ensure(m, k))
#define ecs_map_insert_ptr(m, k, v) ecs_map_insert(m, k, ECS_CAST(ecs_map_val_t, ECS_PTR_CAST(uintptr_t, v)))
#define ecs_map_insert_alloc_t(m, T, k) ECS_CAST(T*, ecs_map_insert_alloc(m, ECS_SIZEOF(T), k))
#define ecs_map_ensure_alloc_t(m, T, k) ECS_PTR_CAST(T*, (uintptr_t)ecs_map_ensure_alloc(m, ECS_SIZEOF(T), k))
#define ecs_map_remove_ptr(m, k) (ECS_PTR_CAST(void*, ECS_CAST(uintptr_t, (ecs_map_remove(m, k)))))
#define ecs_map_key(it) ((it)->res[0])
#define ecs_map_value(it) ((it)->res[1])
#define ecs_map_ptr(it) ECS_PTR_CAST(void*, ECS_CAST(uintptr_t, ecs_map_value(it)))
#define ecs_map_ref(it, T) (ECS_CAST(T**, &((it)->res[1])))
#ifdef __cplusplus
}
#endif
#endif
#ifndef FLECS_ALLOCATOR_H
#define FLECS_ALLOCATOR_H
FLECS_DBG_API extern int64_t ecs_block_allocator_alloc_count;
FLECS_DBG_API extern int64_t ecs_block_allocator_free_count;
FLECS_DBG_API extern int64_t ecs_stack_allocator_alloc_count;
FLECS_DBG_API extern int64_t ecs_stack_allocator_free_count;
struct ecs_allocator_t {
ecs_block_allocator_t chunks;
struct ecs_sparse_t sizes;
};
FLECS_API
void flecs_allocator_init(
ecs_allocator_t *a);
FLECS_API
void flecs_allocator_fini(
ecs_allocator_t *a);
FLECS_API
ecs_block_allocator_t* flecs_allocator_get(
ecs_allocator_t *a,
ecs_size_t size);
FLECS_API
char* flecs_strdup(
ecs_allocator_t *a,
const char* str);
FLECS_API
void flecs_strfree(
ecs_allocator_t *a,
char* str);
FLECS_API
void* flecs_dup(
ecs_allocator_t *a,
ecs_size_t size,
const void *src);
#define flecs_allocator(obj) (&obj->allocators.dyn)
#define flecs_alloc(a, size) flecs_balloc(flecs_allocator_get(a, size))
#define flecs_alloc_t(a, T) flecs_alloc(a, ECS_SIZEOF(T))
#define flecs_alloc_n(a, T, count) flecs_alloc(a, ECS_SIZEOF(T) * (count))
#define flecs_calloc(a, size) flecs_bcalloc(flecs_allocator_get(a, size))
#define flecs_calloc_t(a, T) flecs_calloc(a, ECS_SIZEOF(T))
#define flecs_calloc_n(a, T, count) flecs_calloc(a, ECS_SIZEOF(T) * (count))
#define flecs_free(a, size, ptr) flecs_bfree(flecs_allocator_get(a, size), ptr)
#define flecs_free_t(a, T, ptr) flecs_free(a, ECS_SIZEOF(T), ptr)
#define flecs_free_n(a, T, count, ptr) flecs_free(a, ECS_SIZEOF(T) * (count), ptr)
#define flecs_realloc(a, size_dst, size_src, ptr)\
flecs_brealloc(flecs_allocator_get(a, size_dst),\
flecs_allocator_get(a, size_src),\
ptr)
#define flecs_realloc_n(a, T, count_dst, count_src, ptr)\
flecs_realloc(a, ECS_SIZEOF(T) * (count_dst), ECS_SIZEOF(T) * (count_src), ptr)
#define flecs_dup_n(a, T, count, ptr) flecs_dup(a, ECS_SIZEOF(T) * (count), ptr)
#endif
#ifndef FLECS_STRBUF_H_
#define FLECS_STRBUF_H_
#ifdef __cplusplus
extern "C" {
#endif
#define ECS_STRBUF_INIT (ecs_strbuf_t){0}
#define ECS_STRBUF_ELEMENT_SIZE (511)
#define ECS_STRBUF_MAX_LIST_DEPTH (32)
typedef struct ecs_strbuf_element {
bool buffer_embedded;
int32_t pos;
char *buf;
struct ecs_strbuf_element *next;
} ecs_strbuf_element;
typedef struct ecs_strbuf_element_embedded {
ecs_strbuf_element super;
char buf[ECS_STRBUF_ELEMENT_SIZE + 1];
} ecs_strbuf_element_embedded;
typedef struct ecs_strbuf_element_str {
ecs_strbuf_element super;
char *alloc_str;
} ecs_strbuf_element_str;
typedef struct ecs_strbuf_list_elem {
int32_t count;
const char *separator;
} ecs_strbuf_list_elem;
typedef struct ecs_strbuf_t {
char *buf;
int32_t max;
int32_t size;
int32_t elementCount;
ecs_strbuf_element_embedded firstElement;
ecs_strbuf_element *current;
ecs_strbuf_list_elem list_stack[ECS_STRBUF_MAX_LIST_DEPTH];
int32_t list_sp;
char *content;
int32_t length;
} ecs_strbuf_t;
FLECS_API
bool ecs_strbuf_append(
ecs_strbuf_t *buffer,
const char *fmt,
...);
FLECS_API
bool ecs_strbuf_vappend(
ecs_strbuf_t *buffer,
const char *fmt,
va_list args);
FLECS_API
bool ecs_strbuf_appendstr(
ecs_strbuf_t *buffer,
const char *str);
FLECS_API
bool ecs_strbuf_appendch(
ecs_strbuf_t *buffer,
char ch);
FLECS_API
bool ecs_strbuf_appendint(
ecs_strbuf_t *buffer,
int64_t v);
FLECS_API
bool ecs_strbuf_appendflt(
ecs_strbuf_t *buffer,
double v,
char nan_delim);
FLECS_API
bool ecs_strbuf_appendbool(
ecs_strbuf_t *buffer,
bool v);
FLECS_API
bool ecs_strbuf_mergebuff(
ecs_strbuf_t *dst_buffer,
ecs_strbuf_t *src_buffer);
FLECS_API
bool ecs_strbuf_appendstr_zerocpy(
ecs_strbuf_t *buffer,
char *str);
FLECS_API
bool ecs_strbuf_appendstr_zerocpyn(
ecs_strbuf_t *buffer,
char *str,
int32_t n);
FLECS_API
bool ecs_strbuf_appendstr_zerocpy_const(
ecs_strbuf_t *buffer,
const char *str);
FLECS_API
bool ecs_strbuf_appendstr_zerocpyn_const(
ecs_strbuf_t *buffer,
const char *str,
int32_t n);
FLECS_API
bool ecs_strbuf_appendstrn(
ecs_strbuf_t *buffer,
const char *str,
int32_t n);
FLECS_API
char *ecs_strbuf_get(
ecs_strbuf_t *buffer);
FLECS_API
char *ecs_strbuf_get_small(
ecs_strbuf_t *buffer);
FLECS_API
void ecs_strbuf_reset(
ecs_strbuf_t *buffer);
FLECS_API
void ecs_strbuf_list_push(
ecs_strbuf_t *buffer,
const char *list_open,
const char *separator);
FLECS_API
void ecs_strbuf_list_pop(
ecs_strbuf_t *buffer,
const char *list_close);
FLECS_API
void ecs_strbuf_list_next(
ecs_strbuf_t *buffer);
FLECS_API
bool ecs_strbuf_list_appendch(
ecs_strbuf_t *buffer,
char ch);
FLECS_API
bool ecs_strbuf_list_append(
ecs_strbuf_t *buffer,
const char *fmt,
...);
FLECS_API
bool ecs_strbuf_list_appendstr(
ecs_strbuf_t *buffer,
const char *str);
FLECS_API
bool ecs_strbuf_list_appendstrn(
ecs_strbuf_t *buffer,
const char *str,
int32_t n);
FLECS_API
int32_t ecs_strbuf_written(
const ecs_strbuf_t *buffer);
#define ecs_strbuf_appendlit(buf, str)\
ecs_strbuf_appendstrn(buf, str, (int32_t)(sizeof(str) - 1))
#define ecs_strbuf_list_appendlit(buf, str)\
ecs_strbuf_list_appendstrn(buf, str, (int32_t)(sizeof(str) - 1))
#ifdef __cplusplus
}
#endif
#endif
#ifndef FLECS_OS_API_H
#define FLECS_OS_API_H
#include <stdarg.h>
#include <errno.h>
#if defined(ECS_TARGET_WINDOWS)
#include <malloc.h>
#elif defined(ECS_TARGET_FREEBSD)
#include <stdlib.h>
#else
#include <alloca.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ecs_time_t {
uint32_t sec;
uint32_t nanosec;
} ecs_time_t;
extern int64_t ecs_os_api_malloc_count;
extern int64_t ecs_os_api_realloc_count;
extern int64_t ecs_os_api_calloc_count;
extern int64_t ecs_os_api_free_count;
typedef uintptr_t ecs_os_thread_t;
typedef uintptr_t ecs_os_cond_t;
typedef uintptr_t ecs_os_mutex_t;
typedef uintptr_t ecs_os_dl_t;
typedef uintptr_t ecs_os_sock_t;
typedef uint64_t ecs_os_thread_id_t;
typedef void (*ecs_os_proc_t)(void);
typedef
void (*ecs_os_api_init_t)(void);
typedef
void (*ecs_os_api_fini_t)(void);
typedef
void* (*ecs_os_api_malloc_t)(
ecs_size_t size);
typedef
void (*ecs_os_api_free_t)(
void *ptr);
typedef
void* (*ecs_os_api_realloc_t)(
void *ptr,
ecs_size_t size);
typedef
void* (*ecs_os_api_calloc_t)(
ecs_size_t size);
typedef
char* (*ecs_os_api_strdup_t)(
const char *str);
typedef
void* (*ecs_os_thread_callback_t)(
void*);
typedef
ecs_os_thread_t (*ecs_os_api_thread_new_t)(
ecs_os_thread_callback_t callback,
void *param);
typedef
void* (*ecs_os_api_thread_join_t)(
ecs_os_thread_t thread);
typedef
ecs_os_thread_id_t (*ecs_os_api_thread_self_t)(void);
typedef
ecs_os_thread_t (*ecs_os_api_task_new_t)(
ecs_os_thread_callback_t callback,
void *param);
typedef
void* (*ecs_os_api_task_join_t)(
ecs_os_thread_t thread);
typedef
int32_t (*ecs_os_api_ainc_t)(
int32_t *value);
typedef
int64_t (*ecs_os_api_lainc_t)(
int64_t *value);
typedef
ecs_os_mutex_t (*ecs_os_api_mutex_new_t)(
void);
typedef
void (*ecs_os_api_mutex_lock_t)(
ecs_os_mutex_t mutex);
typedef
void (*ecs_os_api_mutex_unlock_t)(
ecs_os_mutex_t mutex);
typedef
void (*ecs_os_api_mutex_free_t)(
ecs_os_mutex_t mutex);
typedef
ecs_os_cond_t (*ecs_os_api_cond_new_t)(
void);
typedef
void (*ecs_os_api_cond_free_t)(
ecs_os_cond_t cond);
typedef
void (*ecs_os_api_cond_signal_t)(
ecs_os_cond_t cond);
typedef
void (*ecs_os_api_cond_broadcast_t)(
ecs_os_cond_t cond);
typedef
void (*ecs_os_api_cond_wait_t)(
ecs_os_cond_t cond,
ecs_os_mutex_t mutex);
typedef
void (*ecs_os_api_sleep_t)(
int32_t sec,
int32_t nanosec);
typedef
void (*ecs_os_api_enable_high_timer_resolution_t)(
bool enable);
typedef
void (*ecs_os_api_get_time_t)(
ecs_time_t *time_out);
typedef
uint64_t (*ecs_os_api_now_t)(void);
typedef
void (*ecs_os_api_log_t)(
int32_t level,
const char *file,
int32_t line,
const char *msg);
typedef
void (*ecs_os_api_abort_t)(
void);
typedef
ecs_os_dl_t (*ecs_os_api_dlopen_t)(
const char *libname);
typedef
ecs_os_proc_t (*ecs_os_api_dlproc_t)(
ecs_os_dl_t lib,
const char *procname);
typedef
void (*ecs_os_api_dlclose_t)(
ecs_os_dl_t lib);
typedef
char* (*ecs_os_api_module_to_path_t)(
const char *module_id);
typedef struct ecs_os_api_t {
ecs_os_api_init_t init_;
ecs_os_api_fini_t fini_;
ecs_os_api_malloc_t malloc_;
ecs_os_api_realloc_t realloc_;
ecs_os_api_calloc_t calloc_;
ecs_os_api_free_t free_;
ecs_os_api_strdup_t strdup_;
ecs_os_api_thread_new_t thread_new_;
ecs_os_api_thread_join_t thread_join_;
ecs_os_api_thread_self_t thread_self_;
ecs_os_api_thread_new_t task_new_;
ecs_os_api_thread_join_t task_join_;
ecs_os_api_ainc_t ainc_;
ecs_os_api_ainc_t adec_;
ecs_os_api_lainc_t lainc_;
ecs_os_api_lainc_t ladec_;
ecs_os_api_mutex_new_t mutex_new_;
ecs_os_api_mutex_free_t mutex_free_;
ecs_os_api_mutex_lock_t mutex_lock_;
ecs_os_api_mutex_lock_t mutex_unlock_;
ecs_os_api_cond_new_t cond_new_;
ecs_os_api_cond_free_t cond_free_;
ecs_os_api_cond_signal_t cond_signal_;
ecs_os_api_cond_broadcast_t cond_broadcast_;
ecs_os_api_cond_wait_t cond_wait_;
ecs_os_api_sleep_t sleep_;
ecs_os_api_now_t now_;
ecs_os_api_get_time_t get_time_;
ecs_os_api_log_t log_;
ecs_os_api_abort_t abort_;
ecs_os_api_dlopen_t dlopen_;
ecs_os_api_dlproc_t dlproc_;
ecs_os_api_dlclose_t dlclose_;
ecs_os_api_module_to_path_t module_to_dl_;
ecs_os_api_module_to_path_t module_to_etc_;
int32_t log_level_;
int32_t log_indent_;
int32_t log_last_error_;
int64_t log_last_timestamp_;
ecs_flags32_t flags_;
} ecs_os_api_t;
FLECS_API
extern ecs_os_api_t ecs_os_api;
FLECS_API
void ecs_os_init(void);
FLECS_API
void ecs_os_fini(void);
FLECS_API
void ecs_os_set_api(
ecs_os_api_t *os_api);
FLECS_API
ecs_os_api_t ecs_os_get_api(void);
FLECS_API
void ecs_os_set_api_defaults(void);
#ifndef ecs_os_malloc
#define ecs_os_malloc(size) ecs_os_api.malloc_(size)
#endif
#ifndef ecs_os_free
#define ecs_os_free(ptr) ecs_os_api.free_(ptr)
#endif
#ifndef ecs_os_realloc
#define ecs_os_realloc(ptr, size) ecs_os_api.realloc_(ptr, size)
#endif
#ifndef ecs_os_calloc
#define ecs_os_calloc(size) ecs_os_api.calloc_(size)
#endif
#if defined(ECS_TARGET_WINDOWS)
#define ecs_os_alloca(size) _alloca((size_t)(size))
#else
#define ecs_os_alloca(size) alloca((size_t)(size))
#endif
#define ecs_os_malloc_t(T) ECS_CAST(T*, ecs_os_malloc(ECS_SIZEOF(T)))
#define ecs_os_malloc_n(T, count) ECS_CAST(T*, ecs_os_malloc(ECS_SIZEOF(T) * (count)))
#define ecs_os_calloc_t(T) ECS_CAST(T*, ecs_os_calloc(ECS_SIZEOF(T)))
#define ecs_os_calloc_n(T, count) ECS_CAST(T*, ecs_os_calloc(ECS_SIZEOF(T) * (count)))
#define ecs_os_realloc_t(ptr, T) ECS_CAST(T*, ecs_os_realloc(ptr, ECS_SIZEOF(T)))
#define ecs_os_realloc_n(ptr, T, count) ECS_CAST(T*, ecs_os_realloc(ptr, ECS_SIZEOF(T) * (count)))
#define ecs_os_alloca_t(T) ECS_CAST(T*, ecs_os_alloca(ECS_SIZEOF(T)))
#define ecs_os_alloca_n(T, count) ECS_CAST(T*, ecs_os_alloca(ECS_SIZEOF(T) * (count)))
#ifndef ecs_os_strdup
#define ecs_os_strdup(str) ecs_os_api.strdup_(str)
#endif
#ifdef __cplusplus
#define ecs_os_strlen(str) static_cast<ecs_size_t>(strlen(str))
#define ecs_os_strncmp(str1, str2, num) strncmp(str1, str2, static_cast<size_t>(num))
#define ecs_os_memcmp(ptr1, ptr2, num) memcmp(ptr1, ptr2, static_cast<size_t>(num))
#define ecs_os_memcpy(ptr1, ptr2, num) memcpy(ptr1, ptr2, static_cast<size_t>(num))
#define ecs_os_memset(ptr, value, num) memset(ptr, value, static_cast<size_t>(num))
#define ecs_os_memmove(dst, src, size) memmove(dst, src, static_cast<size_t>(size))
#else
#define ecs_os_strlen(str) (ecs_size_t)strlen(str)
#define ecs_os_strncmp(str1, str2, num) strncmp(str1, str2, (size_t)(num))
#define ecs_os_memcmp(ptr1, ptr2, num) memcmp(ptr1, ptr2, (size_t)(num))
#define ecs_os_memcpy(ptr1, ptr2, num) memcpy(ptr1, ptr2, (size_t)(num))
#define ecs_os_memset(ptr, value, num) memset(ptr, value, (size_t)(num))
#define ecs_os_memmove(dst, src, size) memmove(dst, src, (size_t)(size))
#endif
#define ecs_os_memcpy_t(ptr1, ptr2, T) ecs_os_memcpy(ptr1, ptr2, ECS_SIZEOF(T))
#define ecs_os_memcpy_n(ptr1, ptr2, T, count) ecs_os_memcpy(ptr1, ptr2, ECS_SIZEOF(T) * count)
#define ecs_os_memcmp_t(ptr1, ptr2, T) ecs_os_memcmp(ptr1, ptr2, ECS_SIZEOF(T))
#define ecs_os_strcmp(str1, str2) strcmp(str1, str2)
#define ecs_os_memset_t(ptr, value, T) ecs_os_memset(ptr, value, ECS_SIZEOF(T))
#define ecs_os_memset_n(ptr, value, T, count) ecs_os_memset(ptr, value, ECS_SIZEOF(T) * count)
#define ecs_os_zeromem(ptr) ecs_os_memset(ptr, 0, ECS_SIZEOF(*ptr))
#define ecs_os_memdup_t(ptr, T) ecs_os_memdup(ptr, ECS_SIZEOF(T))
#define ecs_os_memdup_n(ptr, T, count) ecs_os_memdup(ptr, ECS_SIZEOF(T) * count)
#define ecs_offset(ptr, T, index)\
ECS_CAST(T*, ECS_OFFSET(ptr, ECS_SIZEOF(T) * index))
#if !defined(ECS_TARGET_POSIX) && !defined(ECS_TARGET_MINGW)
#define ecs_os_strcat(str1, str2) strcat_s(str1, INT_MAX, str2)
#define ecs_os_sprintf(ptr, ...) sprintf_s(ptr, INT_MAX, __VA_ARGS__)
#define ecs_os_vsprintf(ptr, fmt, args) vsprintf_s(ptr, INT_MAX, fmt, args)
#define ecs_os_strcpy(str1, str2) strcpy_s(str1, INT_MAX, str2)
#ifdef __cplusplus
#define ecs_os_strncpy(str1, str2, num) strncpy_s(str1, INT_MAX, str2, static_cast<size_t>(num))
#else
#define ecs_os_strncpy(str1, str2, num) strncpy_s(str1, INT_MAX, str2, (size_t)(num))
#endif
#else
#define ecs_os_strcat(str1, str2) strcat(str1, str2)
#define ecs_os_sprintf(ptr, ...) sprintf(ptr, __VA_ARGS__)
#define ecs_os_vsprintf(ptr, fmt, args) vsprintf(ptr, fmt, args)
#define ecs_os_strcpy(str1, str2) strcpy(str1, str2)
#ifdef __cplusplus
#define ecs_os_strncpy(str1, str2, num) strncpy(str1, str2, static_cast<size_t>(num))
#else
#define ecs_os_strncpy(str1, str2, num) strncpy(str1, str2, (size_t)(num))
#endif
#endif
#ifndef ECS_TARGET_POSIX
#define ecs_os_fopen(result, file, mode) fopen_s(result, file, mode)
#else
#define ecs_os_fopen(result, file, mode) (*(result)) = fopen(file, mode)
#endif
#define ecs_os_thread_new(callback, param) ecs_os_api.thread_new_(callback, param)
#define ecs_os_thread_join(thread) ecs_os_api.thread_join_(thread)
#define ecs_os_thread_self() ecs_os_api.thread_self_()
#define ecs_os_task_new(callback, param) ecs_os_api.task_new_(callback, param)
#define ecs_os_task_join(thread) ecs_os_api.task_join_(thread)
#define ecs_os_ainc(value) ecs_os_api.ainc_(value)
#define ecs_os_adec(value) ecs_os_api.adec_(value)
#define ecs_os_lainc(value) ecs_os_api.lainc_(value)
#define ecs_os_ladec(value) ecs_os_api.ladec_(value)
#define ecs_os_mutex_new() ecs_os_api.mutex_new_()
#define ecs_os_mutex_free(mutex) ecs_os_api.mutex_free_(mutex)
#define ecs_os_mutex_lock(mutex) ecs_os_api.mutex_lock_(mutex)
#define ecs_os_mutex_unlock(mutex) ecs_os_api.mutex_unlock_(mutex)
#define ecs_os_cond_new() ecs_os_api.cond_new_()
#define ecs_os_cond_free(cond) ecs_os_api.cond_free_(cond)
#define ecs_os_cond_signal(cond) ecs_os_api.cond_signal_(cond)
#define ecs_os_cond_broadcast(cond) ecs_os_api.cond_broadcast_(cond)
#define ecs_os_cond_wait(cond, mutex) ecs_os_api.cond_wait_(cond, mutex)
#define ecs_os_sleep(sec, nanosec) ecs_os_api.sleep_(sec, nanosec)
#define ecs_os_now() ecs_os_api.now_()
#define ecs_os_get_time(time_out) ecs_os_api.get_time_(time_out)
FLECS_API
void ecs_os_dbg(const char *file, int32_t line, const char *msg);
FLECS_API
void ecs_os_trace(const char *file, int32_t line, const char *msg);
FLECS_API
void ecs_os_warn(const char *file, int32_t line, const char *msg);
FLECS_API
void ecs_os_err(const char *file, int32_t line, const char *msg);
FLECS_API
void ecs_os_fatal(const char *file, int32_t line, const char *msg);
FLECS_API
const char* ecs_os_strerror(int err);
FLECS_API
void ecs_os_strset(char **str, const char *value);
#ifdef FLECS_ACCURATE_COUNTERS
#define ecs_os_inc(v) (ecs_os_ainc(v))
#define ecs_os_linc(v) (ecs_os_lainc(v))
#define ecs_os_dec(v) (ecs_os_adec(v))
#define ecs_os_ldec(v) (ecs_os_ladec(v))
#else
#define ecs_os_inc(v) (++(*v))
#define ecs_os_linc(v) (++(*v))
#define ecs_os_dec(v) (--(*v))
#define ecs_os_ldec(v) (--(*v))
#endif
#ifdef ECS_TARGET_MINGW
#define ecs_os_isnan(val) (isnan((float)val))
#define ecs_os_isinf(val) (isinf((float)val))
#else
#define ecs_os_isnan(val) (isnan(val))
#define ecs_os_isinf(val) (isinf(val))
#endif
#define ecs_os_abort() ecs_os_api.abort_()
#define ecs_os_dlopen(libname) ecs_os_api.dlopen_(libname)
#define ecs_os_dlproc(lib, procname) ecs_os_api.dlproc_(lib, procname)
#define ecs_os_dlclose(lib) ecs_os_api.dlclose_(lib)
#define ecs_os_module_to_dl(lib) ecs_os_api.module_to_dl_(lib)
#define ecs_os_module_to_etc(lib) ecs_os_api.module_to_etc_(lib)
FLECS_API
void ecs_sleepf(
double t);
FLECS_API
double ecs_time_measure(
ecs_time_t *start);
FLECS_API
ecs_time_t ecs_time_sub(
ecs_time_t t1,
ecs_time_t t2);
FLECS_API
double ecs_time_to_double(
ecs_time_t t);
FLECS_API
void* ecs_os_memdup(
const void *src,
ecs_size_t size);
FLECS_API
bool ecs_os_has_heap(void);
FLECS_API
bool ecs_os_has_threading(void);
FLECS_API
bool ecs_os_has_task_support(void);
FLECS_API
bool ecs_os_has_time(void);
FLECS_API
bool ecs_os_has_logging(void);
FLECS_API
bool ecs_os_has_dl(void);
FLECS_API
bool ecs_os_has_modules(void);
#ifdef __cplusplus
}
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t ecs_id_t;
typedef ecs_id_t ecs_entity_t;
typedef struct {
ecs_id_t *array;
int32_t count;
} ecs_type_t;
typedef struct ecs_world_t ecs_world_t;
typedef struct ecs_table_t ecs_table_t;
typedef struct ecs_term_t ecs_term_t;
typedef struct ecs_filter_t ecs_filter_t;
typedef struct ecs_query_t ecs_query_t;
typedef struct ecs_rule_t ecs_rule_t;
typedef struct ecs_observer_t ecs_observer_t;
typedef struct ecs_observable_t ecs_observable_t;
typedef struct ecs_iter_t ecs_iter_t;
typedef struct ecs_ref_t ecs_ref_t;
typedef struct ecs_type_hooks_t ecs_type_hooks_t;
typedef struct ecs_type_info_t ecs_type_info_t;
typedef struct ecs_record_t ecs_record_t;
typedef struct ecs_id_record_t ecs_id_record_t;
typedef struct ecs_table_record_t ecs_table_record_t;
typedef void ecs_poly_t;
typedef struct ecs_mixins_t ecs_mixins_t;
typedef struct ecs_header_t {
int32_t magic;
int32_t type;
ecs_mixins_t *mixins;
} ecs_header_t;
typedef void (*ecs_run_action_t)(
ecs_iter_t *it);
typedef void (*ecs_iter_action_t)(
ecs_iter_t *it);
typedef void (*ecs_iter_init_action_t)(
const ecs_world_t *world,
const ecs_poly_t *iterable,
ecs_iter_t *it,
ecs_term_t *filter);
typedef bool (*ecs_iter_next_action_t)(
ecs_iter_t *it);
typedef void (*ecs_iter_fini_action_t)(
ecs_iter_t *it);
typedef int (*ecs_order_by_action_t)(
ecs_entity_t e1,
const void *ptr1,
ecs_entity_t e2,
const void *ptr2);
typedef void (*ecs_sort_table_action_t)(
ecs_world_t* world,
ecs_table_t* table,
ecs_entity_t* entities,
void* ptr,
int32_t size,
int32_t lo,
int32_t hi,
ecs_order_by_action_t order_by);
typedef uint64_t (*ecs_group_by_action_t)(
ecs_world_t *world,
ecs_table_t *table,
ecs_id_t group_id,
void *ctx);
typedef void* (*ecs_group_create_action_t)(
ecs_world_t *world,
uint64_t group_id,
void *group_by_ctx);
typedef void (*ecs_group_delete_action_t)(
ecs_world_t *world,
uint64_t group_id,
void *group_ctx,
void *group_by_ctx);
typedef void (*ecs_module_action_t)(
ecs_world_t *world);
typedef void (*ecs_fini_action_t)(
ecs_world_t *world,
void *ctx);
typedef void (*ecs_ctx_free_t)(
void *ctx);
typedef int (*ecs_compare_action_t)(
const void *ptr1,
const void *ptr2);
typedef uint64_t (*ecs_hash_value_action_t)(
const void *ptr);
typedef void (*ecs_xtor_t)(
void *ptr,
int32_t count,
const ecs_type_info_t *type_info);
typedef void (*ecs_copy_t)(
void *dst_ptr,
const void *src_ptr,
int32_t count,
const ecs_type_info_t *type_info);
typedef void (*ecs_move_t)(
void *dst_ptr,
void *src_ptr,
int32_t count,
const ecs_type_info_t *type_info);
typedef void (*ecs_poly_dtor_t)(
ecs_poly_t *poly);
typedef struct ecs_iterable_t {
ecs_iter_init_action_t init;
} ecs_iterable_t;
typedef enum ecs_inout_kind_t {
EcsInOutDefault,
EcsInOutNone,
EcsInOut,
EcsIn,
EcsOut,
} ecs_inout_kind_t;
typedef enum ecs_oper_kind_t {
EcsAnd,
EcsOr,
EcsNot,
EcsOptional,
EcsAndFrom,
EcsOrFrom,
EcsNotFrom,
} ecs_oper_kind_t;
#define EcsSelf (1u << 1)
#define EcsUp (1u << 2)
#define EcsDown (1u << 3)
#define EcsTraverseAll (1u << 4)
#define EcsCascade (1u << 5)
#define EcsParent (1u << 6)
#define EcsIsVariable (1u << 7)
#define EcsIsEntity (1u << 8)
#define EcsIsName (1u << 9)
#define EcsFilter (1u << 10)
#define EcsTraverseFlags (EcsUp|EcsDown|EcsTraverseAll|EcsSelf|EcsCascade|EcsParent)
#define EcsTermMatchAny (1u << 0)
#define EcsTermMatchAnySrc (1u << 1)
#define EcsTermSrcFirstEq (1u << 2)
#define EcsTermSrcSecondEq (1u << 3)
#define EcsTermTransitive (1u << 4)
#define EcsTermReflexive (1u << 5)
#define EcsTermIdInherited (1u << 6)
#define EcsTermMatchDisabled (1u << 7)
#define EcsTermMatchPrefab (1u << 8)
typedef struct ecs_term_id_t {
ecs_entity_t id;
const char *name;
ecs_entity_t trav;
ecs_flags32_t flags;
} ecs_term_id_t;
struct ecs_term_t {
ecs_id_t id;
ecs_term_id_t src;
ecs_term_id_t first;
ecs_term_id_t second;
ecs_inout_kind_t inout;
ecs_oper_kind_t oper;
ecs_id_t id_flags;
char *name;
int32_t field_index;
ecs_id_record_t *idr;
ecs_flags16_t flags;
bool move;
};
FLECS_API extern ecs_filter_t ECS_FILTER_INIT;
struct ecs_filter_t {
ecs_header_t hdr;
ecs_term_t *terms;
int32_t term_count;
int32_t field_count;
bool owned;
bool terms_owned;
ecs_flags32_t flags;
char *variable_names[1];
int32_t *sizes;
ecs_entity_t entity;
ecs_iterable_t iterable;
ecs_poly_dtor_t dtor;
ecs_world_t *world;
};
struct ecs_observer_t {
ecs_header_t hdr;
ecs_filter_t filter;
ecs_entity_t events[FLECS_EVENT_DESC_MAX];
int32_t event_count;
ecs_iter_action_t callback;
ecs_run_action_t run;
void *ctx;
void *binding_ctx;
ecs_ctx_free_t ctx_free;
ecs_ctx_free_t binding_ctx_free;
ecs_observable_t *observable;
int32_t *last_event_id;
int32_t last_event_id_storage;
ecs_id_t register_id;
int32_t term_index;
bool is_monitor;
bool is_multi;
ecs_poly_dtor_t dtor;
};
struct ecs_type_hooks_t {
ecs_xtor_t ctor;
ecs_xtor_t dtor;
ecs_copy_t copy;
ecs_move_t move;
ecs_copy_t copy_ctor;
ecs_move_t move_ctor;
ecs_move_t ctor_move_dtor;
ecs_move_t move_dtor;
ecs_iter_action_t on_add;
ecs_iter_action_t on_set;
ecs_iter_action_t on_remove;
void *ctx;
void *binding_ctx;
ecs_ctx_free_t ctx_free;
ecs_ctx_free_t binding_ctx_free;
};
struct ecs_type_info_t {
ecs_size_t size;
ecs_size_t alignment;
ecs_type_hooks_t hooks;
ecs_entity_t component;
const char *name;
};
#ifndef FLECS_API_TYPES_H
#define FLECS_API_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ecs_stage_t ecs_stage_t;
typedef struct ecs_data_t ecs_data_t;
typedef struct ecs_switch_t ecs_switch_t;
typedef struct ecs_query_table_match_t ecs_query_table_match_t;
typedef struct ecs_event_record_t {
struct ecs_event_id_record_t *any;
struct ecs_event_id_record_t *wildcard;
struct ecs_event_id_record_t *wildcard_pair;
ecs_map_t event_ids;
ecs_entity_t event;
} ecs_event_record_t;
struct ecs_observable_t {
ecs_event_record_t on_add;
ecs_event_record_t on_remove;
ecs_event_record_t on_set;
ecs_event_record_t un_set;
ecs_event_record_t on_wildcard;
ecs_sparse_t events;
};
struct ecs_record_t {
ecs_id_record_t *idr;
ecs_table_t *table;
uint32_t row;
int32_t dense;
};
typedef struct ecs_table_range_t {
ecs_table_t *table;
int32_t offset;
int32_t count;
} ecs_table_range_t;
typedef struct ecs_var_t {
ecs_table_range_t range;
ecs_entity_t entity;
} ecs_var_t;
struct ecs_ref_t {
ecs_entity_t entity;
ecs_entity_t id;
struct ecs_table_record_t *tr;
ecs_record_t *record;
};
struct ecs_stack_page_t;
typedef struct ecs_stack_cursor_t {
struct ecs_stack_cursor_t *prev;
struct ecs_stack_page_t *page;
int16_t sp;
bool is_free;
#ifdef FLECS_DEBUG
struct ecs_stack_t *owner;
#endif
} ecs_stack_cursor_t;
typedef struct ecs_page_iter_t {
int32_t offset;
int32_t limit;
int32_t remaining;
} ecs_page_iter_t;
typedef struct ecs_worker_iter_t {
int32_t index;
int32_t count;
} ecs_worker_iter_t;
typedef struct ecs_table_cache_iter_t {
struct ecs_table_cache_hdr_t *cur, *next;
struct ecs_table_cache_hdr_t *next_list;
} ecs_table_cache_iter_t;
typedef struct ecs_term_iter_t {
ecs_term_t term;
ecs_id_record_t *self_index;
ecs_id_record_t *set_index;
ecs_id_record_t *cur;
ecs_table_cache_iter_t it;
int32_t index;
int32_t observed_table_count;
ecs_table_t *table;
int32_t cur_match;
int32_t match_count;
int32_t last_column;
bool empty_tables;
ecs_id_t id;
int32_t column;
ecs_entity_t subject;
ecs_size_t size;
void *ptr;
} ecs_term_iter_t;
typedef enum ecs_iter_kind_t {
EcsIterEvalCondition,
EcsIterEvalTables,
EcsIterEvalChain,
EcsIterEvalNone
} ecs_iter_kind_t;
typedef struct ecs_filter_iter_t {
const ecs_filter_t *filter;
ecs_iter_kind_t kind;
ecs_term_iter_t term_iter;
int32_t matches_left;
int32_t pivot_term;
} ecs_filter_iter_t;
typedef struct ecs_query_iter_t {
ecs_query_t *query;
ecs_query_table_match_t *node, *prev, *last;
int32_t sparse_smallest;
int32_t sparse_first;
int32_t bitset_first;
int32_t skip_count;
} ecs_query_iter_t;
typedef struct ecs_snapshot_iter_t {
ecs_filter_t filter;
ecs_vec_t tables;
int32_t index;
} ecs_snapshot_iter_t;
typedef struct ecs_rule_op_profile_t {
int32_t count[2];
} ecs_rule_op_profile_t;
typedef struct ecs_rule_iter_t {
const ecs_rule_t *rule;
struct ecs_var_t *vars;
const struct ecs_rule_var_t *rule_vars;
const struct ecs_rule_op_t *ops;
struct ecs_rule_op_ctx_t *op_ctx;
uint64_t *written;
#ifdef FLECS_DEBUG
ecs_rule_op_profile_t *profile;
#endif
bool redo;
int16_t op;
int16_t sp;
} ecs_rule_iter_t;
#define flecs_iter_cache_ids (1u << 0u)
#define flecs_iter_cache_columns (1u << 1u)
#define flecs_iter_cache_sources (1u << 2u)
#define flecs_iter_cache_ptrs (1u << 3u)
#define flecs_iter_cache_match_indices (1u << 4u)
#define flecs_iter_cache_variables (1u << 5u)
#define flecs_iter_cache_all (255)
typedef struct ecs_iter_cache_t {
ecs_stack_cursor_t *stack_cursor;
ecs_flags8_t used;
ecs_flags8_t allocated;
} ecs_iter_cache_t;
typedef struct ecs_iter_private_t {
union {
ecs_term_iter_t term;
ecs_filter_iter_t filter;
ecs_query_iter_t query;
ecs_rule_iter_t rule;
ecs_snapshot_iter_t snapshot;
ecs_page_iter_t page;
ecs_worker_iter_t worker;
} iter;
void *entity_iter;
ecs_iter_cache_t cache;
} ecs_iter_private_t;
struct ecs_iter_t {
ecs_world_t *world;
ecs_world_t *real_world;
ecs_entity_t *entities;
void **ptrs;
ecs_size_t *sizes;
ecs_table_t *table;
ecs_table_t *other_table;
ecs_id_t *ids;
ecs_var_t *variables;
int32_t *columns;
ecs_entity_t *sources;
int32_t *match_indices;
ecs_ref_t *references;
ecs_flags64_t constrained_vars;
uint64_t group_id;
int32_t field_count;
ecs_entity_t system;
ecs_entity_t event;
ecs_id_t event_id;
ecs_term_t *terms;
int32_t table_count;
int32_t term_index;
int32_t variable_count;
char **variable_names;
void *param;
void *ctx;
void *binding_ctx;
ecs_ftime_t delta_time;
ecs_ftime_t delta_system_time;
int32_t frame_offset;
int32_t offset;
int32_t count;
int32_t instance_count;
ecs_flags32_t flags;
ecs_entity_t interrupted_by;
ecs_iter_private_t priv;
ecs_iter_next_action_t next;
ecs_iter_action_t callback;
ecs_iter_action_t set_var;
ecs_iter_fini_action_t fini;
ecs_iter_t *chain_it;
};
#ifdef __cplusplus
}
#endif
#endif
#ifndef FLECS_API_SUPPORT_H
#define FLECS_API_SUPPORT_H
#ifdef __cplusplus
extern "C" {
#endif
#define ECS_MAX_COMPONENT_ID (~((uint32_t)(ECS_ID_FLAGS_MASK >> 32)))
#define ECS_MAX_RECURSION (512)
#define ECS_MAX_TOKEN_SIZE (256)
#define FLECS_ID0ID_ 0
FLECS_API
char* ecs_module_path_from_c(
const char *c_name);
bool ecs_identifier_is_0(
const char *id);
FLECS_API
void ecs_default_ctor(
void *ptr,
int32_t count,
const ecs_type_info_t *ctx);
FLECS_DBG_API
char* ecs_vasprintf(
const char *fmt,
va_list args);
FLECS_API
char* ecs_asprintf(
const char *fmt,
...);
FLECS_API
char* flecs_to_snake_case(
const char *str);
FLECS_DBG_API
int32_t flecs_table_observed_count(
const ecs_table_t *table);
FLECS_DBG_API
void flecs_dump_backtrace(
void *stream);
#ifdef __cplusplus
#define ECS_OFFSET(o, offset) reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(o)) + (static_cast<uintptr_t>(offset)))
#else
#define ECS_OFFSET(o, offset) (void*)(((uintptr_t)(o)) + ((uintptr_t)(offset)))
#endif
#define ECS_OFFSET_T(o, T) ECS_OFFSET(o, ECS_SIZEOF(T))
#define ECS_ELEM(ptr, size, index) ECS_OFFSET(ptr, (size) * (index))
#define ECS_ELEM_T(o, T, index) ECS_ELEM(o, ECS_SIZEOF(T), index)
#define ECS_BIT_SET(flags, bit) (flags) |= (bit)
#define ECS_BIT_CLEAR(flags, bit) (flags) &= ~(bit)
#define ECS_BIT_COND(flags, bit, cond) ((cond) \
? (ECS_BIT_SET(flags, bit)) \
: (ECS_BIT_CLEAR(flags, bit)))
#define ECS_BIT_IS_SET(flags, bit) ((flags) & (bit))
#ifdef __cplusplus
}
#endif
#endif
#ifndef FLECS_HASHMAP_H
#define FLECS_HASHMAP_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
ecs_vec_t keys;
ecs_vec_t values;
} ecs_hm_bucket_t;
typedef struct {
ecs_hash_value_action_t hash;
ecs_compare_action_t compare;
ecs_size_t key_size;
ecs_size_t value_size;
ecs_block_allocator_t *hashmap_allocator;
ecs_block_allocator_t bucket_allocator;
ecs_map_t impl;
} ecs_hashmap_t;
typedef struct {
ecs_map_iter_t it;
ecs_hm_bucket_t *bucket;
int32_t index;
} flecs_hashmap_iter_t;
typedef struct {
void *key;
void *value;
uint64_t hash;
} flecs_hashmap_result_t;
FLECS_DBG_API
void flecs_hashmap_init_(
ecs_hashmap_t *hm,
ecs_size_t key_size,
ecs_size_t value_size,
ecs_hash_value_action_t hash,
ecs_compare_action_t compare,
ecs_allocator_t *allocator);
#define flecs_hashmap_init(hm, K, V, hash, compare, allocator)\
flecs_hashmap_init_(hm, ECS_SIZEOF(K), ECS_SIZEOF(V), hash, compare, allocator)
FLECS_DBG_API
void flecs_hashmap_fini(
ecs_hashmap_t *map);
FLECS_DBG_API
void* flecs_hashmap_get_(
const ecs_hashmap_t *map,
ecs_size_t key_size,
const void *key,
ecs_size_t value_size);
#define flecs_hashmap_get(map, key, V)\
(V*)flecs_hashmap_get_(map, ECS_SIZEOF(*key), key, ECS_SIZEOF(V))
FLECS_DBG_API
flecs_hashmap_result_t flecs_hashmap_ensure_(
ecs_hashmap_t *map,
ecs_size_t key_size,
const void *key,
ecs_size_t value_size);
#define flecs_hashmap_ensure(map, key, V)\
flecs_hashmap_ensure_(map, ECS_SIZEOF(*key), key, ECS_SIZEOF(V))
FLECS_DBG_API
void flecs_hashmap_set_(
ecs_hashmap_t *map,
ecs_size_t key_size,
void *key,
ecs_size_t value_size,
const void *value);
#define flecs_hashmap_set(map, key, value)\
flecs_hashmap_set_(map, ECS_SIZEOF(*key), key, ECS_SIZEOF(*value), value)
FLECS_DBG_API
void flecs_hashmap_remove_(
ecs_hashmap_t *map,
ecs_size_t key_size,
const void *key,
ecs_size_t value_size);
#define flecs_hashmap_remove(map, key, V)\
flecs_hashmap_remove_(map, ECS_SIZEOF(*key), key, ECS_SIZEOF(V))
FLECS_DBG_API
void flecs_hashmap_remove_w_hash_(
ecs_hashmap_t *map,
ecs_size_t key_size,
const void *key,
ecs_size_t value_size,
uint64_t hash);
#define flecs_hashmap_remove_w_hash(map, key, V, hash)\
flecs_hashmap_remove_w_hash_(map, ECS_SIZEOF(*key), key, ECS_SIZEOF(V), hash)
FLECS_DBG_API
ecs_hm_bucket_t* flecs_hashmap_get_bucket(
const ecs_hashmap_t *map,
uint64_t hash);
FLECS_DBG_API
void flecs_hm_bucket_remove(
ecs_hashmap_t *map,
ecs_hm_bucket_t *bucket,
uint64_t hash,
int32_t index);
FLECS_DBG_API
void flecs_hashmap_copy(
ecs_hashmap_t *dst,
const ecs_hashmap_t *src);
FLECS_DBG_API
flecs_hashmap_iter_t flecs_hashmap_iter(
ecs_hashmap_t *map);
FLECS_DBG_API
void* flecs_hashmap_next_(
flecs_hashmap_iter_t *it,
ecs_size_t key_size,
void *key_out,
ecs_size_t value_size);
#define flecs_hashmap_next(map, V)\
(V*)flecs_hashmap_next_(map, 0, NULL, ECS_SIZEOF(V))
#define flecs_hashmap_next_w_key(map, K, key, V)\
(V*)flecs_hashmap_next_(map, ECS_SIZEOF(K), key, ECS_SIZEOF(V))
#ifdef __cplusplus
}
#endif
#endif
typedef struct ecs_entity_desc_t {
int32_t _canary;
ecs_entity_t id;
const char *name;
const char *sep;
const char *root_sep;
const char *symbol;
bool use_low_id;
ecs_id_t add[FLECS_ID_DESC_MAX];
const char *add_expr;
} ecs_entity_desc_t;
typedef struct ecs_bulk_desc_t {
int32_t _canary;
ecs_entity_t *entities;
int32_t count;
ecs_id_t ids[FLECS_ID_DESC_MAX];
void **data;
ecs_table_t *table;
} ecs_bulk_desc_t;
typedef struct ecs_component_desc_t {
int32_t _canary;
ecs_entity_t entity;
ecs_type_info_t type;
} ecs_component_desc_t;
typedef struct ecs_filter_desc_t {
int32_t _canary;
ecs_term_t terms[FLECS_TERM_DESC_MAX];
ecs_term_t *terms_buffer;
int32_t terms_buffer_count;
ecs_filter_t *storage;
bool instanced;
ecs_flags32_t flags;
const char *expr;
ecs_entity_t entity;
} ecs_filter_desc_t;
typedef struct ecs_query_desc_t {
int32_t _canary;
ecs_filter_desc_t filter;
ecs_entity_t order_by_component;
ecs_order_by_action_t order_by;
ecs_sort_table_action_t sort_table;
ecs_id_t group_by_id;
ecs_group_by_action_t group_by;
ecs_group_create_action_t on_group_create;
ecs_group_delete_action_t on_group_delete;
void *group_by_ctx;
ecs_ctx_free_t group_by_ctx_free;
ecs_query_t *parent;
void *ctx;
void *binding_ctx;
ecs_ctx_free_t ctx_free;
ecs_ctx_free_t binding_ctx_free;
} ecs_query_desc_t;
typedef struct ecs_observer_desc_t {
int32_t _canary;
ecs_entity_t entity;
ecs_filter_desc_t filter;
ecs_entity_t events[FLECS_EVENT_DESC_MAX];
bool yield_existing;
ecs_iter_action_t callback;
ecs_run_action_t run;
void *ctx;
void *binding_ctx;
ecs_ctx_free_t ctx_free;
ecs_ctx_free_t binding_ctx_free;
ecs_poly_t *observable;
int32_t *last_event_id;
int32_t term_index;
} ecs_observer_desc_t;
typedef struct ecs_event_desc_t {
ecs_entity_t event;
const ecs_type_t *ids;
ecs_table_t *table;
ecs_table_t *other_table;
int32_t offset;
int32_t count;
ecs_entity_t entity;
const void *param;
ecs_poly_t *observable;
ecs_flags32_t flags;
} ecs_event_desc_t;
typedef struct ecs_value_t {
ecs_entity_t type;
void *ptr;
} ecs_value_t;
typedef struct ecs_world_info_t {
ecs_entity_t last_component_id;
ecs_entity_t min_id;
ecs_entity_t max_id;
ecs_ftime_t delta_time_raw;
ecs_ftime_t delta_time;
ecs_ftime_t time_scale;
ecs_ftime_t target_fps;
ecs_ftime_t frame_time_total;
ecs_ftime_t system_time_total;
ecs_ftime_t emit_time_total;
ecs_ftime_t merge_time_total;
ecs_ftime_t world_time_total;
ecs_ftime_t world_time_total_raw;
ecs_ftime_t rematch_time_total;
int64_t frame_count_total;
int64_t merge_count_total;
int64_t rematch_count_total;
int64_t id_create_total;
int64_t id_delete_total;
int64_t table_create_total;
int64_t table_delete_total;
int64_t pipeline_build_count_total;
int64_t systems_ran_frame;
int64_t observers_ran_frame;
int32_t id_count;
int32_t tag_id_count;
int32_t component_id_count;
int32_t pair_id_count;
int32_t wildcard_id_count;
int32_t table_count;
int32_t tag_table_count;
int32_t trivial_table_count;
int32_t empty_table_count;
int32_t table_record_count;
int32_t table_storage_count;
struct {
int64_t add_count;
int64_t remove_count;
int64_t delete_count;
int64_t clear_count;
int64_t set_count;
int64_t get_mut_count;
int64_t modified_count;
int64_t other_count;
int64_t discard_count;
int64_t batched_entity_count;
int64_t batched_command_count;
} cmd;
const char *name_prefix;
} ecs_world_info_t;
typedef struct ecs_query_group_info_t {
int32_t match_count;
int32_t table_count;
void *ctx;
} ecs_query_group_info_t;
typedef struct EcsIdentifier {
char *value;
ecs_size_t length;
uint64_t hash;
uint64_t index_hash;
ecs_hashmap_t *index;
} EcsIdentifier;
typedef struct EcsComponent {
ecs_size_t size;
ecs_size_t alignment;
} EcsComponent;
typedef struct EcsPoly {
ecs_poly_t *poly;
} EcsPoly;
typedef struct EcsTarget {
int32_t count;
ecs_record_t *target;
} EcsTarget;
typedef ecs_iterable_t EcsIterable;
#ifdef FLECS_DEPRECATED
#ifdef FLECS_DEPRECATED
#ifndef FLECS_DEPRECATED_H
#define FLECS_DEPRECATED_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
FLECS_API extern const ecs_id_t ECS_PAIR;
FLECS_API extern const ecs_id_t ECS_OVERRIDE;
FLECS_API extern const ecs_id_t ECS_TOGGLE;
FLECS_API extern const ecs_id_t ECS_AND;
FLECS_API extern const ecs_entity_t ecs_id(EcsComponent);
FLECS_API extern const ecs_entity_t ecs_id(EcsIdentifier);
FLECS_API extern const ecs_entity_t ecs_id(EcsIterable);
FLECS_API extern const ecs_entity_t ecs_id(EcsPoly);
FLECS_API extern const ecs_entity_t EcsQuery;
FLECS_API extern const ecs_entity_t EcsObserver;
FLECS_API extern const ecs_entity_t EcsSystem;
FLECS_API extern const ecs_entity_t ecs_id(EcsTickSource);
FLECS_API extern const ecs_entity_t ecs_id(EcsPipelineQuery);
FLECS_API extern const ecs_entity_t ecs_id(EcsTimer);
FLECS_API extern const ecs_entity_t ecs_id(EcsRateFilter);
FLECS_API extern const ecs_entity_t EcsFlecs;
FLECS_API extern const ecs_entity_t EcsFlecsCore;
FLECS_API extern const ecs_entity_t EcsWorld;
FLECS_API extern const ecs_entity_t EcsWildcard;
FLECS_API extern const ecs_entity_t EcsAny;
FLECS_API extern const ecs_entity_t EcsThis;
FLECS_API extern const ecs_entity_t EcsVariable;
FLECS_API extern const ecs_entity_t EcsTransitive;
FLECS_API extern const ecs_entity_t EcsReflexive;
FLECS_API extern const ecs_entity_t EcsFinal;
FLECS_API extern const ecs_entity_t EcsDontInherit;
FLECS_API extern const ecs_entity_t EcsAlwaysOverride;
FLECS_API extern const ecs_entity_t EcsSymmetric;
FLECS_API extern const ecs_entity_t EcsExclusive;
FLECS_API extern const ecs_entity_t EcsAcyclic;
FLECS_API extern const ecs_entity_t EcsTraversable;
FLECS_API extern const ecs_entity_t EcsWith;
FLECS_API extern const ecs_entity_t EcsOneOf;
FLECS_API extern const ecs_entity_t EcsTag;
FLECS_API extern const ecs_entity_t EcsUnion;
FLECS_API extern const ecs_entity_t EcsName;
FLECS_API extern const ecs_entity_t EcsSymbol;
FLECS_API extern const ecs_entity_t EcsAlias;
FLECS_API extern const ecs_entity_t EcsChildOf;
FLECS_API extern const ecs_entity_t EcsIsA;
FLECS_API extern const ecs_entity_t EcsDependsOn;
FLECS_API extern const ecs_entity_t EcsSlotOf;
FLECS_API extern const ecs_entity_t EcsModule;
FLECS_API extern const ecs_entity_t EcsPrivate;
FLECS_API extern const ecs_entity_t EcsPrefab;
FLECS_API extern const ecs_entity_t EcsDisabled;
FLECS_API extern const ecs_entity_t EcsOnAdd;
FLECS_API extern const ecs_entity_t EcsOnRemove;
FLECS_API extern const ecs_entity_t EcsOnSet;
FLECS_API extern const ecs_entity_t EcsUnSet;
FLECS_API extern const ecs_entity_t EcsMonitor;
FLECS_API extern const ecs_entity_t EcsOnTableCreate;
FLECS_API extern const ecs_entity_t EcsOnTableDelete;
FLECS_API extern const ecs_entity_t EcsOnTableEmpty;
FLECS_API extern const ecs_entity_t EcsOnTableFill;
FLECS_API extern const ecs_entity_t EcsOnDelete;
FLECS_API extern const ecs_entity_t EcsOnDeleteTarget;
FLECS_API extern const ecs_entity_t EcsRemove;
FLECS_API extern const ecs_entity_t EcsDelete;
FLECS_API extern const ecs_entity_t EcsPanic;
FLECS_API extern const ecs_entity_t ecs_id(EcsTarget);
FLECS_API extern const ecs_entity_t EcsFlatten;
FLECS_API extern const ecs_entity_t EcsDefaultChildComponent;
FLECS_API extern const ecs_entity_t EcsPredEq;
FLECS_API extern const ecs_entity_t EcsPredMatch;
FLECS_API extern const ecs_entity_t EcsPredLookup;
FLECS_API extern const ecs_entity_t EcsScopeOpen;
FLECS_API extern const ecs_entity_t EcsScopeClose;
FLECS_API extern const ecs_entity_t EcsEmpty;
FLECS_API extern const ecs_entity_t ecs_id(EcsPipeline);
FLECS_API extern const ecs_entity_t EcsOnStart;
FLECS_API extern const ecs_entity_t EcsPreFrame;
FLECS_API extern const ecs_entity_t EcsOnLoad;
FLECS_API extern const ecs_entity_t EcsPostLoad;
FLECS_API extern const ecs_entity_t EcsPreUpdate;
FLECS_API extern const ecs_entity_t EcsOnUpdate;
FLECS_API extern const ecs_entity_t EcsOnValidate;
FLECS_API extern const ecs_entity_t EcsPostUpdate;
FLECS_API extern const ecs_entity_t EcsPreStore;
FLECS_API extern const ecs_entity_t EcsOnStore;
FLECS_API extern const ecs_entity_t EcsPostFrame;
FLECS_API extern const ecs_entity_t EcsPhase;
#define EcsLastInternalComponentId (ecs_id(EcsPoly))
#define EcsFirstUserComponentId (8)
#define EcsFirstUserEntityId (FLECS_HI_COMPONENT_ID + 128)
FLECS_API
ecs_world_t* ecs_init(void);
FLECS_API
ecs_world_t* ecs_mini(void);
FLECS_API
ecs_world_t* ecs_init_w_args(
int argc,
char *argv[]);
FLECS_API
int ecs_fini(
ecs_world_t *world);
FLECS_API
bool ecs_is_fini(
const ecs_world_t *world);
FLECS_API
void ecs_atfini(
ecs_world_t *world,
ecs_fini_action_t action,
void *ctx);
FLECS_API
ecs_ftime_t ecs_frame_begin(
ecs_world_t *world,
ecs_ftime_t delta_time);
FLECS_API
void ecs_frame_end(
ecs_world_t *world);
FLECS_API
void ecs_run_post_frame(
ecs_world_t *world,
ecs_fini_action_t action,
void *ctx);
FLECS_API
void ecs_quit(
ecs_world_t *world);
FLECS_API
bool ecs_should_quit(
const ecs_world_t *world);
FLECS_API void ecs_measure_frame_time(
ecs_world_t *world,
bool enable);
FLECS_API void ecs_measure_system_time(
ecs_world_t *world,
bool enable);
FLECS_API
void ecs_set_target_fps(
ecs_world_t *world,
ecs_ftime_t fps);
FLECS_API
bool ecs_readonly_begin(
ecs_world_t *world);
FLECS_API
void ecs_readonly_end(
ecs_world_t *world);
FLECS_API
void ecs_merge(
ecs_world_t *world);
FLECS_API
bool ecs_defer_begin(
ecs_world_t *world);
FLECS_API
bool ecs_is_deferred(
const ecs_world_t *world);
FLECS_API
bool ecs_defer_end(
ecs_world_t *world);
FLECS_API
void ecs_defer_suspend(
ecs_world_t *world);
FLECS_API
void ecs_defer_resume(
ecs_world_t *world);
FLECS_API
void ecs_set_automerge(
ecs_world_t *world,
bool automerge);
FLECS_API
void ecs_set_stage_count(
ecs_world_t *world,
int32_t stages);
FLECS_API
int32_t ecs_get_stage_count(
const ecs_world_t *world);
FLECS_API
int32_t ecs_get_stage_id(
const ecs_world_t *world);
FLECS_API
ecs_world_t* ecs_get_stage(
const ecs_world_t *world,
int32_t stage_id);
FLECS_API
bool ecs_stage_is_readonly(
const ecs_world_t *world);
FLECS_API
ecs_world_t* ecs_async_stage_new(
ecs_world_t *world);
FLECS_API
void ecs_async_stage_free(
ecs_world_t *stage);
FLECS_API
bool ecs_stage_is_async(
ecs_world_t *stage);
FLECS_API
void ecs_set_ctx(
ecs_world_t *world,
void *ctx,
ecs_ctx_free_t ctx_free);
FLECS_API
void ecs_set_binding_ctx(
ecs_world_t *world,
void *ctx,
ecs_ctx_free_t ctx_free);
FLECS_API
void* ecs_get_ctx(
const ecs_world_t *world);
FLECS_API
void* ecs_get_binding_ctx(
const ecs_world_t *world);
FLECS_API
const ecs_world_info_t* ecs_get_world_info(
const ecs_world_t *world);
FLECS_API
void ecs_dim(
ecs_world_t *world,
int32_t entity_count);
FLECS_API
void ecs_set_entity_range(
ecs_world_t *world,
ecs_entity_t id_start,
ecs_entity_t id_end);
FLECS_API
bool ecs_enable_range_check(
ecs_world_t *world,
bool enable);
FLECS_API
ecs_entity_t ecs_get_max_id(
const ecs_world_t *world);
FLECS_API
void ecs_run_aperiodic(
ecs_world_t *world,
ecs_flags32_t flags);
FLECS_API
int32_t ecs_delete_empty_tables(
ecs_world_t *world,
ecs_id_t id,
uint16_t clear_generation,
uint16_t delete_generation,
int32_t min_id_count,
double time_budget_seconds);
FLECS_API
const ecs_world_t* ecs_get_world(
const ecs_poly_t *poly);
FLECS_API
ecs_entity_t ecs_get_entity(
const ecs_poly_t *poly);
FLECS_API
bool ecs_poly_is_(
const ecs_poly_t *object,
int32_t type);
#define ecs_poly_is(object, type)\
ecs_poly_is_(object, type##_magic)
FLECS_API
ecs_id_t ecs_make_pair(
ecs_entity_t first,
ecs_entity_t second);
FLECS_API
ecs_entity_t ecs_new_id(
ecs_world_t *world);
FLECS_API
ecs_entity_t ecs_new_low_id(
ecs_world_t *world);
FLECS_API
ecs_entity_t ecs_new_w_id(
ecs_world_t *world,
ecs_id_t id);
FLECS_API
ecs_entity_t ecs_new_w_table(
ecs_world_t *world,
ecs_table_t *table);
FLECS_API
ecs_entity_t ecs_entity_init(
ecs_world_t *world,
const ecs_entity_desc_t *desc);
FLECS_API
const ecs_entity_t* ecs_bulk_init(
ecs_world_t *world,
const ecs_bulk_desc_t *desc);
FLECS_API
const ecs_entity_t* ecs_bulk_new_w_id(
ecs_world_t *world,
ecs_id_t id,
int32_t count);
FLECS_API
ecs_entity_t ecs_clone(
ecs_world_t *world,
ecs_entity_t dst,
ecs_entity_t src,
bool copy_value);
FLECS_API
void ecs_delete(
ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
void ecs_delete_with(
ecs_world_t *world,
ecs_id_t id);
FLECS_API
void ecs_add_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
void ecs_remove_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
void ecs_override_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
void ecs_clear(
ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
void ecs_remove_all(
ecs_world_t *world,
ecs_id_t id);
FLECS_API
ecs_entity_t ecs_set_with(
ecs_world_t *world,
ecs_id_t id);
FLECS_API
ecs_id_t ecs_get_with(
const ecs_world_t *world);
FLECS_API
void ecs_enable(
ecs_world_t *world,
ecs_entity_t entity,
bool enabled);
FLECS_API
void ecs_enable_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id,
bool enable);
FLECS_API
bool ecs_is_enabled_id(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
const void* ecs_get_id(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
ecs_ref_t ecs_ref_init_id(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
void* ecs_ref_get_id(
const ecs_world_t *world,
ecs_ref_t *ref,
ecs_id_t id);
FLECS_API
void ecs_ref_update(
const ecs_world_t *world,
ecs_ref_t *ref);
FLECS_API
void* ecs_get_mut_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
void* ecs_get_mut_modified_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
ecs_record_t* ecs_write_begin(
ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
void ecs_write_end(
ecs_record_t *record);
FLECS_API
const ecs_record_t* ecs_read_begin(
ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
void ecs_read_end(
const ecs_record_t *record);
FLECS_API
ecs_entity_t ecs_record_get_entity(
const ecs_record_t *record);
FLECS_API
const void* ecs_record_get_id(
ecs_world_t *world,
const ecs_record_t *record,
ecs_id_t id);
FLECS_API
void* ecs_record_get_mut_id(
ecs_world_t *world,
ecs_record_t *record,
ecs_id_t id);
FLECS_API
bool ecs_record_has_id(
ecs_world_t *world,
const ecs_record_t *record,
ecs_id_t id);
FLECS_API
void* ecs_emplace_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
void ecs_modified_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
ecs_entity_t ecs_set_id(
ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id,
size_t size,
const void *ptr);
FLECS_API
bool ecs_is_valid(
const ecs_world_t *world,
ecs_entity_t e);
FLECS_API
bool ecs_is_alive(
const ecs_world_t *world,
ecs_entity_t e);
FLECS_API
ecs_id_t ecs_strip_generation(
ecs_entity_t e);
FLECS_API
void ecs_set_entity_generation(
ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
ecs_entity_t ecs_get_alive(
const ecs_world_t *world,
ecs_entity_t e);
FLECS_API
void ecs_ensure(
ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
void ecs_ensure_id(
ecs_world_t *world,
ecs_id_t id);
FLECS_API
bool ecs_exists(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
const ecs_type_t* ecs_get_type(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
ecs_table_t* ecs_get_table(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
char* ecs_type_str(
const ecs_world_t *world,
const ecs_type_t* type);
FLECS_API
char* ecs_table_str(
const ecs_world_t *world,
const ecs_table_t *table);
FLECS_API
char* ecs_entity_str(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
bool ecs_has_id(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
bool ecs_owns_id(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_id_t id);
FLECS_API
ecs_entity_t ecs_get_target(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t rel,
int32_t index);
FLECS_API
ecs_entity_t ecs_get_parent(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
ecs_entity_t ecs_get_target_for_id(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t rel,
ecs_id_t id);
FLECS_API
int32_t ecs_get_depth(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t rel);
typedef struct ecs_flatten_desc_t {
bool keep_names;
bool lose_depth;
} ecs_flatten_desc_t;
FLECS_API
void ecs_flatten(
ecs_world_t *world,
ecs_id_t pair,
const ecs_flatten_desc_t *desc);
FLECS_API
int32_t ecs_count_id(
const ecs_world_t *world,
ecs_id_t entity);
FLECS_API
const char* ecs_get_name(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
const char* ecs_get_symbol(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
ecs_entity_t ecs_set_name(
ecs_world_t *world,
ecs_entity_t entity,
const char *name);
FLECS_API
ecs_entity_t ecs_set_symbol(
ecs_world_t *world,
ecs_entity_t entity,
const char *symbol);
FLECS_API
void ecs_set_alias(
ecs_world_t *world,
ecs_entity_t entity,
const char *alias);
FLECS_API
ecs_entity_t ecs_lookup(
const ecs_world_t *world,
const char *name);
FLECS_API
ecs_entity_t ecs_lookup_child(
const ecs_world_t *world,
ecs_entity_t parent,
const char *name);
FLECS_API
ecs_entity_t ecs_lookup_path_w_sep(
const ecs_world_t *world,
ecs_entity_t parent,
const char *path,
const char *sep,
const char *prefix,
bool recursive);
FLECS_API
ecs_entity_t ecs_lookup_symbol(
const ecs_world_t *world,
const char *symbol,
bool lookup_as_path,
bool recursive);
FLECS_API
char* ecs_get_path_w_sep(
const ecs_world_t *world,
ecs_entity_t parent,
ecs_entity_t child,
const char *sep,
const char *prefix);
void ecs_get_path_w_sep_buf(
const ecs_world_t *world,
ecs_entity_t parent,
ecs_entity_t child,
const char *sep,
const char *prefix,
ecs_strbuf_t *buf);
FLECS_API
ecs_entity_t ecs_new_from_path_w_sep(
ecs_world_t *world,
ecs_entity_t parent,
const char *path,
const char *sep,
const char *prefix);
FLECS_API
ecs_entity_t ecs_add_path_w_sep(
ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t parent,
const char *path,
const char *sep,
const char *prefix);
FLECS_API
ecs_entity_t ecs_set_scope(
ecs_world_t *world,
ecs_entity_t scope);
FLECS_API
ecs_entity_t ecs_get_scope(
const ecs_world_t *world);
FLECS_API
const char* ecs_set_name_prefix(
ecs_world_t *world,
const char *prefix);
FLECS_API
ecs_entity_t* ecs_set_lookup_path(
ecs_world_t *world,
const ecs_entity_t *lookup_path);
FLECS_API
ecs_entity_t* ecs_get_lookup_path(
const ecs_world_t *world);
FLECS_API
ecs_entity_t ecs_component_init(
ecs_world_t *world,
const ecs_component_desc_t *desc);
FLECS_API
const ecs_type_info_t* ecs_get_type_info(
const ecs_world_t *world,
ecs_id_t id);
FLECS_API
void ecs_set_hooks_id(
ecs_world_t *world,
ecs_entity_t id,
const ecs_type_hooks_t *hooks);
FLECS_API
const ecs_type_hooks_t* ecs_get_hooks_id(
ecs_world_t *world,
ecs_entity_t id);
FLECS_API
bool ecs_id_is_tag(
const ecs_world_t *world,
ecs_id_t id);
FLECS_API
bool ecs_id_is_union(
const ecs_world_t *world,
ecs_id_t id);
FLECS_API
bool ecs_id_in_use(
const ecs_world_t *world,
ecs_id_t id);
FLECS_API
ecs_entity_t ecs_get_typeid(
const ecs_world_t *world,
ecs_id_t id);
FLECS_API
bool ecs_id_match(
ecs_id_t id,
ecs_id_t pattern);
FLECS_API
bool ecs_id_is_pair(
ecs_id_t id);
FLECS_API
bool ecs_id_is_wildcard(
ecs_id_t id);
FLECS_API
bool ecs_id_is_valid(
const ecs_world_t *world,
ecs_id_t id);
FLECS_API
ecs_flags32_t ecs_id_get_flags(
const ecs_world_t *world,
ecs_id_t id);
FLECS_API
const char* ecs_id_flag_str(
ecs_id_t id_flags);
FLECS_API
char* ecs_id_str(
const ecs_world_t *world,
ecs_id_t id);
FLECS_API
void ecs_id_str_buf(
const ecs_world_t *world,
ecs_id_t id,
ecs_strbuf_t *buf);
FLECS_API
ecs_iter_t ecs_term_iter(
const ecs_world_t *world,
ecs_term_t *term);
FLECS_API
ecs_iter_t ecs_term_chain_iter(
const ecs_iter_t *it,
ecs_term_t *term);
FLECS_API
bool ecs_term_next(
ecs_iter_t *it);
FLECS_API
ecs_iter_t ecs_children(
const ecs_world_t *world,
ecs_entity_t parent);
FLECS_API
bool ecs_children_next(
ecs_iter_t *it);
FLECS_API
bool ecs_term_id_is_set(
const ecs_term_id_t *id);
FLECS_API
bool ecs_term_is_initialized(
const ecs_term_t *term);
FLECS_API
bool ecs_term_match_this(
const ecs_term_t *term);
FLECS_API
bool ecs_term_match_0(
const ecs_term_t *term);
FLECS_API
int ecs_term_finalize(
const ecs_world_t *world,
ecs_term_t *term);
FLECS_API
ecs_term_t ecs_term_copy(
const ecs_term_t *src);
FLECS_API
ecs_term_t ecs_term_move(
ecs_term_t *src);
FLECS_API
void ecs_term_fini(
ecs_term_t *term);
FLECS_API
ecs_filter_t * ecs_filter_init(
ecs_world_t *world,
const ecs_filter_desc_t *desc);
FLECS_API
void ecs_filter_fini(
ecs_filter_t *filter);
FLECS_API
int ecs_filter_finalize(
const ecs_world_t *world,
ecs_filter_t *filter);
FLECS_API
int32_t ecs_filter_find_this_var(
const ecs_filter_t *filter);
FLECS_API
char* ecs_term_str(
const ecs_world_t *world,
const ecs_term_t *term);
FLECS_API
char* ecs_filter_str(
const ecs_world_t *world,
const ecs_filter_t *filter);
FLECS_API
ecs_iter_t ecs_filter_iter(
const ecs_world_t *world,
const ecs_filter_t *filter);
FLECS_API
ecs_iter_t ecs_filter_chain_iter(
const ecs_iter_t *it,
const ecs_filter_t *filter);
FLECS_API
int32_t ecs_filter_pivot_term(
const ecs_world_t *world,
const ecs_filter_t *filter);
FLECS_API
bool ecs_filter_next(
ecs_iter_t *it);
FLECS_API
bool ecs_filter_next_instanced(
ecs_iter_t *it);
FLECS_API
void ecs_filter_move(
ecs_filter_t *dst,
ecs_filter_t *src);
FLECS_API
void ecs_filter_copy(
ecs_filter_t *dst,
const ecs_filter_t *src);
FLECS_API
ecs_query_t* ecs_query_init(
ecs_world_t *world,
const ecs_query_desc_t *desc);
FLECS_API
void ecs_query_fini(
ecs_query_t *query);
FLECS_API
const ecs_filter_t* ecs_query_get_filter(
const ecs_query_t *query);
FLECS_API
ecs_iter_t ecs_query_iter(
const ecs_world_t *world,
ecs_query_t *query);
FLECS_API
bool ecs_query_next(
ecs_iter_t *iter);
FLECS_API
bool ecs_query_next_instanced(
ecs_iter_t *iter);
FLECS_API
bool ecs_query_next_table(
ecs_iter_t *iter);
FLECS_API
int ecs_query_populate(
ecs_iter_t *iter,
bool when_changed);
FLECS_API
bool ecs_query_changed(
ecs_query_t *query,
const ecs_iter_t *it);
FLECS_API
void ecs_query_skip(
ecs_iter_t *it);
FLECS_API
void ecs_query_set_group(
ecs_iter_t *it,
uint64_t group_id);
FLECS_API
void* ecs_query_get_group_ctx(
const ecs_query_t *query,
uint64_t group_id);
FLECS_API
const ecs_query_group_info_t* ecs_query_get_group_info(
const ecs_query_t *query,
uint64_t group_id);
FLECS_API
bool ecs_query_orphaned(
const ecs_query_t *query);
FLECS_API
char* ecs_query_str(
const ecs_query_t *query);
FLECS_API
int32_t ecs_query_table_count(
const ecs_query_t *query);
FLECS_API
int32_t ecs_query_empty_table_count(
const ecs_query_t *query);
FLECS_API
int32_t ecs_query_entity_count(
const ecs_query_t *query);
FLECS_API
void* ecs_query_get_ctx(
const ecs_query_t *query);
FLECS_API
void* ecs_query_get_binding_ctx(
const ecs_query_t *query);
FLECS_API
void ecs_emit(
ecs_world_t *world,
ecs_event_desc_t *desc);
FLECS_API
ecs_entity_t ecs_observer_init(
ecs_world_t *world,
const ecs_observer_desc_t *desc);
FLECS_API
bool ecs_observer_default_run_action(
ecs_iter_t *it);
FLECS_API
void* ecs_observer_get_ctx(
const ecs_world_t *world,
ecs_entity_t observer);
FLECS_API
void* ecs_observer_get_binding_ctx(
const ecs_world_t *world,
ecs_entity_t observer);
FLECS_API
void ecs_iter_poly(
const ecs_world_t *world,
const ecs_poly_t *poly,
ecs_iter_t *iter,
ecs_term_t *filter);
FLECS_API
bool ecs_iter_next(
ecs_iter_t *it);
FLECS_API
void ecs_iter_fini(
ecs_iter_t *it);
FLECS_API
int32_t ecs_iter_count(
ecs_iter_t *it);
FLECS_API
bool ecs_iter_is_true(
ecs_iter_t *it);
FLECS_API
ecs_entity_t ecs_iter_first(
ecs_iter_t *it);
FLECS_API
void ecs_iter_set_var(
ecs_iter_t *it,
int32_t var_id,
ecs_entity_t entity);
FLECS_API
void ecs_iter_set_var_as_table(
ecs_iter_t *it,
int32_t var_id,
const ecs_table_t *table);
FLECS_API
void ecs_iter_set_var_as_range(
ecs_iter_t *it,
int32_t var_id,
const ecs_table_range_t *range);
FLECS_API
ecs_entity_t ecs_iter_get_var(
ecs_iter_t *it,
int32_t var_id);
FLECS_API
ecs_table_t* ecs_iter_get_var_as_table(
ecs_iter_t *it,
int32_t var_id);
FLECS_API
ecs_table_range_t ecs_iter_get_var_as_range(
ecs_iter_t *it,
int32_t var_id);
FLECS_API
bool ecs_iter_var_is_constrained(
ecs_iter_t *it,
int32_t var_id);
FLECS_API
char* ecs_iter_str(
const ecs_iter_t *it);
FLECS_API
ecs_iter_t ecs_page_iter(
const ecs_iter_t *it,
int32_t offset,
int32_t limit);
FLECS_API
bool ecs_page_next(
ecs_iter_t *it);
FLECS_API
ecs_iter_t ecs_worker_iter(
const ecs_iter_t *it,
int32_t index,
int32_t count);
FLECS_API
bool ecs_worker_next(
ecs_iter_t *it);
FLECS_API
void* ecs_field_w_size(
const ecs_iter_t *it,
size_t size,
int32_t index);
FLECS_API
bool ecs_field_is_readonly(
const ecs_iter_t *it,
int32_t index);
FLECS_API
bool ecs_field_is_writeonly(
const ecs_iter_t *it,
int32_t index);
FLECS_API
bool ecs_field_is_set(
const ecs_iter_t *it,
int32_t index);
FLECS_API
ecs_id_t ecs_field_id(
const ecs_iter_t *it,
int32_t index);
FLECS_API
int32_t ecs_field_column_index(
const ecs_iter_t *it,
int32_t index);
FLECS_API
ecs_entity_t ecs_field_src(
const ecs_iter_t *it,
int32_t index);
FLECS_API
size_t ecs_field_size(
const ecs_iter_t *it,
int32_t index);
FLECS_API
bool ecs_field_is_self(
const ecs_iter_t *it,
int32_t index);
FLECS_API
const ecs_type_t* ecs_table_get_type(
const ecs_table_t *table);
FLECS_API
int32_t ecs_table_get_type_index(
const ecs_world_t *world,
const ecs_table_t *table,
ecs_id_t id);
FLECS_API
int32_t ecs_table_get_column_index(
const ecs_world_t *world,
const ecs_table_t *table,
ecs_id_t id);
FLECS_API
int32_t ecs_table_column_count(
const ecs_table_t *table);
FLECS_API
int32_t ecs_table_type_to_column_index(
const ecs_table_t *table,
int32_t index);
FLECS_API
int32_t ecs_table_column_to_type_index(
const ecs_table_t *table,
int32_t index);
FLECS_API
void* ecs_table_get_column(
const ecs_table_t *table,
int32_t index,
int32_t offset);
FLECS_API
void* ecs_table_get_id(
const ecs_world_t *world,
const ecs_table_t *table,
ecs_id_t id,
int32_t offset);
FLECS_API
size_t ecs_table_get_column_size(
const ecs_table_t *table,
int32_t index);
FLECS_API
int32_t ecs_table_count(
const ecs_table_t *table);
FLECS_API
bool ecs_table_has_id(
const ecs_world_t *world,
const ecs_table_t *table,
ecs_id_t id);
FLECS_API
int32_t ecs_table_get_depth(
const ecs_world_t *world,
const ecs_table_t *table,
ecs_entity_t rel);
FLECS_API
ecs_table_t* ecs_table_add_id(
ecs_world_t *world,
ecs_table_t *table,
ecs_id_t id);
FLECS_API
ecs_table_t* ecs_table_find(
ecs_world_t *world,
const ecs_id_t *ids,
int32_t id_count);
FLECS_API
ecs_table_t* ecs_table_remove_id(
ecs_world_t *world,
ecs_table_t *table,
ecs_id_t id);
FLECS_API
void ecs_table_lock(
ecs_world_t *world,
ecs_table_t *table);
FLECS_API
void ecs_table_unlock(
ecs_world_t *world,
ecs_table_t *table);
FLECS_API
bool ecs_table_has_flags(
ecs_table_t *table,
ecs_flags32_t flags);
FLECS_API
void ecs_table_swap_rows(
ecs_world_t* world,
ecs_table_t* table,
int32_t row_1,
int32_t row_2);
FLECS_API
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);
FLECS_API
ecs_record_t* ecs_record_find(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
void* ecs_record_get_column(
const ecs_record_t *r,
int32_t column,
size_t c_size);
FLECS_API
int32_t ecs_search(
const ecs_world_t *world,
const ecs_table_t *table,
ecs_id_t id,
ecs_id_t *id_out);
FLECS_API
int32_t ecs_search_offset(
const ecs_world_t *world,
const ecs_table_t *table,
int32_t offset,
ecs_id_t id,
ecs_id_t *id_out);
FLECS_API
int32_t ecs_search_relation(
const ecs_world_t *world,
const ecs_table_t *table,
int32_t offset,
ecs_id_t id,
ecs_entity_t rel,
ecs_flags32_t flags,
ecs_entity_t *subject_out,
ecs_id_t *id_out,
struct ecs_table_record_t **tr_out);
FLECS_API
int ecs_value_init(
const ecs_world_t *world,
ecs_entity_t type,
void *ptr);
FLECS_API
int ecs_value_init_w_type_info(
const ecs_world_t *world,
const ecs_type_info_t *ti,
void *ptr);
FLECS_API
void* ecs_value_new(
ecs_world_t *world,
ecs_entity_t type);
void* ecs_value_new_w_type_info(
ecs_world_t *world,
const ecs_type_info_t *ti);
int ecs_value_fini_w_type_info(
const ecs_world_t *world,
const ecs_type_info_t *ti,
void *ptr);
FLECS_API
int ecs_value_fini(
const ecs_world_t *world,
ecs_entity_t type,
void* ptr);
FLECS_API
int ecs_value_free(
ecs_world_t *world,
ecs_entity_t type,
void* ptr);
FLECS_API
int ecs_value_copy_w_type_info(
const ecs_world_t *world,
const ecs_type_info_t *ti,
void* dst,
const void *src);
FLECS_API
int ecs_value_copy(
const ecs_world_t *world,
ecs_entity_t type,
void* dst,
const void *src);
int ecs_value_move_w_type_info(
const ecs_world_t *world,
const ecs_type_info_t *ti,
void* dst,
void *src);
int ecs_value_move(
const ecs_world_t *world,
ecs_entity_t type,
void* dst,
void *src);
int ecs_value_move_ctor_w_type_info(
const ecs_world_t *world,
const ecs_type_info_t *ti,
void* dst,
void *src);
int ecs_value_move_ctor(
const ecs_world_t *world,
ecs_entity_t type,
void* dst,
void *src);
#ifndef FLECS_C_
#define FLECS_C_
#define ECS_DECLARE(id)\
ecs_entity_t id, ecs_id(id)
#define ECS_ENTITY_DECLARE ECS_DECLARE
#define ECS_ENTITY_DEFINE(world, id_, ...) \
{ \
ecs_entity_desc_t desc = {0}; \
desc.id = id_; \
desc.name = #id_; \
desc.add_expr = #__VA_ARGS__; \
id_ = ecs_entity_init(world, &desc); \
ecs_id(id_) = id_; \
ecs_assert(id_ != 0, ECS_INVALID_PARAMETER, NULL); \
} \
(void)id_; \
(void)ecs_id(id_)
#define ECS_ENTITY(world, id, ...) \
ecs_entity_t ecs_id(id); \
ecs_entity_t id = 0; \
ECS_ENTITY_DEFINE(world, id, __VA_ARGS__)
#define ECS_TAG_DECLARE ECS_DECLARE
#define ECS_TAG_DEFINE(world, id) ECS_ENTITY_DEFINE(world, id, 0)
#define ECS_TAG(world, id) ECS_ENTITY(world, id, 0)
#define ECS_PREFAB_DECLARE ECS_DECLARE
#define ECS_PREFAB_DEFINE(world, id, ...) ECS_ENTITY_DEFINE(world, id, Prefab, __VA_ARGS__)
#define ECS_PREFAB(world, id, ...) ECS_ENTITY(world, id, Prefab, __VA_ARGS__)
#define ECS_COMPONENT_DECLARE(id) ecs_entity_t ecs_id(id)
#define ECS_COMPONENT_DEFINE(world, id_) \
{\
ecs_component_desc_t desc = {0}; \
ecs_entity_desc_t edesc = {0}; \
edesc.id = ecs_id(id_); \
edesc.use_low_id = true; \
edesc.name = #id_; \
edesc.symbol = #id_; \
desc.entity = ecs_entity_init(world, &edesc); \
desc.type.size = ECS_SIZEOF(id_); \
desc.type.alignment = ECS_ALIGNOF(id_); \
ecs_id(id_) = ecs_component_init(world, &desc);\
}\
ecs_assert(ecs_id(id_) != 0, ECS_INVALID_PARAMETER, NULL)
#define ECS_COMPONENT(world, id)\
ecs_entity_t ecs_id(id) = 0;\
ECS_COMPONENT_DEFINE(world, id);\
(void)ecs_id(id)
#define ECS_OBSERVER_DECLARE(id) ecs_entity_t ecs_id(id)
#define ECS_OBSERVER_DEFINE(world, id_, kind, ...)\
{\
ecs_observer_desc_t desc = {0};\
ecs_entity_desc_t edesc = {0}; \
edesc.id = ecs_id(id_); \
edesc.name = #id_; \
desc.entity = ecs_entity_init(world, &edesc); \
desc.callback = id_;\
desc.filter.expr = #__VA_ARGS__;\
desc.events[0] = kind;\
ecs_id(id_) = ecs_observer_init(world, &desc);\
ecs_assert(ecs_id(id_) != 0, ECS_INVALID_PARAMETER, NULL);\
}
#define ECS_OBSERVER(world, id, kind, ...)\
ecs_entity_t ecs_id(id) = 0; \
ECS_OBSERVER_DEFINE(world, id, kind, __VA_ARGS__);\
ecs_entity_t id = ecs_id(id);\
(void)ecs_id(id);\
(void)id
#define ecs_entity(world, ...)\
ecs_entity_init(world, &(ecs_entity_desc_t) __VA_ARGS__ )
#define ecs_component(world, ...)\
ecs_component_init(world, &(ecs_component_desc_t) __VA_ARGS__ )
#define ecs_component_t(world, T)\
ecs_component_init(world, &(ecs_component_desc_t) { \
.entity = ecs_entity(world, { \
.name = #T, \
.symbol = #T, \
.use_low_id = true \
}), \
.type.size = ECS_SIZEOF(T), \
.type.alignment = ECS_ALIGNOF(T) \
})
#define ecs_filter(world, ...)\
ecs_filter_init(world, &(ecs_filter_desc_t) __VA_ARGS__ )
#define ecs_query(world, ...)\
ecs_query_init(world, &(ecs_query_desc_t) __VA_ARGS__ )
#define ecs_observer(world, ...)\
ecs_observer_init(world, &(ecs_observer_desc_t) __VA_ARGS__ )
#define ecs_new(world, T) ecs_new_w_id(world, ecs_id(T))
#define ecs_new_w_pair(world, first, second)\
ecs_new_w_id(world, ecs_pair(first, second))
#define ecs_bulk_new(world, component, count)\
ecs_bulk_new_w_id(world, ecs_id(component), count)
#define ecs_new_entity(world, n)\
ecs_entity_init(world, &(ecs_entity_desc_t){\
.name = n,\
})
#define ecs_new_prefab(world, n)\
ecs_entity_init(world, &(ecs_entity_desc_t){\
.name = n,\
.add = {EcsPrefab}\
})
#define ecs_delete_children(world, parent)\
ecs_delete_with(world, ecs_pair(EcsChildOf, parent))
#define ecs_add(world, entity, T)\
ecs_add_id(world, entity, ecs_id(T))
#define ecs_add_pair(world, subject, first, second)\
ecs_add_id(world, subject, ecs_pair(first, second))
#define ecs_remove(world, entity, T)\
ecs_remove_id(world, entity, ecs_id(T))
#define ecs_remove_pair(world, subject, first, second)\
ecs_remove_id(world, subject, ecs_pair(first, second))
#define ecs_override(world, entity, T)\
ecs_override_id(world, entity, ecs_id(T))
#define ecs_override_pair(world, subject, first, second)\
ecs_override_id(world, subject, ecs_pair(first, second))
#define ecs_set_ptr(world, entity, component, ptr)\
ecs_set_id(world, entity, ecs_id(component), sizeof(component), ptr)
#define ecs_set(world, entity, component, ...)\
ecs_set_id(world, entity, ecs_id(component), sizeof(component), &(component)__VA_ARGS__)
#define ecs_set_pair(world, subject, First, second, ...)\
ecs_set_id(world, subject,\
ecs_pair(ecs_id(First), second),\
sizeof(First), &(First)__VA_ARGS__)
#define ecs_set_pair_second(world, subject, first, Second, ...)\
ecs_set_id(world, subject,\
ecs_pair(first, ecs_id(Second)),\
sizeof(Second), &(Second)__VA_ARGS__)
#define ecs_set_pair_object ecs_set_pair_second
#define ecs_set_override(world, entity, T, ...)\
ecs_add_id(world, entity, ECS_OVERRIDE | ecs_id(T));\
ecs_set(world, entity, T, __VA_ARGS__)
#define ecs_emplace(world, entity, T)\
(ECS_CAST(T*, ecs_emplace_id(world, entity, ecs_id(T))))
#define ecs_emplace_pair(world, entity, First, second)\
(ECS_CAST(First*, ecs_emplace_id(world, entity, ecs_pair_t(First, second))))
#define ecs_get(world, entity, T)\
(ECS_CAST(const T*, ecs_get_id(world, entity, ecs_id(T))))
#define ecs_get_pair(world, subject, First, second)\
(ECS_CAST(const First*, ecs_get_id(world, subject,\
ecs_pair(ecs_id(First), second))))
#define ecs_get_pair_second(world, subject, first, Second)\
(ECS_CAST(const Second*, ecs_get_id(world, subject,\
ecs_pair(first, ecs_id(Second)))))
#define ecs_get_pair_object ecs_get_pair_second
#define ecs_record_get(world, record, T)\
(ECS_CAST(const T*, ecs_record_get_id(world, record, ecs_id(T))))
#define ecs_record_has(world, record, T)\
(ecs_record_has_id(world, record, ecs_id(T)))
#define ecs_record_get_pair(world, record, First, second)\
(ECS_CAST(const First*, ecs_record_get_id(world, record, \
ecs_pair(ecs_id(First), second))))
#define ecs_record_get_pair_second(world, record, first, Second)\
(ECS_CAST(const Second*, ecs_record_get_id(world, record,\
ecs_pair(first, ecs_id(Second)))))
#define ecs_record_get_mut(world, record, T)\
(ECS_CAST(T*, ecs_record_get_mut_id(world, record, ecs_id(T))))
#define ecs_record_get_mut_pair(world, record, First, second)\
(ECS_CAST(First*, ecs_record_get_mut_id(world, record, \
ecs_pair(ecs_id(First), second))))
#define ecs_record_get_mut_pair_second(world, record, first, Second)\
(ECS_CAST(Second*, ecs_record_get_mut_id(world, record,\
ecs_pair(first, ecs_id(Second)))))
#define ecs_record_get_mut_pair_object ecs_record_get_mut_pair_second
#define ecs_ref_init(world, entity, T)\
ecs_ref_init_id(world, entity, ecs_id(T))
#define ecs_ref_get(world, ref, T)\
(ECS_CAST(const T*, ecs_ref_get_id(world, ref, ecs_id(T))))
#define ecs_get_mut(world, entity, T)\
(ECS_CAST(T*, ecs_get_mut_id(world, entity, ecs_id(T))))
#define ecs_get_mut_pair(world, subject, First, second)\
(ECS_CAST(First*, ecs_get_mut_id(world, subject,\
ecs_pair(ecs_id(First), second))))
#define ecs_get_mut_pair_second(world, subject, first, Second)\
(ECS_CAST(Second*, ecs_get_mut_id(world, subject,\
ecs_pair(first, ecs_id(Second)))))
#define ecs_get_mut_pair_object ecs_get_mut_pair_second
#define ecs_modified(world, entity, component)\
ecs_modified_id(world, entity, ecs_id(component))
#define ecs_modified_pair(world, subject, first, second)\
ecs_modified_id(world, subject, ecs_pair(first, second))
#define ecs_singleton_add(world, comp)\
ecs_add(world, ecs_id(comp), comp)
#define ecs_singleton_remove(world, comp)\
ecs_remove(world, ecs_id(comp), comp)
#define ecs_singleton_get(world, comp)\
ecs_get(world, ecs_id(comp), comp)
#define ecs_singleton_set_ptr(world, comp, ptr)\
ecs_set_ptr(world, ecs_id(comp), comp, ptr)
#define ecs_singleton_set(world, comp, ...)\
ecs_set(world, ecs_id(comp), comp, __VA_ARGS__)
#define ecs_singleton_get_mut(world, comp)\
ecs_get_mut(world, ecs_id(comp), comp)
#define ecs_singleton_modified(world, comp)\
ecs_modified(world, ecs_id(comp), comp)
#define ecs_has(world, entity, T)\
ecs_has_id(world, entity, ecs_id(T))
#define ecs_has_pair(world, entity, first, second)\
ecs_has_id(world, entity, ecs_pair(first, second))
#define ecs_owns_pair(world, entity, first, second)\
ecs_owns_id(world, entity, ecs_pair(first, second))
#define ecs_owns(world, entity, T)\
ecs_owns_id(world, entity, ecs_id(T))
#define ecs_shares_id(world, entity, id)\
(ecs_search_relation(world, ecs_get_table(world, entity), 0, ecs_id(id), \
EcsIsA, 1, 0, 0, 0, 0) != -1)
#define ecs_shares_pair(world, entity, first, second)\
(ecs_shares_id(world, entity, ecs_pair(first, second)))
#define ecs_shares(world, entity, T)\
(ecs_shares_id(world, entity, ecs_id(T)))
#define ecs_enable_component(world, entity, T, enable)\
ecs_enable_id(world, entity, ecs_id(T), enable)
#define ecs_is_enabled_component(world, entity, T)\
ecs_is_enabled_id(world, entity, ecs_id(T))
#define ecs_enable_pair(world, entity, First, second, enable)\
ecs_enable_id(world, entity, ecs_pair(ecs_id(First), second), enable)
#define ecs_is_enabled_pair(world, entity, First, second)\
ecs_is_enabled_id(world, entity, ecs_pair(ecs_id(First), second))
#define ecs_lookup_path(world, parent, path)\
ecs_lookup_path_w_sep(world, parent, path, ".", NULL, true)
#define ecs_lookup_fullpath(world, path)\
ecs_lookup_path_w_sep(world, 0, path, ".", NULL, true)
#define ecs_get_path(world, parent, child)\
ecs_get_path_w_sep(world, parent, child, ".", NULL)
#define ecs_get_fullpath(world, child)\
ecs_get_path_w_sep(world, 0, child, ".", NULL)
#define ecs_get_fullpath_buf(world, child, buf)\
ecs_get_path_w_sep_buf(world, 0, child, ".", NULL, buf)
#define ecs_new_from_path(world, parent, path)\
ecs_new_from_path_w_sep(world, parent, path, ".", NULL)
#define ecs_new_from_fullpath(world, path)\
ecs_new_from_path_w_sep(world, 0, path, ".", NULL)
#define ecs_add_path(world, entity, parent, path)\
ecs_add_path_w_sep(world, entity, parent, path, ".", NULL)
#define ecs_add_fullpath(world, entity, path)\
ecs_add_path_w_sep(world, entity, 0, path, ".", NULL)
#define ecs_set_hooks(world, T, ...)\
ecs_set_hooks_id(world, ecs_id(T), &(ecs_type_hooks_t)__VA_ARGS__)
#define ecs_get_hooks(world, T)\
ecs_get_hooks_id(world, ecs_id(T));
#define ECS_CTOR(type, var, ...)\
ECS_XTOR_IMPL(type, ctor, var, __VA_ARGS__)
#define ECS_DTOR(type, var, ...)\
ECS_XTOR_IMPL(type, dtor, var, __VA_ARGS__)
#define ECS_COPY(type, dst_var, src_var, ...)\
ECS_COPY_IMPL(type, dst_var, src_var, __VA_ARGS__)
#define ECS_MOVE(type, dst_var, src_var, ...)\
ECS_MOVE_IMPL(type, dst_var, src_var, __VA_ARGS__)
#define ECS_ON_ADD(type, ptr, ...)\
ECS_HOOK_IMPL(type, ecs_on_add(type), ptr, __VA_ARGS__)
#define ECS_ON_REMOVE(type, ptr, ...)\
ECS_HOOK_IMPL(type, ecs_on_remove(type), ptr, __VA_ARGS__)
#define ECS_ON_SET(type, ptr, ...)\
ECS_HOOK_IMPL(type, ecs_on_set(type), ptr, __VA_ARGS__)
#define ecs_ctor(type) type##_ctor
#define ecs_dtor(type) type##_dtor
#define ecs_copy(type) type##_copy
#define ecs_move(type) type##_move
#define ecs_on_set(type) type##_on_set
#define ecs_on_add(type) type##_on_add
#define ecs_on_remove(type) type##_on_remove
#define ecs_count(world, type)\
ecs_count_id(world, ecs_id(type))
#define ecs_field(it, T, index)\
(ECS_CAST(T*, ecs_field_w_size(it, sizeof(T), index)))
#define ecs_table_get(world, table, T, offset)\
(ECS_CAST(T*, ecs_table_get_id(world, table, ecs_id(T), offset)))
#define ecs_table_get_pair(world, table, First, second, offset)\
(ECS_CAST(First*, ecs_table_get_id(world, table, ecs_pair(ecs_id(First), second), offset)))
#define ecs_table_get_pair_second(world, table, first, Second, offset)\
(ECS_CAST(Second*, ecs_table_get_id(world, table, ecs_pair(first, ecs_id(Second)), offset)))
#define ecs_value(T, ptr) ((ecs_value_t){ecs_id(T), ptr})
#define ecs_value_new_t(world, T) ecs_value_new(world, ecs_id(T))
#define ecs_sort_table(id) ecs_id(id##_sort_table)
#define ecs_compare(id) ecs_id(id##_compare_fn)
#define ECS_SORT_TABLE_WITH_COMPARE(id, op_name, compare_fn, ...) \
static int32_t ECS_CONCAT(op_name, _partition)( \
ecs_world_t *world, \
ecs_table_t *table, \
ecs_entity_t *entities, \
void *ptr, \
int32_t elem_size, \
int32_t lo, \
int32_t hi, \
ecs_order_by_action_t order_by) \
{ \
(void)(order_by); \
int32_t p = (hi + lo) / 2; \
void *pivot = ECS_ELEM(ptr, elem_size, p); \
ecs_entity_t pivot_e = entities[p]; \
int32_t i = lo - 1, j = hi + 1; \
void *el; \
repeat: \
{ \
do { \
i ++; \
el = ECS_ELEM(ptr, elem_size, i); \
} while ( compare_fn(entities[i], el, pivot_e, pivot) < 0); \
do { \
j --; \
el = ECS_ELEM(ptr, elem_size, j); \
} while ( compare_fn(entities[j], el, pivot_e, pivot) > 0); \
if (i >= j) { \
return j; \
} \
ecs_table_swap_rows(world, table, i, j); \
if (p == i) { \
pivot = ECS_ELEM(ptr, elem_size, j); \
pivot_e = entities[j]; \
} else if (p == j) { \
pivot = ECS_ELEM(ptr, elem_size, i); \
pivot_e = entities[i]; \
} \
goto repeat; \
} \
} \
__VA_ARGS__ void op_name( \
ecs_world_t *world, \
ecs_table_t *table, \
ecs_entity_t *entities, \
void *ptr, \
int32_t size, \
int32_t lo, \
int32_t hi, \
ecs_order_by_action_t order_by) \
{ \
if ((hi - lo) < 1) { \
return; \
} \
int32_t p = ECS_CONCAT(op_name, _partition)(world, table, entities, ptr, size, lo, hi, order_by); \
op_name(world, table, entities, ptr, size, lo, p, order_by); \
op_name(world, table, entities, ptr, size, p + 1, hi, order_by); \
}
#define ECS_SORT_TABLE(id, ...) \
ECS_SORT_TABLE_WITH_COMPARE(id, ecs_sort_table(id), ecs_compare(id), __VA_ARGS__)
#define ECS_COMPARE(id, ...) \
int ecs_compare(id)(ecs_entity_t e1, const void* ptr1, ecs_entity_t e2, const void* ptr2) { \
__VA_ARGS__ \
}
#define ecs_isa(e) ecs_pair(EcsIsA, e)
#define ecs_childof(e) ecs_pair(EcsChildOf, e)
#define ecs_dependson(e) ecs_pair(EcsDependsOn, e)
#define ecs_query_new(world, q_expr)\
ecs_query_init(world, &(ecs_query_desc_t){\
.filter.expr = q_expr\
})
#define ecs_rule_new(world, q_expr)\
ecs_rule_init(world, &(ecs_filter_desc_t){\
.expr = q_expr\
})
#endif
#ifdef __cplusplus
}
#endif
#ifndef FLECS_ADDONS_H
#define FLECS_ADDONS_H
#ifdef FLECS_NO_CPP
#undef FLECS_CPP
#endif
#ifdef FLECS_NO_MODULE
#undef FLECS_MODULE
#endif
#ifdef FLECS_NO_PARSER
#undef FLECS_PARSER
#endif
#ifdef FLECS_NO_PLECS
#undef FLECS_PLECS
#endif
#ifdef FLECS_NO_RULES
#undef FLECS_RULES
#endif
#ifdef FLECS_NO_SNAPSHOT
#undef FLECS_SNAPSHOT
#endif
#ifdef FLECS_NO_MONITOR
#undef FLECS_MONITOR
#endif
#ifdef FLECS_NO_STATS
#undef FLECS_STATS
#endif
#ifdef FLECS_NO_SYSTEM
#undef FLECS_SYSTEM
#endif
#ifdef FLECS_NO_PIPELINE
#undef FLECS_PIPELINE
#endif
#ifdef FLECS_NO_TIMER
#undef FLECS_TIMER
#endif
#ifdef FLECS_NO_META
#undef FLECS_META
#endif
#ifdef FLECS_NO_META_C
#undef FLECS_META_C
#endif
#ifdef FLECS_NO_UNITS
#undef FLECS_UNITS
#endif
#ifdef FLECS_NO_EXPR
#undef FLECS_EXPR
#endif
#ifdef FLECS_NO_JSON
#undef FLECS_JSON
#endif
#ifdef FLECS_NO_DOC
#undef FLECS_DOC
#endif
#ifdef FLECS_NO_COREDOC
#undef FLECS_COREDOC
#endif
#ifdef FLECS_NO_LOG
#undef FLECS_LOG
#endif
#ifdef FLECS_NO_APP
#undef FLECS_APP
#endif
#ifdef FLECS_NO_OS_API_IMPL
#undef FLECS_OS_API_IMPL
#endif
#ifdef FLECS_NO_HTTP
#undef FLECS_HTTP
#endif
#ifdef FLECS_NO_REST
#undef FLECS_REST
#endif
#ifdef FLECS_NO_JOURNAL
#undef FLECS_JOURNAL
#endif
#ifdef FLECS_JOURNAL
#ifndef FLECS_LOG
#define FLECS_LOG
#endif
#ifndef FLECS_JOURNAL_H
#define FLECS_JOURNAL_H
#define FLECS_JOURNAL_LOG_LEVEL (0)
#ifdef __cplusplus
extern "C" {
#endif
typedef enum ecs_journal_kind_t {
EcsJournalNew,
EcsJournalMove,
EcsJournalClear,
EcsJournalDelete,
EcsJournalDeleteWith,
EcsJournalRemoveAll,
EcsJournalTableEvents
} ecs_journal_kind_t;
FLECS_DBG_API
void flecs_journal_begin(
ecs_world_t *world,
ecs_journal_kind_t kind,
ecs_entity_t entity,
ecs_type_t *add,
ecs_type_t *remove);
FLECS_DBG_API
void flecs_journal_end(void);
#define flecs_journal(...)\
flecs_journal_begin(__VA_ARGS__);\
flecs_journal_end();
#ifdef __cplusplus
}
#endif #endif #else
#define flecs_journal_begin(...)
#define flecs_journal_end(...)
#define flecs_journal(...)
#endif
#ifndef FLECS_LOG_H
#define FLECS_LOG_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef FLECS_LOG
FLECS_API
void ecs_deprecated_(
const char *file,
int32_t line,
const char *msg);
FLECS_API
void ecs_log_push_(int32_t level);
FLECS_API
void ecs_log_pop_(int32_t level);
FLECS_API
bool ecs_should_log(int32_t level);
FLECS_API
const char* ecs_strerror(
int32_t error_code);
#else
#define ecs_deprecated_(file, line, msg)\
(void)file;\
(void)line;\
(void)msg
#define ecs_log_push_(level)
#define ecs_log_pop_(level)
#define ecs_should_log(level) false
#define ecs_strerror(error_code)\
(void)error_code
#endif
FLECS_API
void ecs_print_(
int32_t level,
const char *file,
int32_t line,
const char *fmt,
...);
FLECS_API
void ecs_printv_(
int level,
const char *file,
int32_t line,
const char *fmt,
va_list args);
FLECS_API
void ecs_log_(
int32_t level,
const char *file,
int32_t line,
const char *fmt,
...);
FLECS_API
void ecs_logv_(
int level,
const char *file,
int32_t line,
const char *fmt,
va_list args);
FLECS_API
void ecs_abort_(
int32_t error_code,
const char *file,
int32_t line,
const char *fmt,
...);
FLECS_API
bool ecs_assert_(
bool condition,
int32_t error_code,
const char *condition_str,
const char *file,
int32_t line,
const char *fmt,
...);
FLECS_API
void ecs_parser_error_(
const char *name,
const char *expr,
int64_t column,
const char *fmt,
...);
FLECS_API
void ecs_parser_errorv_(
const char *name,
const char *expr,
int64_t column,
const char *fmt,
va_list args);
#ifndef FLECS_LEGACY
#define ecs_print(level, ...)\
ecs_print_(level, __FILE__, __LINE__, __VA_ARGS__)
#define ecs_printv(level, fmt, args)\
ecs_printv_(level, __FILE__, __LINE__, fmt, args)
#define ecs_log(level, ...)\
ecs_log_(level, __FILE__, __LINE__, __VA_ARGS__)
#define ecs_logv(level, fmt, args)\
ecs_logv_(level, __FILE__, __LINE__, fmt, args)
#define ecs_trace_(file, line, ...) ecs_log_(0, file, line, __VA_ARGS__)
#define ecs_trace(...) ecs_trace_(__FILE__, __LINE__, __VA_ARGS__)
#define ecs_warn_(file, line, ...) ecs_log_(-2, file, line, __VA_ARGS__)
#define ecs_warn(...) ecs_warn_(__FILE__, __LINE__, __VA_ARGS__)
#define ecs_err_(file, line, ...) ecs_log_(-3, file, line, __VA_ARGS__)
#define ecs_err(...) ecs_err_(__FILE__, __LINE__, __VA_ARGS__)
#define ecs_fatal_(file, line, ...) ecs_log_(-4, file, line, __VA_ARGS__)
#define ecs_fatal(...) ecs_fatal_(__FILE__, __LINE__, __VA_ARGS__)
#ifndef FLECS_NO_DEPRECATED_WARNINGS
#define ecs_deprecated(...)\
ecs_deprecated_(__FILE__, __LINE__, __VA_ARGS__)
#else
#define ecs_deprecated(...)
#endif
#if !(defined(FLECS_LOG_0) || defined(FLECS_LOG_1) || defined(FLECS_LOG_2) || defined(FLECS_LOG_3))
#if !defined(FLECS_NDEBUG)
#define FLECS_LOG_3
#else
#define FLECS_LOG_0
#endif #endif
#if defined(FLECS_LOG_3)
#define ecs_dbg_1(...) ecs_log(1, __VA_ARGS__);
#define ecs_dbg_2(...) ecs_log(2, __VA_ARGS__);
#define ecs_dbg_3(...) ecs_log(3, __VA_ARGS__);
#define ecs_log_push_1() ecs_log_push_(1);
#define ecs_log_push_2() ecs_log_push_(2);
#define ecs_log_push_3() ecs_log_push_(3);
#define ecs_log_pop_1() ecs_log_pop_(1);
#define ecs_log_pop_2() ecs_log_pop_(2);
#define ecs_log_pop_3() ecs_log_pop_(3);
#define ecs_should_log_1() ecs_should_log(1)
#define ecs_should_log_2() ecs_should_log(2)
#define ecs_should_log_3() ecs_should_log(3)
#define FLECS_LOG_2
#define FLECS_LOG_1
#define FLECS_LOG_0
#elif defined(FLECS_LOG_2)
#define ecs_dbg_1(...) ecs_log(1, __VA_ARGS__);
#define ecs_dbg_2(...) ecs_log(2, __VA_ARGS__);
#define ecs_dbg_3(...)
#define ecs_log_push_1() ecs_log_push_(1);
#define ecs_log_push_2() ecs_log_push_(2);
#define ecs_log_push_3()
#define ecs_log_pop_1() ecs_log_pop_(1);
#define ecs_log_pop_2() ecs_log_pop_(2);
#define ecs_log_pop_3()
#define ecs_should_log_1() ecs_should_log(1)
#define ecs_should_log_2() ecs_should_log(2)
#define ecs_should_log_3() false
#define FLECS_LOG_1
#define FLECS_LOG_0
#elif defined(FLECS_LOG_1)
#define ecs_dbg_1(...) ecs_log(1, __VA_ARGS__);
#define ecs_dbg_2(...)
#define ecs_dbg_3(...)
#define ecs_log_push_1() ecs_log_push_(1);
#define ecs_log_push_2()
#define ecs_log_push_3()
#define ecs_log_pop_1() ecs_log_pop_(1);
#define ecs_log_pop_2()
#define ecs_log_pop_3()
#define ecs_should_log_1() ecs_should_log(1)
#define ecs_should_log_2() false
#define ecs_should_log_3() false
#define FLECS_LOG_0
#elif defined(FLECS_LOG_0)
#define ecs_dbg_1(...)
#define ecs_dbg_2(...)
#define ecs_dbg_3(...)
#define ecs_log_push_1()
#define ecs_log_push_2()
#define ecs_log_push_3()
#define ecs_log_pop_1()
#define ecs_log_pop_2()
#define ecs_log_pop_3()
#define ecs_should_log_1() false
#define ecs_should_log_2() false
#define ecs_should_log_3() false
#else
#undef ecs_trace
#define ecs_trace(...)
#define ecs_dbg_1(...)
#define ecs_dbg_2(...)
#define ecs_dbg_3(...)
#define ecs_log_push_1()
#define ecs_log_push_2()
#define ecs_log_push_3()
#define ecs_log_pop_1()
#define ecs_log_pop_2()
#define ecs_log_pop_3()
#endif
#define ecs_dbg ecs_dbg_1
#define ecs_log_push() ecs_log_push_(0)
#define ecs_log_pop() ecs_log_pop_(0)
#define ecs_abort(error_code, ...)\
ecs_abort_(error_code, __FILE__, __LINE__, __VA_ARGS__);\
ecs_os_abort(); abort();
#if defined(FLECS_NDEBUG) && !defined(FLECS_KEEP_ASSERT)
#define ecs_assert(condition, error_code, ...)
#else
#define ecs_assert(condition, error_code, ...)\
if (!ecs_assert_(condition, error_code, #condition, __FILE__, __LINE__, __VA_ARGS__)) {\
ecs_os_abort();\
}\
assert(condition)
#endif
#define ecs_assert_var(var, error_code, ...)\
ecs_assert(var, error_code, __VA_ARGS__);\
(void)var
#ifndef FLECS_NDEBUG
#define ecs_dbg_assert(condition, error_code, ...) ecs_assert(condition, error_code, __VA_ARGS__)
#else
#define ecs_dbg_assert(condition, error_code, ...)
#endif
#ifdef FLECS_SANITIZE
#define ecs_san_assert(condition, error_code, ...) ecs_assert(condition, error_code, __VA_ARGS__)
#else
#define ecs_san_assert(condition, error_code, ...)
#endif
#define ecs_dummy_check\
if ((false)) {\
goto error;\
}
#if defined(FLECS_NDEBUG) && !defined(FLECS_KEEP_ASSERT)
#define ecs_check(condition, error_code, ...) ecs_dummy_check
#else
#ifdef FLECS_SOFT_ASSERT
#define ecs_check(condition, error_code, ...)\
if (!ecs_assert_(condition, error_code, #condition, __FILE__, __LINE__, __VA_ARGS__)) {\
goto error;\
}
#else
#define ecs_check(condition, error_code, ...)\
ecs_assert(condition, error_code, __VA_ARGS__);\
ecs_dummy_check
#endif
#endif
#if defined(FLECS_NDEBUG) && !defined(FLECS_KEEP_ASSERT)
#define ecs_throw(error_code, ...) ecs_dummy_check
#else
#ifdef FLECS_SOFT_ASSERT
#define ecs_throw(error_code, ...)\
ecs_abort_(error_code, __FILE__, __LINE__, __VA_ARGS__);\
goto error;
#else
#define ecs_throw(error_code, ...)\
ecs_abort(error_code, __VA_ARGS__);\
ecs_dummy_check
#endif
#endif
#define ecs_parser_error(name, expr, column, ...)\
ecs_parser_error_(name, expr, column, __VA_ARGS__)
#define ecs_parser_errorv(name, expr, column, fmt, args)\
ecs_parser_errorv_(name, expr, column, fmt, args)
#endif
FLECS_API
int ecs_log_set_level(
int level);
FLECS_API
int ecs_log_get_level(void);
FLECS_API
bool ecs_log_enable_colors(
bool enabled);
FLECS_API
bool ecs_log_enable_timestamp(
bool enabled);
FLECS_API
bool ecs_log_enable_timedelta(
bool enabled);
FLECS_API
int ecs_log_last_error(void);
#define ECS_INVALID_OPERATION (1)
#define ECS_INVALID_PARAMETER (2)
#define ECS_CONSTRAINT_VIOLATED (3)
#define ECS_OUT_OF_MEMORY (4)
#define ECS_OUT_OF_RANGE (5)
#define ECS_UNSUPPORTED (6)
#define ECS_INTERNAL_ERROR (7)
#define ECS_ALREADY_DEFINED (8)
#define ECS_MISSING_OS_API (9)
#define ECS_OPERATION_FAILED (10)
#define ECS_INVALID_CONVERSION (11)
#define ECS_ID_IN_USE (12)
#define ECS_CYCLE_DETECTED (13)
#define ECS_LEAK_DETECTED (14)
#define ECS_DOUBLE_FREE (15)
#define ECS_INCONSISTENT_NAME (20)
#define ECS_NAME_IN_USE (21)
#define ECS_NOT_A_COMPONENT (22)
#define ECS_INVALID_COMPONENT_SIZE (23)
#define ECS_INVALID_COMPONENT_ALIGNMENT (24)
#define ECS_COMPONENT_NOT_REGISTERED (25)
#define ECS_INCONSISTENT_COMPONENT_ID (26)
#define ECS_INCONSISTENT_COMPONENT_ACTION (27)
#define ECS_MODULE_UNDEFINED (28)
#define ECS_MISSING_SYMBOL (29)
#define ECS_ALREADY_IN_USE (30)
#define ECS_ACCESS_VIOLATION (40)
#define ECS_COLUMN_INDEX_OUT_OF_RANGE (41)
#define ECS_COLUMN_IS_NOT_SHARED (42)
#define ECS_COLUMN_IS_SHARED (43)
#define ECS_COLUMN_TYPE_MISMATCH (45)
#define ECS_INVALID_WHILE_READONLY (70)
#define ECS_LOCKED_STORAGE (71)
#define ECS_INVALID_FROM_WORKER (72)
#define ECS_BLACK "\033[1;30m"
#define ECS_RED "\033[0;31m"
#define ECS_GREEN "\033[0;32m"
#define ECS_YELLOW "\033[0;33m"
#define ECS_BLUE "\033[0;34m"
#define ECS_MAGENTA "\033[0;35m"
#define ECS_CYAN "\033[0;36m"
#define ECS_WHITE "\033[1;37m"
#define ECS_GREY "\033[0;37m"
#define ECS_NORMAL "\033[0;49m"
#define ECS_BOLD "\033[1;49m"
#ifdef __cplusplus
}
#endif
#endif
#ifdef FLECS_MONITOR
#ifndef FLECS_STATS
#define FLECS_STATS
#endif
#ifndef FLECS_SYSTEM
#define FLECS_SYSTEM
#endif
#ifndef FLECS_TIMER
#define FLECS_TIMER
#endif
#endif
#ifdef FLECS_REST
#define FLECS_HTTP
#endif
#ifdef FLECS_PLECS
#define FLECS_EXPR
#endif
#ifdef FLECS_APP
#ifdef FLECS_NO_APP
#error "FLECS_NO_APP failed: APP is required by other addons"
#endif
#ifdef FLECS_APP
#ifndef FLECS_PIPELINE
#define FLECS_PIPELINE
#endif
#ifndef FLECS_APP_H
#define FLECS_APP_H
#ifdef __cplusplus
extern "C" {
#endif
typedef int(*ecs_app_init_action_t)(
ecs_world_t *world);
typedef struct ecs_app_desc_t {
ecs_ftime_t target_fps;
ecs_ftime_t delta_time;
int32_t threads;
int32_t frames;
bool enable_rest;
bool enable_monitor;
uint16_t port;
ecs_app_init_action_t init;
void *ctx;
} ecs_app_desc_t;
typedef int(*ecs_app_run_action_t)(
ecs_world_t *world,
ecs_app_desc_t *desc);
typedef int(*ecs_app_frame_action_t)(
ecs_world_t *world,
const ecs_app_desc_t *desc);
FLECS_API
int ecs_app_run(
ecs_world_t *world,
ecs_app_desc_t *desc);
FLECS_API
int ecs_app_run_frame(
ecs_world_t *world,
const ecs_app_desc_t *desc);
FLECS_API
int ecs_app_set_run_action(
ecs_app_run_action_t callback);
FLECS_API
int ecs_app_set_frame_action(
ecs_app_frame_action_t callback);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_HTTP
#ifdef FLECS_NO_HTTP
#error "FLECS_NO_HTTP failed: HTTP is required by other addons"
#endif
#ifdef FLECS_HTTP
#if !defined(FLECS_OS_API_IMPL) && !defined(FLECS_NO_OS_API_IMPL)
#define FLECS_OS_API_IMPL
#endif
#ifndef FLECS_HTTP_H
#define FLECS_HTTP_H
#define ECS_HTTP_HEADER_COUNT_MAX (32)
#define ECS_HTTP_QUERY_PARAM_COUNT_MAX (32)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ecs_http_server_t ecs_http_server_t;
typedef struct {
uint64_t id;
ecs_http_server_t *server;
char host[128];
char port[16];
} ecs_http_connection_t;
typedef struct {
const char *key;
const char *value;
} ecs_http_key_value_t;
typedef enum {
EcsHttpGet,
EcsHttpPost,
EcsHttpPut,
EcsHttpDelete,
EcsHttpOptions,
EcsHttpMethodUnsupported
} ecs_http_method_t;
typedef struct {
uint64_t id;
ecs_http_method_t method;
char *path;
char *body;
ecs_http_key_value_t headers[ECS_HTTP_HEADER_COUNT_MAX];
ecs_http_key_value_t params[ECS_HTTP_HEADER_COUNT_MAX];
int32_t header_count;
int32_t param_count;
ecs_http_connection_t *conn;
} ecs_http_request_t;
typedef struct {
int code;
ecs_strbuf_t body;
const char* status;
const char* content_type;
ecs_strbuf_t headers;
} ecs_http_reply_t;
#define ECS_HTTP_REPLY_INIT \
(ecs_http_reply_t){200, ECS_STRBUF_INIT, "OK", "application/json", ECS_STRBUF_INIT}
extern int64_t ecs_http_request_received_count;
extern int64_t ecs_http_request_invalid_count;
extern int64_t ecs_http_request_handled_ok_count;
extern int64_t ecs_http_request_handled_error_count;
extern int64_t ecs_http_request_not_handled_count;
extern int64_t ecs_http_request_preflight_count;
extern int64_t ecs_http_send_ok_count;
extern int64_t ecs_http_send_error_count;
extern int64_t ecs_http_busy_count;
typedef bool (*ecs_http_reply_action_t)(
const ecs_http_request_t* request,
ecs_http_reply_t *reply,
void *ctx);
typedef struct {
ecs_http_reply_action_t callback;
void *ctx;
uint16_t port;
const char *ipaddr;
int32_t send_queue_wait_ms;
} ecs_http_server_desc_t;
FLECS_API
ecs_http_server_t* ecs_http_server_init(
const ecs_http_server_desc_t *desc);
FLECS_API
void ecs_http_server_fini(
ecs_http_server_t* server);
FLECS_API
int ecs_http_server_start(
ecs_http_server_t* server);
FLECS_API
void ecs_http_server_dequeue(
ecs_http_server_t* server,
ecs_ftime_t delta_time);
FLECS_API
void ecs_http_server_stop(
ecs_http_server_t* server);
FLECS_API
int ecs_http_server_http_request(
ecs_http_server_t* srv,
const char *req,
ecs_size_t len,
ecs_http_reply_t *reply_out);
FLECS_API
int ecs_http_server_request(
ecs_http_server_t* srv,
const char *method,
const char *req,
ecs_http_reply_t *reply_out);
FLECS_API
void* ecs_http_server_ctx(
ecs_http_server_t* srv);
FLECS_API
const char* ecs_http_get_header(
const ecs_http_request_t* req,
const char* name);
FLECS_API
const char* ecs_http_get_param(
const ecs_http_request_t* req,
const char* name);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_REST
#ifdef FLECS_NO_REST
#error "FLECS_NO_REST failed: REST is required by other addons"
#endif
#ifdef FLECS_REST
#ifndef FLECS_HTTP
#define FLECS_HTTP
#endif
#ifndef FLECS_JSON
#define FLECS_JSON
#endif
#ifndef FLECS_RULES
#define FLECS_RULES
#endif
#ifndef FLECS_PIPELINE
#define FLECS_PIPELINE
#endif
#ifndef FLECS_REST_H
#define FLECS_REST_H
#ifdef __cplusplus
extern "C" {
#endif
#define ECS_REST_DEFAULT_PORT (27750)
FLECS_API extern const ecs_entity_t ecs_id(EcsRest);
typedef struct {
uint16_t port;
char *ipaddr;
void *impl;
} EcsRest;
extern int64_t ecs_rest_request_count;
extern int64_t ecs_rest_entity_count;
extern int64_t ecs_rest_entity_error_count;
extern int64_t ecs_rest_query_count;
extern int64_t ecs_rest_query_error_count;
extern int64_t ecs_rest_query_name_count;
extern int64_t ecs_rest_query_name_error_count;
extern int64_t ecs_rest_query_name_from_cache_count;
extern int64_t ecs_rest_enable_count;
extern int64_t ecs_rest_enable_error_count;
extern int64_t ecs_rest_delete_count;
extern int64_t ecs_rest_delete_error_count;
extern int64_t ecs_rest_world_stats_count;
extern int64_t ecs_rest_pipeline_stats_count;
extern int64_t ecs_rest_stats_error_count;
FLECS_API
ecs_http_server_t* ecs_rest_server_init(
ecs_world_t *world,
const ecs_http_server_desc_t *desc);
FLECS_API
void ecs_rest_server_fini(
ecs_http_server_t *srv);
FLECS_API
void FlecsRestImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_TIMER
#ifdef FLECS_NO_TIMER
#error "FLECS_NO_TIMER failed: TIMER is required by other addons"
#endif
#ifdef FLECS_TIMER
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifndef FLECS_PIPELINE
#define FLECS_PIPELINE
#endif
#ifndef FLECS_TIMER_H
#define FLECS_TIMER_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct EcsTimer {
ecs_ftime_t timeout;
ecs_ftime_t time;
ecs_ftime_t overshoot;
int32_t fired_count;
bool active;
bool single_shot;
} EcsTimer;
typedef struct EcsRateFilter {
ecs_entity_t src;
int32_t rate;
int32_t tick_count;
ecs_ftime_t time_elapsed;
} EcsRateFilter;
FLECS_API
ecs_entity_t ecs_set_timeout(
ecs_world_t *world,
ecs_entity_t tick_source,
ecs_ftime_t timeout);
FLECS_API
ecs_ftime_t ecs_get_timeout(
const ecs_world_t *world,
ecs_entity_t tick_source);
FLECS_API
ecs_entity_t ecs_set_interval(
ecs_world_t *world,
ecs_entity_t tick_source,
ecs_ftime_t interval);
FLECS_API
ecs_ftime_t ecs_get_interval(
const ecs_world_t *world,
ecs_entity_t tick_source);
FLECS_API
void ecs_start_timer(
ecs_world_t *world,
ecs_entity_t tick_source);
FLECS_API
void ecs_stop_timer(
ecs_world_t *world,
ecs_entity_t tick_source);
FLECS_API
void ecs_reset_timer(
ecs_world_t *world,
ecs_entity_t tick_source);
FLECS_API
void ecs_randomize_timers(
ecs_world_t *world);
FLECS_API
ecs_entity_t ecs_set_rate(
ecs_world_t *world,
ecs_entity_t tick_source,
int32_t rate,
ecs_entity_t source);
FLECS_API
void ecs_set_tick_source(
ecs_world_t *world,
ecs_entity_t system,
ecs_entity_t tick_source);
FLECS_API
void FlecsTimerImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_PIPELINE
#ifdef FLECS_NO_PIPELINE
#error "FLECS_NO_PIPELINE failed: PIPELINE is required by other addons"
#endif
#ifdef FLECS_PIPELINE
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifndef FLECS_SYSTEM
#define FLECS_SYSTEM
#endif
#if !defined(FLECS_OS_API_IMPL) && !defined(FLECS_NO_OS_API_IMPL)
#define FLECS_OS_API_IMPL
#endif
#ifndef FLECS_PIPELINE_H
#define FLECS_PIPELINE_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FLECS_LEGACY
#define ECS_PIPELINE_DEFINE(world, id_, ...) \
{ \
ecs_pipeline_desc_t desc = {0}; \
ecs_entity_desc_t edesc = {0}; \
edesc.id = id_;\
edesc.name = #id_;\
desc.entity = ecs_entity_init(world, &edesc);\
desc.query.filter.expr = #__VA_ARGS__; \
id_ = ecs_pipeline_init(world, &desc); \
ecs_id(id_) = id_;\
} \
ecs_assert(id_ != 0, ECS_INVALID_PARAMETER, NULL);
#define ECS_PIPELINE(world, id, ...) \
ecs_entity_t id = 0, ecs_id(id) = 0; ECS_PIPELINE_DEFINE(world, id, __VA_ARGS__);\
(void)id;\
(void)ecs_id(id);
#define ecs_pipeline(world, ...)\
ecs_pipeline_init(world, &(ecs_pipeline_desc_t) __VA_ARGS__ )
#endif
typedef struct ecs_pipeline_desc_t {
ecs_entity_t entity;
ecs_query_desc_t query;
} ecs_pipeline_desc_t;
FLECS_API
ecs_entity_t ecs_pipeline_init(
ecs_world_t *world,
const ecs_pipeline_desc_t *desc);
FLECS_API
void ecs_set_pipeline(
ecs_world_t *world,
ecs_entity_t pipeline);
FLECS_API
ecs_entity_t ecs_get_pipeline(
const ecs_world_t *world);
FLECS_API
bool ecs_progress(
ecs_world_t *world,
ecs_ftime_t delta_time);
FLECS_API
void ecs_set_time_scale(
ecs_world_t *world,
ecs_ftime_t scale);
FLECS_API
void ecs_reset_clock(
ecs_world_t *world);
FLECS_API
void ecs_run_pipeline(
ecs_world_t *world,
ecs_entity_t pipeline,
ecs_ftime_t delta_time);
FLECS_API
void ecs_set_threads(
ecs_world_t *world,
int32_t threads);
FLECS_API
void ecs_set_task_threads(
ecs_world_t *world,
int32_t task_threads);
FLECS_API
bool ecs_using_task_threads(
ecs_world_t *world);
FLECS_API
void FlecsPipelineImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_SYSTEM
#ifdef FLECS_NO_SYSTEM
#error "FLECS_NO_SYSTEM failed: SYSTEM is required by other addons"
#endif
#ifdef FLECS_SYSTEM
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifndef FLECS_SYSTEM_H
#define FLECS_SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct EcsTickSource {
bool tick;
ecs_ftime_t time_elapsed;
} EcsTickSource;
typedef struct ecs_system_desc_t {
int32_t _canary;
ecs_entity_t entity;
ecs_query_desc_t query;
ecs_run_action_t run;
ecs_iter_action_t callback;
void *ctx;
void *binding_ctx;
ecs_ctx_free_t ctx_free;
ecs_ctx_free_t binding_ctx_free;
ecs_ftime_t interval;
int32_t rate;
ecs_entity_t tick_source;
bool multi_threaded;
bool no_readonly;
} ecs_system_desc_t;
FLECS_API
ecs_entity_t ecs_system_init(
ecs_world_t *world,
const ecs_system_desc_t *desc);
#ifndef FLECS_LEGACY
#define ECS_SYSTEM_DECLARE(id) ecs_entity_t ecs_id(id)
#define ECS_SYSTEM_DEFINE(world, id_, phase, ...) \
{ \
ecs_system_desc_t desc = {0}; \
ecs_entity_desc_t edesc = {0}; \
edesc.id = ecs_id(id_);\
edesc.name = #id_;\
edesc.add[0] = ((phase) ? ecs_pair(EcsDependsOn, (phase)) : 0); \
edesc.add[1] = (phase); \
desc.entity = ecs_entity_init(world, &edesc);\
desc.query.filter.expr = #__VA_ARGS__; \
desc.callback = id_; \
ecs_id(id_) = ecs_system_init(world, &desc); \
} \
ecs_assert(ecs_id(id_) != 0, ECS_INVALID_PARAMETER, NULL)
#define ECS_SYSTEM(world, id, phase, ...) \
ecs_entity_t ecs_id(id) = 0; ECS_SYSTEM_DEFINE(world, id, phase, __VA_ARGS__);\
ecs_entity_t id = ecs_id(id);\
(void)ecs_id(id);\
(void)id
#define ecs_system(world, ...)\
ecs_system_init(world, &(ecs_system_desc_t) __VA_ARGS__ )
#endif
FLECS_API
ecs_entity_t ecs_run(
ecs_world_t *world,
ecs_entity_t system,
ecs_ftime_t delta_time,
void *param);
FLECS_API
ecs_entity_t ecs_run_worker(
ecs_world_t *world,
ecs_entity_t system,
int32_t stage_current,
int32_t stage_count,
ecs_ftime_t delta_time,
void *param);
FLECS_API
ecs_entity_t ecs_run_w_filter(
ecs_world_t *world,
ecs_entity_t system,
ecs_ftime_t delta_time,
int32_t offset,
int32_t limit,
void *param);
FLECS_API
ecs_query_t* ecs_system_get_query(
const ecs_world_t *world,
ecs_entity_t system);
FLECS_API
void* ecs_system_get_ctx(
const ecs_world_t *world,
ecs_entity_t system);
FLECS_API
void* ecs_system_get_binding_ctx(
const ecs_world_t *world,
ecs_entity_t system);
FLECS_API
void FlecsSystemImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_STATS
#ifdef FLECS_NO_STATS
#error "FLECS_NO_STATS failed: STATS is required by other addons"
#endif
#ifdef FLECS_STATS
#ifndef FLECS_STATS_H
#define FLECS_STATS_H
#ifdef __cplusplus
extern "C" {
#endif
#define ECS_STAT_WINDOW (60)
typedef struct ecs_gauge_t {
ecs_float_t avg[ECS_STAT_WINDOW];
ecs_float_t min[ECS_STAT_WINDOW];
ecs_float_t max[ECS_STAT_WINDOW];
} ecs_gauge_t;
typedef struct ecs_counter_t {
ecs_gauge_t rate;
double value[ECS_STAT_WINDOW];
} ecs_counter_t;
typedef union ecs_metric_t {
ecs_gauge_t gauge;
ecs_counter_t counter;
} ecs_metric_t;
typedef struct ecs_world_stats_t {
int64_t first_;
struct {
ecs_metric_t count;
ecs_metric_t not_alive_count;
} entities;
struct {
ecs_metric_t count;
ecs_metric_t tag_count;
ecs_metric_t component_count;
ecs_metric_t pair_count;
ecs_metric_t wildcard_count;
ecs_metric_t type_count;
ecs_metric_t create_count;
ecs_metric_t delete_count;
} ids;
struct {
ecs_metric_t count;
ecs_metric_t empty_count;
ecs_metric_t tag_only_count;
ecs_metric_t trivial_only_count;
ecs_metric_t record_count;
ecs_metric_t storage_count;
ecs_metric_t create_count;
ecs_metric_t delete_count;
} tables;
struct {
ecs_metric_t query_count;
ecs_metric_t observer_count;
ecs_metric_t system_count;
} queries;
struct {
ecs_metric_t add_count;
ecs_metric_t remove_count;
ecs_metric_t delete_count;
ecs_metric_t clear_count;
ecs_metric_t set_count;
ecs_metric_t get_mut_count;
ecs_metric_t modified_count;
ecs_metric_t other_count;
ecs_metric_t discard_count;
ecs_metric_t batched_entity_count;
ecs_metric_t batched_count;
} commands;
struct {
ecs_metric_t frame_count;
ecs_metric_t merge_count;
ecs_metric_t rematch_count;
ecs_metric_t pipeline_build_count;
ecs_metric_t systems_ran;
ecs_metric_t observers_ran;
ecs_metric_t event_emit_count;
} frame;
struct {
ecs_metric_t world_time_raw;
ecs_metric_t world_time;
ecs_metric_t frame_time;
ecs_metric_t system_time;
ecs_metric_t emit_time;
ecs_metric_t merge_time;
ecs_metric_t rematch_time;
ecs_metric_t fps;
ecs_metric_t delta_time;
} performance;
struct {
ecs_metric_t alloc_count;
ecs_metric_t realloc_count;
ecs_metric_t free_count;
ecs_metric_t outstanding_alloc_count;
ecs_metric_t block_alloc_count;
ecs_metric_t block_free_count;
ecs_metric_t block_outstanding_alloc_count;
ecs_metric_t stack_alloc_count;
ecs_metric_t stack_free_count;
ecs_metric_t stack_outstanding_alloc_count;
} memory;
struct {
ecs_metric_t request_count;
ecs_metric_t entity_count;
ecs_metric_t entity_error_count;
ecs_metric_t query_count;
ecs_metric_t query_error_count;
ecs_metric_t query_name_count;
ecs_metric_t query_name_error_count;
ecs_metric_t query_name_from_cache_count;
ecs_metric_t enable_count;
ecs_metric_t enable_error_count;
ecs_metric_t world_stats_count;
ecs_metric_t pipeline_stats_count;
ecs_metric_t stats_error_count;
} rest;
struct {
ecs_metric_t request_received_count;
ecs_metric_t request_invalid_count;
ecs_metric_t request_handled_ok_count;
ecs_metric_t request_handled_error_count;
ecs_metric_t request_not_handled_count;
ecs_metric_t request_preflight_count;
ecs_metric_t send_ok_count;
ecs_metric_t send_error_count;
ecs_metric_t busy_count;
} http;
int64_t last_;
int32_t t;
} ecs_world_stats_t;
typedef struct ecs_query_stats_t {
int64_t first_;
ecs_metric_t matched_table_count;
ecs_metric_t matched_empty_table_count;
ecs_metric_t matched_entity_count;
int64_t last_;
int32_t t;
} ecs_query_stats_t;
typedef struct ecs_system_stats_t {
int64_t first_;
ecs_metric_t time_spent;
ecs_metric_t invoke_count;
int64_t last_;
bool task;
ecs_query_stats_t query;
} ecs_system_stats_t;
typedef struct ecs_sync_stats_t {
int64_t first_;
ecs_metric_t time_spent;
ecs_metric_t commands_enqueued;
int64_t last_;
int32_t system_count;
bool multi_threaded;
bool no_readonly;
} ecs_sync_stats_t;
typedef struct ecs_pipeline_stats_t {
int8_t canary_;
ecs_vec_t systems;
ecs_vec_t sync_points;
ecs_map_t system_stats;
int32_t t;
int32_t system_count;
int32_t active_system_count;
int32_t rebuild_count;
} ecs_pipeline_stats_t;
FLECS_API
void ecs_world_stats_get(
const ecs_world_t *world,
ecs_world_stats_t *stats);
FLECS_API
void ecs_world_stats_reduce(
ecs_world_stats_t *dst,
const ecs_world_stats_t *src);
FLECS_API
void ecs_world_stats_reduce_last(
ecs_world_stats_t *stats,
const ecs_world_stats_t *old,
int32_t count);
FLECS_API
void ecs_world_stats_repeat_last(
ecs_world_stats_t *stats);
FLECS_API
void ecs_world_stats_copy_last(
ecs_world_stats_t *dst,
const ecs_world_stats_t *src);
FLECS_API
void ecs_world_stats_log(
const ecs_world_t *world,
const ecs_world_stats_t *stats);
FLECS_API
void ecs_query_stats_get(
const ecs_world_t *world,
const ecs_query_t *query,
ecs_query_stats_t *stats);
FLECS_API
void ecs_query_stats_reduce(
ecs_query_stats_t *dst,
const ecs_query_stats_t *src);
FLECS_API
void ecs_query_stats_reduce_last(
ecs_query_stats_t *stats,
const ecs_query_stats_t *old,
int32_t count);
FLECS_API
void ecs_query_stats_repeat_last(
ecs_query_stats_t *stats);
FLECS_API
void ecs_query_stats_copy_last(
ecs_query_stats_t *dst,
const ecs_query_stats_t *src);
#ifdef FLECS_SYSTEM
FLECS_API
bool ecs_system_stats_get(
const ecs_world_t *world,
ecs_entity_t system,
ecs_system_stats_t *stats);
FLECS_API
void ecs_system_stats_reduce(
ecs_system_stats_t *dst,
const ecs_system_stats_t *src);
FLECS_API
void ecs_system_stats_reduce_last(
ecs_system_stats_t *stats,
const ecs_system_stats_t *old,
int32_t count);
FLECS_API
void ecs_system_stats_repeat_last(
ecs_system_stats_t *stats);
FLECS_API
void ecs_system_stats_copy_last(
ecs_system_stats_t *dst,
const ecs_system_stats_t *src);
#endif
#ifdef FLECS_PIPELINE
FLECS_API
bool ecs_pipeline_stats_get(
ecs_world_t *world,
ecs_entity_t pipeline,
ecs_pipeline_stats_t *stats);
FLECS_API
void ecs_pipeline_stats_fini(
ecs_pipeline_stats_t *stats);
FLECS_API
void ecs_pipeline_stats_reduce(
ecs_pipeline_stats_t *dst,
const ecs_pipeline_stats_t *src);
FLECS_API
void ecs_pipeline_stats_reduce_last(
ecs_pipeline_stats_t *stats,
const ecs_pipeline_stats_t *old,
int32_t count);
FLECS_API
void ecs_pipeline_stats_repeat_last(
ecs_pipeline_stats_t *stats);
FLECS_API
void ecs_pipeline_stats_copy_last(
ecs_pipeline_stats_t *dst,
const ecs_pipeline_stats_t *src);
#endif
FLECS_API
void ecs_metric_reduce(
ecs_metric_t *dst,
const ecs_metric_t *src,
int32_t t_dst,
int32_t t_src);
FLECS_API
void ecs_metric_reduce_last(
ecs_metric_t *m,
int32_t t,
int32_t count);
FLECS_API
void ecs_metric_copy(
ecs_metric_t *m,
int32_t dst,
int32_t src);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_METRICS
#ifdef FLECS_NO_METRICS
#error "FLECS_NO_METRICS failed: METRICS is required by other addons"
#endif
#ifdef FLECS_METRICS
#ifndef FLECS_METRICS_H
#define FLECS_METRICS_H
#ifndef FLECS_META
#define FLECS_META
#endif
#ifndef FLECS_UNITS
#define FLECS_UNITS
#endif
#ifndef FLECS_PIPELINE
#define FLECS_PIPELINE
#endif
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API extern ECS_COMPONENT_DECLARE(FlecsMetrics);
FLECS_API extern ECS_TAG_DECLARE(EcsMetric);
FLECS_API extern ECS_TAG_DECLARE(EcsCounter);
FLECS_API extern ECS_TAG_DECLARE(EcsCounterIncrement);
FLECS_API extern ECS_TAG_DECLARE(EcsCounterId);
FLECS_API extern ECS_TAG_DECLARE(EcsGauge);
FLECS_API extern ECS_TAG_DECLARE(EcsMetricInstance);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsMetricValue);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsMetricSource);
typedef struct EcsMetricValue {
double value;
} EcsMetricValue;
typedef struct EcsMetricSource {
ecs_entity_t entity;
} EcsMetricSource;
typedef struct ecs_metric_desc_t {
int32_t _canary;
ecs_entity_t entity;
ecs_entity_t member;
const char *dotmember;
ecs_id_t id;
bool targets;
ecs_entity_t kind;
const char *brief;
} ecs_metric_desc_t;
FLECS_API
ecs_entity_t ecs_metric_init(
ecs_world_t *world,
const ecs_metric_desc_t *desc);
#define ecs_metric(world, ...)\
ecs_metric_init(world, &(ecs_metric_desc_t) __VA_ARGS__ )
FLECS_API
void FlecsMetricsImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_ALERTS
#ifdef FLECS_NO_ALERTS
#error "FLECS_NO_ALERTS failed: ALERTS is required by other addons"
#endif
#ifdef FLECS_ALERTS
#ifndef FLECS_ALERTS_H
#define FLECS_ALERTS_H
#ifndef FLECS_RULES
#define FLECS_RULES
#endif
#ifndef FLECS_PIPELINE
#define FLECS_PIPELINE
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define ECS_ALERT_MAX_SEVERITY_FILTERS (4)
FLECS_API extern ECS_COMPONENT_DECLARE(FlecsAlerts);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsAlert);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsAlertInstance);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsAlertsActive);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsAlertTimeout);
FLECS_API extern ECS_TAG_DECLARE(EcsAlertInfo);
FLECS_API extern ECS_TAG_DECLARE(EcsAlertWarning);
FLECS_API extern ECS_TAG_DECLARE(EcsAlertError);
FLECS_API extern ECS_TAG_DECLARE(EcsAlertCritical);
typedef struct EcsAlertInstance {
char *message;
} EcsAlertInstance;
typedef struct EcsAlertsActive {
int32_t info_count;
int32_t warning_count;
int32_t error_count;
ecs_map_t alerts;
} EcsAlertsActive;
typedef struct ecs_alert_severity_filter_t {
ecs_entity_t severity;
ecs_id_t with;
const char *var;
int32_t _var_index;
} ecs_alert_severity_filter_t;
typedef struct ecs_alert_desc_t {
int32_t _canary;
ecs_entity_t entity;
ecs_filter_desc_t filter;
const char *message;
const char *doc_name;
const char *brief;
ecs_entity_t severity;
ecs_alert_severity_filter_t severity_filters[ECS_ALERT_MAX_SEVERITY_FILTERS];
ecs_ftime_t retain_period;
ecs_entity_t member;
ecs_id_t id;
const char *var;
} ecs_alert_desc_t;
FLECS_API
ecs_entity_t ecs_alert_init(
ecs_world_t *world,
const ecs_alert_desc_t *desc);
#define ecs_alert(world, ...)\
ecs_alert_init(world, &(ecs_alert_desc_t)__VA_ARGS__)
FLECS_API
int32_t ecs_get_alert_count(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t alert);
FLECS_API
ecs_entity_t ecs_get_alert(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t alert);
FLECS_API
void FlecsAlertsImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_MONITOR
#ifdef FLECS_NO_MONITOR
#error "FLECS_NO_MONITOR failed: MONITOR is required by other addons"
#endif
#ifdef FLECS_MONITOR
#ifndef FLECS_MONITOR_H
#define FLECS_MONITOR_H
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifndef FLECS_STATS
#define FLECS_STATS
#endif
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API extern ECS_COMPONENT_DECLARE(FlecsMonitor);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsWorldStats);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsWorldSummary);
FLECS_API extern ECS_COMPONENT_DECLARE(EcsPipelineStats);
FLECS_API extern ecs_entity_t EcsPeriod1s;
FLECS_API extern ecs_entity_t EcsPeriod1m;
FLECS_API extern ecs_entity_t EcsPeriod1h;
FLECS_API extern ecs_entity_t EcsPeriod1d;
FLECS_API extern ecs_entity_t EcsPeriod1w;
typedef struct {
ecs_ftime_t elapsed;
int32_t reduce_count;
} EcsStatsHeader;
typedef struct {
EcsStatsHeader hdr;
ecs_world_stats_t stats;
} EcsWorldStats;
typedef struct {
EcsStatsHeader hdr;
ecs_pipeline_stats_t stats;
} EcsPipelineStats;
typedef struct {
double target_fps;
double frame_time_total;
double system_time_total;
double merge_time_total;
double frame_time_last;
double system_time_last;
double merge_time_last;
} EcsWorldSummary;
FLECS_API
void FlecsMonitorImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_COREDOC
#ifdef FLECS_NO_COREDOC
#error "FLECS_NO_COREDOC failed: COREDOC is required by other addons"
#endif
#ifdef FLECS_COREDOC
#ifndef FLECS_DOC
#define FLECS_DOC
#endif
#ifndef FLECS_META
#define FLECS_META
#endif
#ifndef FLECS_COREDOC_H
#define FLECS_COREDOC_H
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API
void FlecsCoreDocImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_DOC
#ifdef FLECS_NO_DOC
#error "FLECS_NO_DOC failed: DOC is required by other addons"
#endif
#ifdef FLECS_DOC
#ifndef FLECS_DOC_H
#define FLECS_DOC_H
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API extern const ecs_entity_t ecs_id(EcsDocDescription);
FLECS_API extern const ecs_entity_t EcsDocBrief;
FLECS_API extern const ecs_entity_t EcsDocDetail;
FLECS_API extern const ecs_entity_t EcsDocLink;
FLECS_API extern const ecs_entity_t EcsDocColor;
typedef struct EcsDocDescription {
char *value;
} EcsDocDescription;
FLECS_API
void ecs_doc_set_name(
ecs_world_t *world,
ecs_entity_t entity,
const char *name);
FLECS_API
void ecs_doc_set_brief(
ecs_world_t *world,
ecs_entity_t entity,
const char *description);
FLECS_API
void ecs_doc_set_detail(
ecs_world_t *world,
ecs_entity_t entity,
const char *description);
FLECS_API
void ecs_doc_set_link(
ecs_world_t *world,
ecs_entity_t entity,
const char *link);
FLECS_API
void ecs_doc_set_color(
ecs_world_t *world,
ecs_entity_t entity,
const char *color);
FLECS_API
const char* ecs_doc_get_name(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
const char* ecs_doc_get_brief(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
const char* ecs_doc_get_detail(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
const char* ecs_doc_get_link(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
const char* ecs_doc_get_color(
const ecs_world_t *world,
ecs_entity_t entity);
FLECS_API
void FlecsDocImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_JSON
#ifdef FLECS_NO_JSON
#error "FLECS_NO_JSON failed: JSON is required by other addons"
#endif
#ifdef FLECS_JSON
#ifndef FLECS_EXPR
#define FLECS_EXPR
#endif
#ifndef FLECS_JSON_H
#define FLECS_JSON_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ecs_from_json_desc_t {
const char *name;
const char *expr;
ecs_entity_t (*lookup_action)(
const ecs_world_t*,
const char *value,
void *ctx);
void *lookup_ctx;
} ecs_from_json_desc_t;
FLECS_API
const char* ecs_ptr_from_json(
const ecs_world_t *world,
ecs_entity_t type,
void *ptr,
const char *json,
const ecs_from_json_desc_t *desc);
FLECS_API
const char* ecs_entity_from_json(
ecs_world_t *world,
ecs_entity_t entity,
const char *json,
const ecs_from_json_desc_t *desc);
FLECS_API
const char* ecs_world_from_json(
ecs_world_t *world,
const char *json,
const ecs_from_json_desc_t *desc);
FLECS_API
char* ecs_array_to_json(
const ecs_world_t *world,
ecs_entity_t type,
const void *data,
int32_t count);
FLECS_API
int ecs_array_to_json_buf(
const ecs_world_t *world,
ecs_entity_t type,
const void *data,
int32_t count,
ecs_strbuf_t *buf_out);
FLECS_API
char* ecs_ptr_to_json(
const ecs_world_t *world,
ecs_entity_t type,
const void *data);
FLECS_API
int ecs_ptr_to_json_buf(
const ecs_world_t *world,
ecs_entity_t type,
const void *data,
ecs_strbuf_t *buf_out);
FLECS_API
char* ecs_type_info_to_json(
const ecs_world_t *world,
ecs_entity_t type);
FLECS_API
int ecs_type_info_to_json_buf(
const ecs_world_t *world,
ecs_entity_t type,
ecs_strbuf_t *buf_out);
typedef struct ecs_entity_to_json_desc_t {
bool serialize_path;
bool serialize_label;
bool serialize_brief;
bool serialize_link;
bool serialize_color;
bool serialize_ids;
bool serialize_id_labels;
bool serialize_base;
bool serialize_private;
bool serialize_hidden;
bool serialize_values;
bool serialize_type_info;
bool serialize_alerts;
ecs_entity_t serialize_refs;
bool serialize_matches;
} ecs_entity_to_json_desc_t;
#define ECS_ENTITY_TO_JSON_INIT (ecs_entity_to_json_desc_t){true, false,\
false, false, false, true, false, true, false, false, false, false, false,\
false, false }
FLECS_API
char* ecs_entity_to_json(
const ecs_world_t *world,
ecs_entity_t entity,
const ecs_entity_to_json_desc_t *desc);
FLECS_API
int ecs_entity_to_json_buf(
const ecs_world_t *world,
ecs_entity_t entity,
ecs_strbuf_t *buf_out,
const ecs_entity_to_json_desc_t *desc);
typedef struct ecs_iter_to_json_desc_t {
bool serialize_term_ids;
bool serialize_term_labels;
bool serialize_ids;
bool serialize_id_labels;
bool serialize_sources;
bool serialize_variables;
bool serialize_is_set;
bool serialize_values;
bool serialize_private;
bool serialize_entities;
bool serialize_entity_labels;
bool serialize_entity_ids;
bool serialize_entity_names;
bool serialize_variable_labels;
bool serialize_variable_ids;
bool serialize_colors;
bool measure_eval_duration;
bool serialize_type_info;
bool serialize_table;
} ecs_iter_to_json_desc_t;
#define ECS_ITER_TO_JSON_INIT (ecs_iter_to_json_desc_t){\
.serialize_term_ids = true, \
.serialize_term_labels = false, \
.serialize_ids = true, \
.serialize_id_labels = false, \
.serialize_sources = true, \
.serialize_variables = true, \
.serialize_is_set = true, \
.serialize_values = true, \
.serialize_entities = true, \
.serialize_entity_labels = false, \
.serialize_entity_ids = false, \
.serialize_entity_names = false, \
.serialize_variable_labels = false, \
.serialize_variable_ids = false, \
.serialize_colors = false, \
.measure_eval_duration = false, \
.serialize_type_info = false, \
.serialize_table = false \
}
FLECS_API
char* ecs_iter_to_json(
const ecs_world_t *world,
ecs_iter_t *iter,
const ecs_iter_to_json_desc_t *desc);
FLECS_API
int ecs_iter_to_json_buf(
const ecs_world_t *world,
ecs_iter_t *iter,
ecs_strbuf_t *buf_out,
const ecs_iter_to_json_desc_t *desc);
typedef struct ecs_world_to_json_desc_t {
bool serialize_builtin;
bool serialize_modules;
} ecs_world_to_json_desc_t;
FLECS_API
char* ecs_world_to_json(
ecs_world_t *world,
const ecs_world_to_json_desc_t *desc);
FLECS_API
int ecs_world_to_json_buf(
ecs_world_t *world,
ecs_strbuf_t *buf_out,
const ecs_world_to_json_desc_t *desc);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#if defined(FLECS_EXPR) || defined(FLECS_META_C)
#ifndef FLECS_META
#define FLECS_META
#endif
#endif
#ifdef FLECS_UNITS
#ifdef FLECS_NO_UNITS
#error "FLECS_NO_UNITS failed: UNITS is required by other addons"
#endif
#ifdef FLECS_UNITS
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifndef FLECS_META
#define FLECS_META
#endif
#ifndef FLECS_UNITS_H
#define FLECS_UNITS_H
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API extern ECS_DECLARE(EcsUnitPrefixes);
FLECS_API extern ECS_DECLARE(EcsYocto);
FLECS_API extern ECS_DECLARE(EcsZepto);
FLECS_API extern ECS_DECLARE(EcsAtto);
FLECS_API extern ECS_DECLARE(EcsFemto);
FLECS_API extern ECS_DECLARE(EcsPico);
FLECS_API extern ECS_DECLARE(EcsNano);
FLECS_API extern ECS_DECLARE(EcsMicro);
FLECS_API extern ECS_DECLARE(EcsMilli);
FLECS_API extern ECS_DECLARE(EcsCenti);
FLECS_API extern ECS_DECLARE(EcsDeci);
FLECS_API extern ECS_DECLARE(EcsDeca);
FLECS_API extern ECS_DECLARE(EcsHecto);
FLECS_API extern ECS_DECLARE(EcsKilo);
FLECS_API extern ECS_DECLARE(EcsMega);
FLECS_API extern ECS_DECLARE(EcsGiga);
FLECS_API extern ECS_DECLARE(EcsTera);
FLECS_API extern ECS_DECLARE(EcsPeta);
FLECS_API extern ECS_DECLARE(EcsExa);
FLECS_API extern ECS_DECLARE(EcsZetta);
FLECS_API extern ECS_DECLARE(EcsYotta);
FLECS_API extern ECS_DECLARE(EcsKibi);
FLECS_API extern ECS_DECLARE(EcsMebi);
FLECS_API extern ECS_DECLARE(EcsGibi);
FLECS_API extern ECS_DECLARE(EcsTebi);
FLECS_API extern ECS_DECLARE(EcsPebi);
FLECS_API extern ECS_DECLARE(EcsExbi);
FLECS_API extern ECS_DECLARE(EcsZebi);
FLECS_API extern ECS_DECLARE(EcsYobi);
FLECS_API extern ECS_DECLARE(EcsDuration);
FLECS_API extern ECS_DECLARE(EcsPicoSeconds);
FLECS_API extern ECS_DECLARE(EcsNanoSeconds);
FLECS_API extern ECS_DECLARE(EcsMicroSeconds);
FLECS_API extern ECS_DECLARE(EcsMilliSeconds);
FLECS_API extern ECS_DECLARE(EcsSeconds);
FLECS_API extern ECS_DECLARE(EcsMinutes);
FLECS_API extern ECS_DECLARE(EcsHours);
FLECS_API extern ECS_DECLARE(EcsDays);
FLECS_API extern ECS_DECLARE(EcsTime);
FLECS_API extern ECS_DECLARE(EcsDate);
FLECS_API extern ECS_DECLARE(EcsMass);
FLECS_API extern ECS_DECLARE(EcsGrams);
FLECS_API extern ECS_DECLARE(EcsKiloGrams);
FLECS_API extern ECS_DECLARE(EcsElectricCurrent);
FLECS_API extern ECS_DECLARE(EcsAmpere);
FLECS_API extern ECS_DECLARE(EcsAmount);
FLECS_API extern ECS_DECLARE(EcsMole);
FLECS_API extern ECS_DECLARE(EcsLuminousIntensity);
FLECS_API extern ECS_DECLARE(EcsCandela);
FLECS_API extern ECS_DECLARE(EcsForce);
FLECS_API extern ECS_DECLARE(EcsNewton);
FLECS_API extern ECS_DECLARE(EcsLength);
FLECS_API extern ECS_DECLARE(EcsMeters);
FLECS_API extern ECS_DECLARE(EcsPicoMeters);
FLECS_API extern ECS_DECLARE(EcsNanoMeters);
FLECS_API extern ECS_DECLARE(EcsMicroMeters);
FLECS_API extern ECS_DECLARE(EcsMilliMeters);
FLECS_API extern ECS_DECLARE(EcsCentiMeters);
FLECS_API extern ECS_DECLARE(EcsKiloMeters);
FLECS_API extern ECS_DECLARE(EcsMiles);
FLECS_API extern ECS_DECLARE(EcsPixels);
FLECS_API extern ECS_DECLARE(EcsPressure);
FLECS_API extern ECS_DECLARE(EcsPascal);
FLECS_API extern ECS_DECLARE(EcsBar);
FLECS_API extern ECS_DECLARE(EcsSpeed);
FLECS_API extern ECS_DECLARE(EcsMetersPerSecond);
FLECS_API extern ECS_DECLARE(EcsKiloMetersPerSecond);
FLECS_API extern ECS_DECLARE(EcsKiloMetersPerHour);
FLECS_API extern ECS_DECLARE(EcsMilesPerHour);
FLECS_API extern ECS_DECLARE(EcsTemperature);
FLECS_API extern ECS_DECLARE(EcsKelvin);
FLECS_API extern ECS_DECLARE(EcsCelsius);
FLECS_API extern ECS_DECLARE(EcsFahrenheit);
FLECS_API extern ECS_DECLARE(EcsData);
FLECS_API extern ECS_DECLARE(EcsBits);
FLECS_API extern ECS_DECLARE(EcsKiloBits);
FLECS_API extern ECS_DECLARE(EcsMegaBits);
FLECS_API extern ECS_DECLARE(EcsGigaBits);
FLECS_API extern ECS_DECLARE(EcsBytes);
FLECS_API extern ECS_DECLARE(EcsKiloBytes);
FLECS_API extern ECS_DECLARE(EcsMegaBytes);
FLECS_API extern ECS_DECLARE(EcsGigaBytes);
FLECS_API extern ECS_DECLARE(EcsKibiBytes);
FLECS_API extern ECS_DECLARE(EcsMebiBytes);
FLECS_API extern ECS_DECLARE(EcsGibiBytes);
FLECS_API extern ECS_DECLARE(EcsDataRate);
FLECS_API extern ECS_DECLARE(EcsBitsPerSecond);
FLECS_API extern ECS_DECLARE(EcsKiloBitsPerSecond);
FLECS_API extern ECS_DECLARE(EcsMegaBitsPerSecond);
FLECS_API extern ECS_DECLARE(EcsGigaBitsPerSecond);
FLECS_API extern ECS_DECLARE(EcsBytesPerSecond);
FLECS_API extern ECS_DECLARE(EcsKiloBytesPerSecond);
FLECS_API extern ECS_DECLARE(EcsMegaBytesPerSecond);
FLECS_API extern ECS_DECLARE(EcsGigaBytesPerSecond);
FLECS_API extern ECS_DECLARE(EcsAngle);
FLECS_API extern ECS_DECLARE(EcsRadians);
FLECS_API extern ECS_DECLARE(EcsDegrees);
FLECS_API extern ECS_DECLARE(EcsFrequency);
FLECS_API extern ECS_DECLARE(EcsHertz);
FLECS_API extern ECS_DECLARE(EcsKiloHertz);
FLECS_API extern ECS_DECLARE(EcsMegaHertz);
FLECS_API extern ECS_DECLARE(EcsGigaHertz);
FLECS_API extern ECS_DECLARE(EcsUri);
FLECS_API extern ECS_DECLARE(EcsUriHyperlink);
FLECS_API extern ECS_DECLARE(EcsUriImage);
FLECS_API extern ECS_DECLARE(EcsUriFile);
FLECS_API extern ECS_DECLARE(EcsAcceleration);
FLECS_API extern ECS_DECLARE(EcsPercentage);
FLECS_API extern ECS_DECLARE(EcsBel);
FLECS_API extern ECS_DECLARE(EcsDeciBel);
FLECS_API
void FlecsUnitsImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_META
#ifdef FLECS_NO_META
#error "FLECS_NO_META failed: META is required by other addons"
#endif
#ifdef FLECS_META
#include <stddef.h>
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifndef FLECS_META_H
#define FLECS_META_H
#ifdef __cplusplus
extern "C" {
#endif
#define ECS_MEMBER_DESC_CACHE_SIZE (32)
typedef bool ecs_bool_t;
typedef char ecs_char_t;
typedef unsigned char ecs_byte_t;
typedef uint8_t ecs_u8_t;
typedef uint16_t ecs_u16_t;
typedef uint32_t ecs_u32_t;
typedef uint64_t ecs_u64_t;
typedef uintptr_t ecs_uptr_t;
typedef int8_t ecs_i8_t;
typedef int16_t ecs_i16_t;
typedef int32_t ecs_i32_t;
typedef int64_t ecs_i64_t;
typedef intptr_t ecs_iptr_t;
typedef float ecs_f32_t;
typedef double ecs_f64_t;
typedef char* ecs_string_t;
FLECS_API extern const ecs_entity_t ecs_id(EcsMetaType);
FLECS_API extern const ecs_entity_t ecs_id(EcsMetaTypeSerialized);
FLECS_API extern const ecs_entity_t ecs_id(EcsPrimitive);
FLECS_API extern const ecs_entity_t ecs_id(EcsEnum);
FLECS_API extern const ecs_entity_t ecs_id(EcsBitmask);
FLECS_API extern const ecs_entity_t ecs_id(EcsMember);
FLECS_API extern const ecs_entity_t ecs_id(EcsMemberRanges);
FLECS_API extern const ecs_entity_t ecs_id(EcsStruct);
FLECS_API extern const ecs_entity_t ecs_id(EcsArray);
FLECS_API extern const ecs_entity_t ecs_id(EcsVector);
FLECS_API extern const ecs_entity_t ecs_id(EcsOpaque);
FLECS_API extern const ecs_entity_t ecs_id(EcsUnit);
FLECS_API extern const ecs_entity_t ecs_id(EcsUnitPrefix);
FLECS_API extern const ecs_entity_t EcsConstant;
FLECS_API extern const ecs_entity_t EcsQuantity;
FLECS_API extern const ecs_entity_t ecs_id(ecs_bool_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_char_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_byte_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_u8_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_u16_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_u32_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_u64_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_uptr_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_i8_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_i16_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_i32_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_i64_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_iptr_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_f32_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_f64_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_string_t);
FLECS_API extern const ecs_entity_t ecs_id(ecs_entity_t);
typedef enum ecs_type_kind_t {
EcsPrimitiveType,
EcsBitmaskType,
EcsEnumType,
EcsStructType,
EcsArrayType,
EcsVectorType,
EcsOpaqueType,
EcsTypeKindLast = EcsOpaqueType
} ecs_type_kind_t;
typedef struct EcsMetaType {
ecs_type_kind_t kind;
bool existing;
bool partial;
} EcsMetaType;
typedef enum ecs_primitive_kind_t {
EcsBool = 1,
EcsChar,
EcsByte,
EcsU8,
EcsU16,
EcsU32,
EcsU64,
EcsI8,
EcsI16,
EcsI32,
EcsI64,
EcsF32,
EcsF64,
EcsUPtr,
EcsIPtr,
EcsString,
EcsEntity,
EcsPrimitiveKindLast = EcsEntity
} ecs_primitive_kind_t;
typedef struct EcsPrimitive {
ecs_primitive_kind_t kind;
} EcsPrimitive;
typedef struct EcsMember {
ecs_entity_t type;
int32_t count;
ecs_entity_t unit;
int32_t offset;
} EcsMember;
typedef struct ecs_member_value_range_t {
double min;
double max;
} ecs_member_value_range_t;
typedef struct EcsMemberRanges {
ecs_member_value_range_t value;
ecs_member_value_range_t warning;
ecs_member_value_range_t error;
} EcsMemberRanges;
typedef struct ecs_member_t {
const char *name;
ecs_entity_t type;
int32_t count;
int32_t offset;
ecs_entity_t unit;
ecs_member_value_range_t range;
ecs_member_value_range_t error_range;
ecs_member_value_range_t warning_range;
ecs_size_t size;
ecs_entity_t member;
} ecs_member_t;
typedef struct EcsStruct {
ecs_vec_t members;
} EcsStruct;
typedef struct ecs_enum_constant_t {
const char *name;
int32_t value;
ecs_entity_t constant;
} ecs_enum_constant_t;
typedef struct EcsEnum {
ecs_map_t constants;
} EcsEnum;
typedef struct ecs_bitmask_constant_t {
const char *name;
ecs_flags32_t value;
ecs_entity_t constant;
} ecs_bitmask_constant_t;
typedef struct EcsBitmask {
ecs_map_t constants;
} EcsBitmask;
typedef struct EcsArray {
ecs_entity_t type;
int32_t count;
} EcsArray;
typedef struct EcsVector {
ecs_entity_t type;
} EcsVector;
#if !defined(__cplusplus) || !defined(FLECS_CPP)
typedef struct ecs_serializer_t {
int (*value)(
const struct ecs_serializer_t *ser,
ecs_entity_t type,
const void *value);
int (*member)(
const struct ecs_serializer_t *ser,
const char *member);
const ecs_world_t *world;
void *ctx;
} ecs_serializer_t;
#elif defined(__cplusplus)
}
typedef struct ecs_serializer_t {
int (*value_)(
const struct ecs_serializer_t *ser,
ecs_entity_t type,
const void *value);
int (*member_)(
const struct ecs_serializer_t *ser,
const char *name);
int value(ecs_entity_t type, const void *value) const;
template <typename T>
int value(const T& value) const;
int member(const char *name) const;
const ecs_world_t *world;
void *ctx;
} ecs_serializer_t;
extern "C" {
#endif
typedef int (*ecs_meta_serialize_t)(
const ecs_serializer_t *ser,
const void *src);
typedef struct EcsOpaque {
ecs_entity_t as_type;
ecs_meta_serialize_t serialize;
void (*assign_bool)(
void *dst,
bool value);
void (*assign_char)(
void *dst,
char value);
void (*assign_int)(
void *dst,
int64_t value);
void (*assign_uint)(
void *dst,
uint64_t value);
void (*assign_float)(
void *dst,
double value);
void (*assign_string)(
void *dst,
const char *value);
void (*assign_entity)(
void *dst,
ecs_world_t *world,
ecs_entity_t entity);
void (*assign_null)(
void *dst);
void (*clear)(
void *dst);
void* (*ensure_element)(
void *dst,
size_t elem);
void* (*ensure_member)(
void *dst,
const char *member);
size_t (*count)(
const void *dst);
void (*resize)(
void *dst,
size_t count);
} EcsOpaque;
typedef struct ecs_unit_translation_t {
int32_t factor;
int32_t power;
} ecs_unit_translation_t;
typedef struct EcsUnit {
char *symbol;
ecs_entity_t prefix;
ecs_entity_t base;
ecs_entity_t over;
ecs_unit_translation_t translation;
} EcsUnit;
typedef struct EcsUnitPrefix {
char *symbol;
ecs_unit_translation_t translation;
} EcsUnitPrefix;
typedef enum ecs_meta_type_op_kind_t {
EcsOpArray,
EcsOpVector,
EcsOpOpaque,
EcsOpPush,
EcsOpPop,
EcsOpScope,
EcsOpEnum,
EcsOpBitmask,
EcsOpPrimitive,
EcsOpBool,
EcsOpChar,
EcsOpByte,
EcsOpU8,
EcsOpU16,
EcsOpU32,
EcsOpU64,
EcsOpI8,
EcsOpI16,
EcsOpI32,
EcsOpI64,
EcsOpF32,
EcsOpF64,
EcsOpUPtr,
EcsOpIPtr,
EcsOpString,
EcsOpEntity,
EcsMetaTypeOpKindLast = EcsOpEntity
} ecs_meta_type_op_kind_t;
typedef struct ecs_meta_type_op_t {
ecs_meta_type_op_kind_t kind;
ecs_size_t offset;
int32_t count;
const char *name;
int32_t op_count;
ecs_size_t size;
ecs_entity_t type;
int32_t member_index;
ecs_hashmap_t *members;
} ecs_meta_type_op_t;
typedef struct EcsMetaTypeSerialized {
ecs_vec_t ops;
} EcsMetaTypeSerialized;
#define ECS_META_MAX_SCOPE_DEPTH (32)
typedef struct ecs_meta_scope_t {
ecs_entity_t type;
ecs_meta_type_op_t *ops;
int32_t op_count;
int32_t op_cur;
int32_t elem_cur;
int32_t prev_depth;
void *ptr;
const EcsComponent *comp;
const EcsOpaque *opaque;
ecs_vec_t *vector;
ecs_hashmap_t *members;
bool is_collection;
bool is_inline_array;
bool is_empty_scope;
} ecs_meta_scope_t;
typedef struct ecs_meta_cursor_t {
const ecs_world_t *world;
ecs_meta_scope_t scope[ECS_META_MAX_SCOPE_DEPTH];
int32_t depth;
bool valid;
bool is_primitive_scope;
ecs_entity_t (*lookup_action)(const ecs_world_t*, const char*, void*);
void *lookup_ctx;
} ecs_meta_cursor_t;
FLECS_API
ecs_meta_cursor_t ecs_meta_cursor(
const ecs_world_t *world,
ecs_entity_t type,
void *ptr);
FLECS_API
void* ecs_meta_get_ptr(
ecs_meta_cursor_t *cursor);
FLECS_API
int ecs_meta_next(
ecs_meta_cursor_t *cursor);
FLECS_API
int ecs_meta_elem(
ecs_meta_cursor_t *cursor,
int32_t elem);
FLECS_API
int ecs_meta_member(
ecs_meta_cursor_t *cursor,
const char *name);
FLECS_API
int ecs_meta_dotmember(
ecs_meta_cursor_t *cursor,
const char *name);
FLECS_API
int ecs_meta_push(
ecs_meta_cursor_t *cursor);
FLECS_API
int ecs_meta_pop(
ecs_meta_cursor_t *cursor);
FLECS_API
bool ecs_meta_is_collection(
const ecs_meta_cursor_t *cursor);
FLECS_API
ecs_entity_t ecs_meta_get_type(
const ecs_meta_cursor_t *cursor);
FLECS_API
ecs_entity_t ecs_meta_get_unit(
const ecs_meta_cursor_t *cursor);
FLECS_API
const char* ecs_meta_get_member(
const ecs_meta_cursor_t *cursor);
FLECS_API
ecs_entity_t ecs_meta_get_member_id(
const ecs_meta_cursor_t *cursor);
FLECS_API
int ecs_meta_set_bool(
ecs_meta_cursor_t *cursor,
bool value);
FLECS_API
int ecs_meta_set_char(
ecs_meta_cursor_t *cursor,
char value);
FLECS_API
int ecs_meta_set_int(
ecs_meta_cursor_t *cursor,
int64_t value);
FLECS_API
int ecs_meta_set_uint(
ecs_meta_cursor_t *cursor,
uint64_t value);
FLECS_API
int ecs_meta_set_float(
ecs_meta_cursor_t *cursor,
double value);
FLECS_API
int ecs_meta_set_string(
ecs_meta_cursor_t *cursor,
const char *value);
FLECS_API
int ecs_meta_set_string_literal(
ecs_meta_cursor_t *cursor,
const char *value);
FLECS_API
int ecs_meta_set_entity(
ecs_meta_cursor_t *cursor,
ecs_entity_t value);
FLECS_API
int ecs_meta_set_null(
ecs_meta_cursor_t *cursor);
FLECS_API
int ecs_meta_set_value(
ecs_meta_cursor_t *cursor,
const ecs_value_t *value);
FLECS_API
bool ecs_meta_get_bool(
const ecs_meta_cursor_t *cursor);
FLECS_API
char ecs_meta_get_char(
const ecs_meta_cursor_t *cursor);
FLECS_API
int64_t ecs_meta_get_int(
const ecs_meta_cursor_t *cursor);
FLECS_API
uint64_t ecs_meta_get_uint(
const ecs_meta_cursor_t *cursor);
FLECS_API
double ecs_meta_get_float(
const ecs_meta_cursor_t *cursor);
FLECS_API
const char* ecs_meta_get_string(
const ecs_meta_cursor_t *cursor);
FLECS_API
ecs_entity_t ecs_meta_get_entity(
const ecs_meta_cursor_t *cursor);
FLECS_API
double ecs_meta_ptr_to_float(
ecs_primitive_kind_t type_kind,
const void *ptr);
typedef struct ecs_primitive_desc_t {
ecs_entity_t entity;
ecs_primitive_kind_t kind;
} ecs_primitive_desc_t;
FLECS_API
ecs_entity_t ecs_primitive_init(
ecs_world_t *world,
const ecs_primitive_desc_t *desc);
typedef struct ecs_enum_desc_t {
ecs_entity_t entity;
ecs_enum_constant_t constants[ECS_MEMBER_DESC_CACHE_SIZE];
} ecs_enum_desc_t;
FLECS_API
ecs_entity_t ecs_enum_init(
ecs_world_t *world,
const ecs_enum_desc_t *desc);
typedef struct ecs_bitmask_desc_t {
ecs_entity_t entity;
ecs_bitmask_constant_t constants[ECS_MEMBER_DESC_CACHE_SIZE];
} ecs_bitmask_desc_t;
FLECS_API
ecs_entity_t ecs_bitmask_init(
ecs_world_t *world,
const ecs_bitmask_desc_t *desc);
typedef struct ecs_array_desc_t {
ecs_entity_t entity;
ecs_entity_t type;
int32_t count;
} ecs_array_desc_t;
FLECS_API
ecs_entity_t ecs_array_init(
ecs_world_t *world,
const ecs_array_desc_t *desc);
typedef struct ecs_vector_desc_t {
ecs_entity_t entity;
ecs_entity_t type;
} ecs_vector_desc_t;
FLECS_API
ecs_entity_t ecs_vector_init(
ecs_world_t *world,
const ecs_vector_desc_t *desc);
typedef struct ecs_struct_desc_t {
ecs_entity_t entity;
ecs_member_t members[ECS_MEMBER_DESC_CACHE_SIZE];
} ecs_struct_desc_t;
FLECS_API
ecs_entity_t ecs_struct_init(
ecs_world_t *world,
const ecs_struct_desc_t *desc);
typedef struct ecs_opaque_desc_t {
ecs_entity_t entity;
EcsOpaque type;
} ecs_opaque_desc_t;
FLECS_API
ecs_entity_t ecs_opaque_init(
ecs_world_t *world,
const ecs_opaque_desc_t *desc);
typedef struct ecs_unit_desc_t {
ecs_entity_t entity;
const char *symbol;
ecs_entity_t quantity;
ecs_entity_t base;
ecs_entity_t over;
ecs_unit_translation_t translation;
ecs_entity_t prefix;
} ecs_unit_desc_t;
FLECS_API
ecs_entity_t ecs_unit_init(
ecs_world_t *world,
const ecs_unit_desc_t *desc);
typedef struct ecs_unit_prefix_desc_t {
ecs_entity_t entity;
const char *symbol;
ecs_unit_translation_t translation;
} ecs_unit_prefix_desc_t;
FLECS_API
ecs_entity_t ecs_unit_prefix_init(
ecs_world_t *world,
const ecs_unit_prefix_desc_t *desc);
FLECS_API
ecs_entity_t ecs_quantity_init(
ecs_world_t *world,
const ecs_entity_desc_t *desc);
#define ecs_primitive(world, ...)\
ecs_primitive_init(world, &(ecs_primitive_desc_t) __VA_ARGS__ )
#define ecs_enum(world, ...)\
ecs_enum_init(world, &(ecs_enum_desc_t) __VA_ARGS__ )
#define ecs_bitmask(world, ...)\
ecs_bitmask_init(world, &(ecs_bitmask_desc_t) __VA_ARGS__ )
#define ecs_array(world, ...)\
ecs_array_init(world, &(ecs_array_desc_t) __VA_ARGS__ )
#define ecs_vector(world, ...)\
ecs_vector_init(world, &(ecs_vector_desc_t) __VA_ARGS__ )
#define ecs_opaque(world, ...)\
ecs_opaque_init(world, &(ecs_opaque_desc_t) __VA_ARGS__ )
#define ecs_struct(world, ...)\
ecs_struct_init(world, &(ecs_struct_desc_t) __VA_ARGS__ )
#define ecs_unit(world, ...)\
ecs_unit_init(world, &(ecs_unit_desc_t) __VA_ARGS__ )
#define ecs_unit_prefix(world, ...)\
ecs_unit_prefix_init(world, &(ecs_unit_prefix_desc_t) __VA_ARGS__ )
#define ecs_quantity(world, ...)\
ecs_quantity_init(world, &(ecs_entity_desc_t) __VA_ARGS__ )
FLECS_API
void FlecsMetaImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_EXPR
#ifdef FLECS_NO_EXPR
#error "FLECS_NO_EXPR failed: EXPR is required by other addons"
#endif
#ifdef FLECS_EXPR
#ifndef FLECS_META
#define FLECS_META
#endif
#ifndef FLECS_PARSER
#define FLECS_PARSER
#endif
#ifndef FLECS_EXPR_H
#define FLECS_EXPR_H
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API
char* ecs_chresc(
char *out,
char in,
char delimiter);
const char* ecs_chrparse(
const char *in,
char *out);
FLECS_API
ecs_size_t ecs_stresc(
char *out,
ecs_size_t size,
char delimiter,
const char *in);
FLECS_API
char* ecs_astresc(
char delimiter,
const char *in);
typedef struct ecs_expr_var_t {
char *name;
ecs_value_t value;
bool owned;
} ecs_expr_var_t;
typedef struct ecs_expr_var_scope_t {
ecs_hashmap_t var_index;
ecs_vec_t vars;
struct ecs_expr_var_scope_t *parent;
} ecs_expr_var_scope_t;
typedef struct ecs_vars_t {
ecs_world_t *world;
ecs_expr_var_scope_t root;
ecs_expr_var_scope_t *cur;
} ecs_vars_t;
FLECS_API
void ecs_vars_init(
ecs_world_t *world,
ecs_vars_t *vars);
FLECS_API
void ecs_vars_fini(
ecs_vars_t *vars);
FLECS_API
void ecs_vars_push(
ecs_vars_t *vars);
FLECS_API
int ecs_vars_pop(
ecs_vars_t *vars);
FLECS_API
ecs_expr_var_t* ecs_vars_declare(
ecs_vars_t *vars,
const char *name,
ecs_entity_t type);
FLECS_API
ecs_expr_var_t* ecs_vars_declare_w_value(
ecs_vars_t *vars,
const char *name,
ecs_value_t *value);
FLECS_API
ecs_expr_var_t* ecs_vars_lookup(
const ecs_vars_t *vars,
const char *name);
typedef struct ecs_parse_expr_desc_t {
const char *name;
const char *expr;
ecs_entity_t (*lookup_action)(
const ecs_world_t*,
const char *value,
void *ctx);
void *lookup_ctx;
ecs_vars_t *vars;
} ecs_parse_expr_desc_t;
FLECS_API
const char* ecs_parse_expr(
ecs_world_t *world,
const char *ptr,
ecs_value_t *value,
const ecs_parse_expr_desc_t *desc);
FLECS_API
char* ecs_ptr_to_expr(
const ecs_world_t *world,
ecs_entity_t type,
const void *data);
FLECS_API
int ecs_ptr_to_expr_buf(
const ecs_world_t *world,
ecs_entity_t type,
const void *data,
ecs_strbuf_t *buf);
FLECS_API
char* ecs_ptr_to_str(
const ecs_world_t *world,
ecs_entity_t type,
const void *data);
FLECS_API
int ecs_ptr_to_str_buf(
const ecs_world_t *world,
ecs_entity_t type,
const void *data,
ecs_strbuf_t *buf);
FLECS_API
int ecs_primitive_to_expr_buf(
const ecs_world_t *world,
ecs_primitive_kind_t kind,
const void *data,
ecs_strbuf_t *buf);
FLECS_API
const char *ecs_parse_expr_token(
const char *name,
const char *expr,
const char *ptr,
char *token);
FLECS_API
char* ecs_interpolate_string(
ecs_world_t *world,
const char *str,
const ecs_vars_t *vars);
FLECS_API
void ecs_iter_to_vars(
const ecs_iter_t *it,
ecs_vars_t *vars,
int offset);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_META_C
#ifdef FLECS_NO_META_C
#error "FLECS_NO_META_C failed: META_C is required by other addons"
#endif
#ifdef FLECS_META_C
#ifndef FLECS_META
#define FLECS_META
#endif
#ifndef FLECS_PARSER
#define FLECS_PARSER
#endif
#ifndef FLECS_META_C_H
#define FLECS_META_C_H
#ifdef __cplusplus
extern "C" {
#endif
#define ECS_META_COMPONENT(world, name)\
ECS_COMPONENT_DEFINE(world, name);\
ecs_meta_from_desc(world, ecs_id(name),\
FLECS__##name##_kind, FLECS__##name##_desc)
#define ECS_STRUCT(name, ...)\
ECS_META_IMPL_CALL(ECS_STRUCT_, ECS_META_IMPL, name, #__VA_ARGS__);\
ECS_STRUCT_TYPE(name, __VA_ARGS__)
#define ECS_ENUM(name, ...)\
ECS_META_IMPL_CALL(ECS_ENUM_, ECS_META_IMPL, name, #__VA_ARGS__);\
ECS_ENUM_TYPE(name, __VA_ARGS__)
#define ECS_BITMASK(name, ...)\
ECS_META_IMPL_CALL(ECS_BITMASK_, ECS_META_IMPL, name, #__VA_ARGS__);\
ECS_ENUM_TYPE(name, __VA_ARGS__)
#define ECS_PRIVATE
FLECS_API
int ecs_meta_from_desc(
ecs_world_t *world,
ecs_entity_t component,
ecs_type_kind_t kind,
const char *desc);
#define ECS_META_IMPL_CALL_INNER(base, impl, name, type_desc)\
base ## impl(name, type_desc)
#define ECS_META_IMPL_CALL(base, impl, name, type_desc)\
ECS_META_IMPL_CALL_INNER(base, impl, name, type_desc)
#define ECS_STRUCT_TYPE(name, ...)\
typedef struct __VA_ARGS__ name
#define ECS_STRUCT_ECS_META_IMPL ECS_STRUCT_IMPL
#define ECS_STRUCT_IMPL(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name);\
static const char *FLECS__##name##_desc = type_desc;\
static ecs_type_kind_t FLECS__##name##_kind = EcsStructType;\
ECS_COMPONENT_DECLARE(name) = 0
#define ECS_STRUCT_DECLARE(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name);\
ECS_COMPONENT_DECLARE(name) = 0
#define ECS_STRUCT_EXTERN(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name)
#define ECS_ENUM_TYPE(name, ...)\
typedef enum __VA_ARGS__ name
#define ECS_ENUM_ECS_META_IMPL ECS_ENUM_IMPL
#define ECS_ENUM_IMPL(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name);\
static const char *FLECS__##name##_desc = type_desc;\
static ecs_type_kind_t FLECS__##name##_kind = EcsEnumType;\
ECS_COMPONENT_DECLARE(name) = 0
#define ECS_ENUM_DECLARE(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name);\
ECS_COMPONENT_DECLARE(name) = 0
#define ECS_ENUM_EXTERN(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name)
#define ECS_BITMASK_TYPE(name, ...)\
typedef enum __VA_ARGS__ name
#define ECS_BITMASK_ECS_META_IMPL ECS_BITMASK_IMPL
#define ECS_BITMASK_IMPL(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name);\
static const char *FLECS__##name##_desc = type_desc;\
static ecs_type_kind_t FLECS__##name##_kind = EcsBitmaskType;\
ECS_COMPONENT_DECLARE(name) = 0
#define ECS_BITMASK_DECLARE(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name);\
ECS_COMPONENT_DECLARE(name) = 0
#define ECS_BITMASK_EXTERN(name, type_desc)\
extern ECS_COMPONENT_DECLARE(name)
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_PLECS
#ifdef FLECS_NO_PLECS
#error "FLECS_NO_PLECS failed: PLECS is required by other addons"
#endif
#ifdef FLECS_PLECS
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifndef FLECS_PARSER
#define FLECS_PARSER
#endif
#ifndef FLECS_EXPR
#define FLECS_EXPR
#endif
#ifndef FLECS_PLECS_H
#define FLECS_PLECS_H
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API
extern ECS_COMPONENT_DECLARE(EcsScript);
typedef struct EcsScript {
ecs_vec_t using_;
char *script;
ecs_vec_t prop_defaults;
ecs_world_t *world;
} EcsScript;
FLECS_API
int ecs_plecs_from_str(
ecs_world_t *world,
const char *name,
const char *str);
FLECS_API
int ecs_plecs_from_file(
ecs_world_t *world,
const char *filename);
typedef struct ecs_script_desc_t {
ecs_entity_t entity;
const char *filename;
const char *str;
} ecs_script_desc_t;
FLECS_API
ecs_entity_t ecs_script_init(
ecs_world_t *world,
const ecs_script_desc_t *desc);
#define ecs_script(world, ...)\
ecs_script_init(world, &(ecs_script_desc_t) __VA_ARGS__)
FLECS_API
int ecs_script_update(
ecs_world_t *world,
ecs_entity_t script,
ecs_entity_t instance,
const char *str,
ecs_vars_t *vars);
FLECS_API
void ecs_script_clear(
ecs_world_t *world,
ecs_entity_t script,
ecs_entity_t instance);
FLECS_API
void FlecsScriptImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_RULES
#ifdef FLECS_NO_RULES
#error "FLECS_NO_RULES failed: RULES is required by other addons"
#endif
#ifdef FLECS_RULES
#ifndef FLECS_RULES_H
#define FLECS_RULES_H
#ifdef __cplusplus
extern "C" {
#endif
#define ecs_rule(world, ...)\
ecs_rule_init(world, &(ecs_filter_desc_t) __VA_ARGS__ )
FLECS_API
ecs_rule_t* ecs_rule_init(
ecs_world_t *world,
const ecs_filter_desc_t *desc);
FLECS_API
void ecs_rule_fini(
ecs_rule_t *rule);
FLECS_API
const ecs_filter_t* ecs_rule_get_filter(
const ecs_rule_t *rule);
FLECS_API
int32_t ecs_rule_var_count(
const ecs_rule_t *rule);
FLECS_API
int32_t ecs_rule_find_var(
const ecs_rule_t *rule,
const char *name);
FLECS_API
const char* ecs_rule_var_name(
const ecs_rule_t *rule,
int32_t var_id);
FLECS_API
bool ecs_rule_var_is_entity(
const ecs_rule_t *rule,
int32_t var_id);
FLECS_API
ecs_iter_t ecs_rule_iter(
const ecs_world_t *world,
const ecs_rule_t *rule);
FLECS_API
bool ecs_rule_next(
ecs_iter_t *it);
FLECS_API
bool ecs_rule_next_instanced(
ecs_iter_t *it);
FLECS_API
char* ecs_rule_str(
const ecs_rule_t *rule);
FLECS_API
char* ecs_rule_str_w_profile(
const ecs_rule_t *rule,
const ecs_iter_t *it);
FLECS_API
const char* ecs_rule_parse_vars(
ecs_rule_t *rule,
ecs_iter_t *it,
const char *expr);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_SNAPSHOT
#ifdef FLECS_NO_SNAPSHOT
#error "FLECS_NO_SNAPSHOT failed: SNAPSHOT is required by other addons"
#endif
#ifdef FLECS_SNAPSHOT
#ifndef FLECS_SNAPSHOT_H
#define FLECS_SNAPSHOT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ecs_snapshot_t ecs_snapshot_t;
FLECS_API
ecs_snapshot_t* ecs_snapshot_take(
ecs_world_t *world);
FLECS_API
ecs_snapshot_t* ecs_snapshot_take_w_iter(
ecs_iter_t *iter);
FLECS_API
void ecs_snapshot_restore(
ecs_world_t *world,
ecs_snapshot_t *snapshot);
FLECS_API
ecs_iter_t ecs_snapshot_iter(
ecs_snapshot_t *snapshot);
FLECS_API
bool ecs_snapshot_next(
ecs_iter_t *iter);
FLECS_API
void ecs_snapshot_free(
ecs_snapshot_t *snapshot);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_PARSER
#ifdef FLECS_NO_PARSER
#error "FLECS_NO_PARSER failed: PARSER is required by other addons"
#endif
#ifdef FLECS_PARSER
#ifndef FLECS_PARSER_H
#define FLECS_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API
const char* ecs_parse_ws(
const char *ptr);
FLECS_API
const char* ecs_parse_ws_eol(
const char *ptr);
const char* ecs_parse_identifier(
const char *name,
const char *expr,
const char *ptr,
char *token_out);
FLECS_API
const char* ecs_parse_digit(
const char *ptr,
char *token);
FLECS_API
const char* ecs_parse_token(
const char *name,
const char *expr,
const char *ptr,
char *token_out,
char delim);
FLECS_API
char* ecs_parse_term(
const ecs_world_t *world,
const char *name,
const char *expr,
const char *ptr,
ecs_term_t *term_out);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_OS_API_IMPL
#ifdef FLECS_NO_OS_API_IMPL
#error "FLECS_NO_OS_API_IMPL failed: OS_API_IMPL is required by other addons"
#endif
#ifdef FLECS_OS_API_IMPL
#ifndef FLECS_OS_API_IMPL_H
#define FLECS_OS_API_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API
void ecs_set_os_api_impl(void);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_MODULE
#ifdef FLECS_NO_MODULE
#error "FLECS_NO_MODULE failed: MODULE is required by other addons"
#endif
#ifdef FLECS_MODULE
#ifndef FLECS_MODULE_H
#define FLECS_MODULE_H
#ifdef __cplusplus
extern "C" {
#endif
FLECS_API
ecs_entity_t ecs_import(
ecs_world_t *world,
ecs_module_action_t module,
const char *module_name);
FLECS_API
ecs_entity_t ecs_import_c(
ecs_world_t *world,
ecs_module_action_t module,
const char *module_name_c);
FLECS_API
ecs_entity_t ecs_import_from_library(
ecs_world_t *world,
const char *library_name,
const char *module_name);
FLECS_API
ecs_entity_t ecs_module_init(
ecs_world_t *world,
const char *c_name,
const ecs_component_desc_t *desc);
#define ECS_MODULE_DEFINE(world, id)\
{\
ecs_component_desc_t desc = {0};\
desc.entity = ecs_id(id);\
ecs_id(id) = ecs_module_init(world, #id, &desc);\
ecs_set_scope(world, ecs_id(id));\
}
#define ECS_MODULE(world, id)\
ecs_entity_t ecs_id(id) = 0; ECS_MODULE_DEFINE(world, id)\
(void)ecs_id(id)
#define ECS_IMPORT(world, id) ecs_import_c(world, id##Import, #id)
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
#ifdef FLECS_CPP
#ifdef FLECS_NO_CPP
#error "FLECS_NO_CPP failed: CPP is required by other addons"
#endif
#ifdef FLECS_CPP
#ifndef FLECS_CPP_H
#define FLECS_CPP_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
#if defined(__clang__)
#define ECS_FUNC_NAME_FRONT(type, name) ((sizeof(#type) + sizeof(" flecs::_::() [T = ") + sizeof(#name)) - 3u)
#define ECS_FUNC_NAME_BACK (sizeof("]") - 1u)
#define ECS_FUNC_NAME __PRETTY_FUNCTION__
#elif defined(__GNUC__)
#define ECS_FUNC_NAME_FRONT(type, name) ((sizeof(#type) + sizeof(" flecs::_::() [with T = ") + sizeof(#name)) - 3u)
#define ECS_FUNC_NAME_BACK (sizeof("]") - 1u)
#define ECS_FUNC_NAME __PRETTY_FUNCTION__
#elif defined(_WIN32)
#define ECS_FUNC_NAME_FRONT(type, name) ((sizeof(#type) + sizeof(" __cdecl flecs::_::<") + sizeof(#name)) - 3u)
#define ECS_FUNC_NAME_BACK (sizeof(">(void)") - 1u)
#define ECS_FUNC_NAME __FUNCSIG__
#else
#error "implicit component registration not supported"
#endif
#define ECS_FUNC_TYPE_LEN(type, name, str)\
(flecs::string::length(str) - (ECS_FUNC_NAME_FRONT(type, name) + ECS_FUNC_NAME_BACK))
#endif
FLECS_API
char* ecs_cpp_get_type_name(
char *type_name,
const char *func_name,
size_t len,
size_t front_len);
FLECS_API
char* ecs_cpp_get_symbol_name(
char *symbol_name,
const char *type_name,
size_t len);
FLECS_API
char* ecs_cpp_get_constant_name(
char *constant_name,
const char *func_name,
size_t len,
size_t back_len);
FLECS_API
const char* ecs_cpp_trim_module(
ecs_world_t *world,
const char *type_name);
FLECS_API
void ecs_cpp_component_validate(
ecs_world_t *world,
ecs_entity_t id,
const char *name,
const char *symbol,
size_t size,
size_t alignment,
bool implicit_name);
FLECS_API
ecs_entity_t ecs_cpp_component_register(
ecs_world_t *world,
ecs_entity_t id,
const char *name,
const char *symbol,
ecs_size_t size,
ecs_size_t alignment,
bool implicit_name,
bool *existing_out);
FLECS_API
ecs_entity_t ecs_cpp_component_register_explicit(
ecs_world_t *world,
ecs_entity_t s_id,
ecs_entity_t id,
const char *name,
const char *type_name,
const char *symbol,
size_t size,
size_t alignment,
bool is_component,
bool *existing_out);
FLECS_API
void ecs_cpp_enum_init(
ecs_world_t *world,
ecs_entity_t id);
FLECS_API
ecs_entity_t ecs_cpp_enum_constant_register(
ecs_world_t *world,
ecs_entity_t parent,
ecs_entity_t id,
const char *name,
int value);
FLECS_API
int32_t ecs_cpp_reset_count_get(void);
FLECS_API
int32_t ecs_cpp_reset_count_inc(void);
#ifdef FLECS_META
FLECS_API
const ecs_member_t* ecs_cpp_last_member(
const ecs_world_t *world,
ecs_entity_t type);
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif
#ifdef __cplusplus
#pragma once
#include <type_traits>
namespace flecs
{
struct world;
struct world_async_stage;
struct iter;
struct entity_view;
struct entity;
struct type;
struct table;
struct table_range;
struct untyped_component;
template <typename T>
struct component;
namespace _
{
template <typename T, typename U = int>
struct cpp_type;
template <typename Func, typename ... Components>
struct each_invoker;
} }
#pragma once
namespace flecs {
using world_t = ecs_world_t;
using world_info_t = ecs_world_info_t;
using query_group_info_t = ecs_query_group_info_t;
using id_t = ecs_id_t;
using entity_t = ecs_entity_t;
using type_t = ecs_type_t;
using table_t = ecs_table_t;
using filter_t = ecs_filter_t;
using observer_t = ecs_observer_t;
using query_t = ecs_query_t;
using rule_t = ecs_rule_t;
using ref_t = ecs_ref_t;
using iter_t = ecs_iter_t;
using type_info_t = ecs_type_info_t;
using type_hooks_t = ecs_type_hooks_t;
using flags32_t = ecs_flags32_t;
enum inout_kind_t {
InOutDefault = EcsInOutDefault,
InOutNone = EcsInOutNone,
InOut = EcsInOut,
In = EcsIn,
Out = EcsOut
};
enum oper_kind_t {
And = EcsAnd,
Or = EcsOr,
Not = EcsNot,
Optional = EcsOptional,
AndFrom = EcsAndFrom,
OrFrom = EcsOrFrom,
NotFrom = EcsNotFrom
};
static const flecs::entity_t Pair = ECS_PAIR;
static const flecs::entity_t Override = ECS_OVERRIDE;
static const flecs::entity_t Toggle = ECS_TOGGLE;
using Component = EcsComponent;
using Identifier = EcsIdentifier;
using Poly = EcsPoly;
using Target = EcsTarget;
static const flecs::entity_t Query = EcsQuery;
static const flecs::entity_t Observer = EcsObserver;
static const flecs::entity_t Private = EcsPrivate;
static const flecs::entity_t Module = EcsModule;
static const flecs::entity_t Prefab = EcsPrefab;
static const flecs::entity_t Disabled = EcsDisabled;
static const flecs::entity_t Empty = EcsEmpty;
static const flecs::entity_t Monitor = EcsMonitor;
static const flecs::entity_t System = EcsSystem;
static const flecs::entity_t Pipeline = ecs_id(EcsPipeline);
static const flecs::entity_t Phase = EcsPhase;
static const flecs::entity_t OnAdd = EcsOnAdd;
static const flecs::entity_t OnRemove = EcsOnRemove;
static const flecs::entity_t OnSet = EcsOnSet;
static const flecs::entity_t UnSet = EcsUnSet;
static const flecs::entity_t OnTableCreate = EcsOnTableCreate;
static const flecs::entity_t OnTableDelete = EcsOnTableDelete;
static const uint32_t Self = EcsSelf;
static const uint32_t Up = EcsUp;
static const uint32_t Down = EcsDown;
static const uint32_t Cascade = EcsCascade;
static const uint32_t Parent = EcsParent;
static const uint32_t IsVariable = EcsIsVariable;
static const uint32_t IsEntity = EcsIsEntity;
static const uint32_t Filter = EcsFilter;
static const uint32_t TraverseFlags = EcsTraverseFlags;
static const flecs::entity_t Flecs = EcsFlecs;
static const flecs::entity_t FlecsCore = EcsFlecsCore;
static const flecs::entity_t World = EcsWorld;
static const flecs::entity_t Wildcard = EcsWildcard;
static const flecs::entity_t Any = EcsAny;
static const flecs::entity_t This = EcsThis;
static const flecs::entity_t Transitive = EcsTransitive;
static const flecs::entity_t Reflexive = EcsReflexive;
static const flecs::entity_t Final = EcsFinal;
static const flecs::entity_t DontInherit = EcsDontInherit;
static const flecs::entity_t Tag = EcsTag;
static const flecs::entity_t Union = EcsUnion;
static const flecs::entity_t Exclusive = EcsExclusive;
static const flecs::entity_t Acyclic = EcsAcyclic;
static const flecs::entity_t Traversable = EcsTraversable;
static const flecs::entity_t Symmetric = EcsSymmetric;
static const flecs::entity_t With = EcsWith;
static const flecs::entity_t OneOf = EcsOneOf;
static const flecs::entity_t IsA = EcsIsA;
static const flecs::entity_t ChildOf = EcsChildOf;
static const flecs::entity_t DependsOn = EcsDependsOn;
static const flecs::entity_t SlotOf = EcsSlotOf;
static const flecs::entity_t Name = EcsName;
static const flecs::entity_t Symbol = EcsSymbol;
static const flecs::entity_t OnDelete = EcsOnDelete;
static const flecs::entity_t OnDeleteTarget = EcsOnDeleteTarget;
static const flecs::entity_t Remove = EcsRemove;
static const flecs::entity_t Delete = EcsDelete;
static const flecs::entity_t Panic = EcsPanic;
static const flecs::entity_t Flatten = EcsFlatten;
static const flecs::entity_t DefaultChildComponent = EcsDefaultChildComponent;
static const flecs::entity_t PredEq = EcsPredEq;
static const flecs::entity_t PredMatch = EcsPredMatch;
static const flecs::entity_t PredLookup = EcsPredLookup;
static const flecs::entity_t ScopeOpen = EcsScopeOpen;
static const flecs::entity_t ScopeClose = EcsScopeClose;
}
#define FLECS_PLACEMENT_NEW(_ptr, _type) ::new(flecs::_::placement_new_tag, _ptr) _type
#define FLECS_NEW(_type) FLECS_PLACEMENT_NEW(ecs_os_malloc(sizeof(_type)), _type)
#define FLECS_DELETE(_ptr) \
do { \
if (_ptr) { \
flecs::_::destruct_obj(_ptr); \
ecs_os_free(_ptr); \
} \
} while (false)
#define FLECS_MOV(...) \
static_cast<flecs::remove_reference_t<decltype(__VA_ARGS__)>&&>(__VA_ARGS__)
#define FLECS_FWD(...) \
static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
namespace flecs
{
namespace _
{
struct placement_new_tag_t{};
constexpr placement_new_tag_t placement_new_tag{};
template<class Ty> inline void destruct_obj(Ty* _ptr) { _ptr->~Ty(); }
template<class Ty> inline void free_obj(Ty* _ptr) {
if (_ptr) {
destruct_obj(_ptr);
ecs_os_free(_ptr);
}
}
}
}
#ifndef flecs_static_assert
#define flecs_static_assert(cond, str) static_assert(cond, str)
#endif
inline void* operator new(size_t, flecs::_::placement_new_tag_t, void* _ptr) noexcept { return _ptr; }
inline void operator delete(void*, flecs::_::placement_new_tag_t, void*) noexcept { }
namespace flecs
{
template <bool V, typename T, typename F>
using conditional_t = typename std::conditional<V, T, F>::type;
template <typename T>
using decay_t = typename std::decay<T>::type;
template <bool V, typename T = void>
using enable_if_t = typename std::enable_if<V, T>::type;
template <typename T>
using remove_pointer_t = typename std::remove_pointer<T>::type;
template <typename T>
using remove_reference_t = typename std::remove_reference<T>::type;
using std::is_base_of;
using std::is_empty;
using std::is_const;
using std::is_pointer;
using std::is_reference;
using std::is_volatile;
using std::is_same;
using std::is_enum;
template <typename T>
using is_const_p = is_const< remove_pointer_t<T> >;
template<class Src, class Dst>
using transcribe_const_t = conditional_t<is_const<Src>::value, Dst const, Dst>;
template<class Src, class Dst>
using transcribe_volatile_t = conditional_t<is_volatile<Src>::value, Dst volatile, Dst>;
template<class Src, class Dst>
using transcribe_cv_t = transcribe_const_t< Src, transcribe_volatile_t< Src, Dst> >;
template <bool V>
using if_t = enable_if_t<V, int>;
template <bool V>
using if_not_t = enable_if_t<false == V, int>;
namespace _
{
template <class... T>
struct always_false {
static const bool value = false;
};
}
}
#include <stdlib.h>
namespace flecs {
template <typename T>
struct array_iterator
{
explicit array_iterator(T* value, int index) {
m_value = value;
m_index = index;
}
bool operator!=(array_iterator const& other) const
{
return m_index != other.m_index;
}
T & operator*() const
{
return m_value[m_index];
}
array_iterator& operator++()
{
++m_index;
return *this;
}
private:
T* m_value;
int m_index;
};
template <typename T, size_t Size, class Enable = void>
struct array final { };
template <typename T, size_t Size>
struct array<T, Size, enable_if_t<Size != 0> > final {
array() {};
array(const T (&elems)[Size]) {
int i = 0;
for (auto it = this->begin(); it != this->end(); ++ it) {
*it = elems[i ++];
}
}
T& operator[](int index) {
return m_array[index];
}
T& operator[](size_t index) {
return m_array[index];
}
array_iterator<T> begin() {
return array_iterator<T>(m_array, 0);
}
array_iterator<T> end() {
return array_iterator<T>(m_array, Size);
}
size_t size() {
return Size;
}
T* ptr() {
return m_array;
}
template <typename Func>
void each(const Func& func) {
for (auto& elem : *this) {
func(elem);
}
}
private:
T m_array[Size];
};
template<typename T, size_t Size>
array<T, Size> to_array(const T (&elems)[Size]) {
return array<T, Size>(elems);
}
template <typename T, size_t Size>
struct array<T, Size, enable_if_t<Size == 0>> final {
array() {};
array(const T* (&elems)) { (void)elems; }
T operator[](size_t index) { ecs_os_abort(); (void)index; return T(); }
array_iterator<T> begin() { return array_iterator<T>(nullptr, 0); }
array_iterator<T> end() { return array_iterator<T>(nullptr, 0); }
size_t size() {
return 0;
}
T* ptr() {
return NULL;
}
};
}
namespace flecs {
struct string_view;
struct string {
explicit string()
: m_str(nullptr)
, m_const_str("")
, m_length(0) { }
explicit string(char *str)
: m_str(str)
, m_const_str(str ? str : "")
, m_length(str ? ecs_os_strlen(str) : 0) { }
~string() {
if (m_str) {
ecs_os_free(m_str);
}
}
string(string&& str) {
ecs_os_free(m_str);
m_str = str.m_str;
m_const_str = str.m_const_str;
m_length = str.m_length;
str.m_str = nullptr;
}
operator const char*() const {
return m_const_str;
}
string& operator=(string&& str) {
ecs_os_free(m_str);
m_str = str.m_str;
m_const_str = str.m_const_str;
m_length = str.m_length;
str.m_str = nullptr;
return *this;
}
string& operator=(const string& str) = delete;
string(const string& str) = delete;
bool operator==(const flecs::string& str) const {
if (str.m_const_str == m_const_str) {
return true;
}
if (!m_const_str || !str.m_const_str) {
return false;
}
if (str.m_length != m_length) {
return false;
}
return ecs_os_strcmp(str, m_const_str) == 0;
}
bool operator!=(const flecs::string& str) const {
return !(*this == str);
}
bool operator==(const char *str) const {
if (m_const_str == str) {
return true;
}
if (!m_const_str || !str) {
return false;
}
return ecs_os_strcmp(str, m_const_str) == 0;
}
bool operator!=(const char *str) const {
return !(*this == str);
}
const char* c_str() const {
return m_const_str;
}
std::size_t length() const {
return static_cast<std::size_t>(m_length);
}
template <size_t N>
static constexpr size_t length( char const (&)[N] ) {
return N - 1;
}
std::size_t size() const {
return length();
}
void clear() {
ecs_os_free(m_str);
m_str = nullptr;
m_const_str = nullptr;
}
protected:
string(const char *str)
: m_str(nullptr)
, m_const_str(str ? str : "")
, m_length(str ? ecs_os_strlen(str) : 0) { }
char *m_str = nullptr;
const char *m_const_str;
ecs_size_t m_length;
};
struct string_view : string {
explicit string_view(const char *str)
: string(str) { }
};
}
#include <string.h>
#define FLECS_ENUM_MAX(T) _::to_constant<T, 128>::value
#define FLECS_ENUM_MAX_COUNT (FLECS_ENUM_MAX(int) + 1)
#ifndef FLECS_CPP_ENUM_REFLECTION_SUPPORT
#if !defined(__clang__) && defined(__GNUC__)
#if __GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ >= 5)
#define FLECS_CPP_ENUM_REFLECTION_SUPPORT 1
#else
#define FLECS_CPP_ENUM_REFLECTION_SUPPORT 0
#endif
#else
#define FLECS_CPP_ENUM_REFLECTION_SUPPORT 1
#endif
#endif
namespace flecs {
namespace _ {
template <typename E, int Value>
struct to_constant {
#if defined(__clang__) && __clang_major__ >= 16
static constexpr E value = __builtin_bit_cast(E, Value);
#else
static constexpr E value = static_cast<E>(Value);
#endif
};
template <typename E, int Value>
constexpr E to_constant<E, Value>::value;
}
template <typename E>
struct enum_data;
template <typename E>
static enum_data<E> enum_type(flecs::world_t *world);
template <typename E>
struct enum_last {
static constexpr E value = FLECS_ENUM_MAX(E);
};
#define FLECS_ENUM_LAST(T, Last)\
namespace flecs {\
template<>\
struct enum_last<T> {\
static constexpr T value = Last;\
};\
}
namespace _ {
#if INTPTR_MAX == INT64_MAX
#ifdef ECS_TARGET_MSVC
#if _MSC_VER >= 1930
#define ECS_SIZE_T_STR "unsigned __int64"
#else
#define ECS_SIZE_T_STR "unsigned int"
#endif
#elif defined(__clang__)
#define ECS_SIZE_T_STR "size_t"
#else
#ifdef ECS_TARGET_WINDOWS
#define ECS_SIZE_T_STR "constexpr size_t; size_t = long long unsigned int"
#else
#define ECS_SIZE_T_STR "constexpr size_t; size_t = long unsigned int"
#endif
#endif
#else
#ifdef ECS_TARGET_MSVC
#if _MSC_VER >= 1930
#define ECS_SIZE_T_STR "unsigned __int32"
#else
#define ECS_SIZE_T_STR "unsigned int"
#endif
#elif defined(__clang__)
#define ECS_SIZE_T_STR "size_t"
#else
#ifdef ECS_TARGET_WINDOWS
#define ECS_SIZE_T_STR "constexpr size_t; size_t = unsigned int"
#else
#define ECS_SIZE_T_STR "constexpr size_t; size_t = unsigned int"
#endif
#endif
#endif
template <typename E>
constexpr size_t enum_type_len() {
return ECS_FUNC_TYPE_LEN(, enum_type_len, ECS_FUNC_NAME)
- (sizeof(ECS_SIZE_T_STR) - 1u);
}
#if defined(ECS_TARGET_CLANG)
#if ECS_CLANG_VERSION < 13
template <typename E, E C>
constexpr bool enum_constant_is_valid() {
return !(
(ECS_FUNC_NAME[ECS_FUNC_NAME_FRONT(bool, enum_constant_is_valid) +
enum_type_len<E>() + 6 ] >= '0') &&
(ECS_FUNC_NAME[ECS_FUNC_NAME_FRONT(bool, enum_constant_is_valid) +
enum_type_len<E>() + 6 ] <= '9'));
}
#else
template <typename E, E C>
constexpr bool enum_constant_is_valid() {
return (ECS_FUNC_NAME[ECS_FUNC_NAME_FRONT(bool, enum_constant_is_valid) +
enum_type_len<E>() + 6 ] != '(');
}
#endif
#elif defined(ECS_TARGET_GNU)
template <typename E, E C>
constexpr bool enum_constant_is_valid() {
return (ECS_FUNC_NAME[ECS_FUNC_NAME_FRONT(constepxr bool, enum_constant_is_valid) +
enum_type_len<E>() + 8 ] != '(');
}
#else
template <typename E, E C>
constexpr bool enum_constant_is_valid() {
return ECS_FUNC_NAME[ECS_FUNC_NAME_FRONT(bool, enum_constant_is_valid) +
enum_type_len<E>() + 1] != '(';
}
#endif
template <typename E, E C>
struct enum_is_valid {
static constexpr bool value = enum_constant_is_valid<E, C>();
};
template <typename E, E C>
static const char* enum_constant_to_name() {
static const size_t len = ECS_FUNC_TYPE_LEN(const char*, enum_constant_to_name, ECS_FUNC_NAME);
static char result[len + 1] = {};
return ecs_cpp_get_constant_name(
result, ECS_FUNC_NAME, string::length(ECS_FUNC_NAME),
ECS_FUNC_NAME_BACK);
}
struct enum_constant_data {
flecs::entity_t id;
int next;
};
struct enum_data_impl {
flecs::entity_t id;
int min;
int max;
enum_constant_data constants[FLECS_ENUM_MAX_COUNT];
};
template <typename E>
struct enum_type {
static enum_data_impl data;
static enum_type<E>& get() {
static _::enum_type<E> instance;
return instance;
}
flecs::entity_t entity(E value) const {
return data.constants[static_cast<int>(value)].id;
}
void init(flecs::world_t *world, flecs::entity_t id) {
#if !FLECS_CPP_ENUM_REFLECTION_SUPPORT
ecs_abort(ECS_UNSUPPORTED, "enum reflection requires gcc 7.5 or higher")
#endif
ecs_log_push();
ecs_cpp_enum_init(world, id);
data.id = id;
data.min = FLECS_ENUM_MAX(int);
init< enum_last<E>::value >(world);
ecs_log_pop();
}
private:
template <E Value>
static constexpr int to_int() {
return static_cast<int>(Value);
}
template <int Value>
static constexpr E from_int() {
return to_constant<E, Value>::value;
}
template <E Value>
static constexpr int is_not_0() {
return static_cast<int>(Value != from_int<0>());
}
template <E Value, flecs::if_not_t< enum_constant_is_valid<E, Value>() > = 0>
static void init_constant(flecs::world_t*) { }
template <E Value, flecs::if_t< enum_constant_is_valid<E, Value>() > = 0>
static void init_constant(flecs::world_t *world) {
int v = to_int<Value>();
const char *name = enum_constant_to_name<E, Value>();
data.constants[v].next = data.min;
data.min = v;
if (!data.max) {
data.max = v;
}
data.constants[v].id = ecs_cpp_enum_constant_register(
world, data.id, data.constants[v].id, name, v);
}
template <E Value = FLECS_ENUM_MAX(E) >
static void init(flecs::world_t *world) {
init_constant<Value>(world);
if (is_not_0<Value>()) {
init<from_int<to_int<Value>() - is_not_0<Value>()>()>(world);
}
}
};
template <typename E>
enum_data_impl enum_type<E>::data;
template <typename E, if_t< is_enum<E>::value > = 0>
inline static void init_enum(flecs::world_t *world, flecs::entity_t id) {
_::enum_type<E>::get().init(world, id);
}
template <typename E, if_not_t< is_enum<E>::value > = 0>
inline static void init_enum(flecs::world_t*, flecs::entity_t) { }
}
template <typename E>
struct enum_data {
enum_data(flecs::world_t *world, _::enum_data_impl& impl)
: world_(world)
, impl_(impl) { }
bool is_valid(int value) {
return impl_.constants[value].id != 0;
}
int first() const {
return impl_.min;
}
int last() const {
return impl_.max;
}
int next(int cur) const {
return impl_.constants[cur].next;
}
flecs::entity entity() const;
flecs::entity entity(int value) const;
flecs::entity entity(E value) const;
flecs::world_t *world_;
_::enum_data_impl& impl_;
};
template <typename E>
enum_data<E> enum_type(flecs::world_t *world) {
_::cpp_type<E>::id(world); auto& ref = _::enum_type<E>::get();
return enum_data<E>(world, ref.data);
}
}
namespace flecs {
struct stringstream {
explicit stringstream()
: m_buf({}) { }
~stringstream() {
ecs_strbuf_reset(&m_buf);
}
stringstream(stringstream&& str) {
ecs_strbuf_reset(&m_buf);
m_buf = str.m_buf;
str.m_buf = {};
}
stringstream& operator=(stringstream&& str) {
ecs_strbuf_reset(&m_buf);
m_buf = str.m_buf;
str.m_buf = {};
return *this;
}
stringstream& operator=(const stringstream& str) = delete;
stringstream(const stringstream& str) = delete;
stringstream& operator<<(const char* str) {
ecs_strbuf_appendstr(&m_buf, str);
return *this;
}
flecs::string str() {
return flecs::string(ecs_strbuf_get(&m_buf));
}
private:
ecs_strbuf_t m_buf;
};
}
namespace flecs {
namespace _ {
template <typename ... Args>
struct arg_list { };
template <typename ReturnType, typename... Args>
struct function_traits_defs
{
static constexpr bool is_callable = true;
static constexpr size_t arity = sizeof...(Args);
using return_type = ReturnType;
using args = arg_list<Args ...>;
};
template <typename T>
struct function_traits_impl {
static constexpr bool is_callable = false;
};
template <typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(Args...)>
: function_traits_defs<ReturnType, Args...> {};
template <typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(*)(Args...)>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...)>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) const>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) const&>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) const&&>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile&>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile&&>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile&>
: function_traits_defs<ReturnType, Args...> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile&&>
: function_traits_defs<ReturnType, Args...> {};
template <typename T, typename V = void>
struct function_traits_no_cv
: function_traits_impl<T> {};
template <typename T>
struct function_traits_no_cv<T, decltype((void)&T::operator())>
: function_traits_impl<decltype(&T::operator())> {};
template <typename T>
struct function_traits
: function_traits_no_cv< decay_t<T> > {};
}
template <typename T>
struct is_callable {
static constexpr bool value = _::function_traits<T>::is_callable;
};
template <typename T>
struct arity {
static constexpr int value = _::function_traits<T>::arity;
};
template <typename T>
using return_type_t = typename _::function_traits<T>::return_type;
template <typename T>
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;
}
#pragma once
namespace flecs {
struct id;
struct entity;
struct id {
id()
: m_world(nullptr)
, m_id(0) { }
explicit id(flecs::id_t value)
: m_world(nullptr)
, m_id(value) { }
explicit id(flecs::world_t *world, flecs::id_t value = 0)
: m_world(world)
, m_id(value) { }
explicit id(flecs::world_t *world, flecs::id_t first, flecs::id_t second)
: m_world(world)
, m_id(ecs_pair(first, second)) { }
explicit id(flecs::id_t first, flecs::id_t second)
: m_world(nullptr)
, m_id(ecs_pair(first, second)) { }
explicit id(const flecs::id& first, const flecs::id& second)
: m_world(first.m_world)
, m_id(ecs_pair(first.m_id, second.m_id)) { }
bool is_pair() const {
return (m_id & ECS_ID_FLAGS_MASK) == flecs::Pair;
}
bool is_wildcard() const {
return ecs_id_is_wildcard(m_id);
}
bool is_entity() const {
return !(m_id & ECS_ID_FLAGS_MASK);
}
flecs::entity entity() const;
flecs::entity add_flags(flecs::id_t flags) const;
flecs::entity remove_flags(flecs::id_t flags) const;
flecs::entity remove_flags() const;
flecs::entity remove_generation() const;
flecs::entity type_id() const;
bool has_flags(flecs::id_t flags) const {
return ((m_id & flags) == flags);
}
bool has_flags() const {
return (m_id & ECS_ID_FLAGS_MASK) != 0;
}
flecs::entity flags() const;
bool has_relation(flecs::id_t first) const {
if (!is_pair()) {
return false;
}
return ECS_PAIR_FIRST(m_id) == first;
}
flecs::entity first() const;
flecs::entity second() const;
flecs::string str() const {
return flecs::string(ecs_id_str(m_world, m_id));
}
flecs::string flags_str() const {
return flecs::string_view( ecs_id_flag_str(m_id & ECS_ID_FLAGS_MASK));
}
flecs::id_t raw_id() const {
return m_id;
}
operator flecs::id_t() const {
return m_id;
}
flecs::world world() const;
protected:
flecs::world_t *m_world;
flecs::id_t m_id;
};
}
#pragma once
namespace flecs {
struct term;
struct term_builder;
}
#pragma once
namespace flecs {
struct filter_base;
template<typename ... Components>
struct filter;
template<typename ... Components>
struct filter_builder;
}
#pragma once
#pragma once
#define ECS_EVENT_DESC_ID_COUNT_MAX (8)
namespace flecs {
template <typename Base, typename E>
struct event_builder_base {
event_builder_base(flecs::world_t *world, flecs::entity_t event)
: m_world(world)
, m_desc{}
, m_ids{}
, m_ids_array{}
{
m_desc.event = event;
}
template <typename T>
Base& id() {
m_ids.array = m_ids_array;
m_ids.array[m_ids.count] = _::cpp_type<T>().id(m_world);
m_ids.count ++;
return *this;
}
template <typename First, typename Second>
Base& id() {
return id(
ecs_pair(_::cpp_type<First>::id(this->m_world),
_::cpp_type<Second>::id(this->m_world)));
}
template <typename First>
Base& id(entity_t second) {
return id(ecs_pair(_::cpp_type<First>::id(this->m_world), second));
}
Base& id(entity_t first, entity_t second) {
return id(ecs_pair(first, second));
}
Base& id(flecs::id_t id) {
m_ids.array = m_ids_array;
m_ids.array[m_ids.count] = id;
m_ids.count ++;
return *this;
}
Base& entity(flecs::entity_t e) {
ecs_record_t *r = ecs_record_find(m_world, e);
ecs_assert(r != nullptr, ECS_INVALID_PARAMETER, nullptr);
ecs_assert(r->table != nullptr, ECS_INVALID_PARAMETER, nullptr);
m_desc.table = r->table;
m_desc.offset = ECS_RECORD_TO_ROW(r->row);
m_desc.count = 1;
return *this;
}
Base& table(flecs::table_t *t, int32_t offset = 0, int32_t count = 0) {
m_desc.table = t;
m_desc.offset = offset;
m_desc.count = count;
return *this;
}
Base& ctx(const E* ptr) {
m_desc.param = ptr;
return *this;
}
void emit() {
ecs_assert(m_ids.count != 0, ECS_INVALID_PARAMETER, NULL);
ecs_assert(m_desc.table != nullptr, ECS_INVALID_PARAMETER, NULL);
m_ids.array = m_ids_array;
m_desc.ids = &m_ids;
m_desc.observable = const_cast<flecs::world_t*>(ecs_get_world(m_world));
ecs_emit(m_world, &m_desc);
}
protected:
flecs::world_t *m_world;
ecs_event_desc_t m_desc;
flecs::type_t m_ids;
flecs::id_t m_ids_array[ECS_EVENT_DESC_ID_COUNT_MAX];
private:
operator Base&() {
return *static_cast<Base*>(this);
}
};
struct event_builder : event_builder_base<event_builder, void> {
using event_builder_base::event_builder_base;
};
template <typename E>
struct event_builder_typed : event_builder_base<event_builder_typed<E>, E> {
private:
using Class = event_builder_typed<E>;
public:
using event_builder_base<Class, E>::event_builder_base;
Class& ctx(const E& ptr) {
this->m_desc.param = &ptr;
return *this;
}
};
}
#pragma once
namespace flecs {
struct query_base;
template<typename ... Components>
struct query;
template<typename ... Components>
struct query_builder;
}
#pragma once
namespace flecs {
struct observer;
template<typename ... Components>
struct observer_builder;
}
#ifdef FLECS_SYSTEM
#pragma once
namespace flecs {
using TickSource = EcsTickSource;
struct system;
template<typename ... Components>
struct system_builder;
namespace _ {
void system_init(flecs::world& world);
} }
#endif
#ifdef FLECS_PIPELINE
#pragma once
namespace flecs {
template <typename ... Components>
struct pipeline;
template <typename ... Components>
struct pipeline_builder;
static const flecs::entity_t OnStart = EcsOnStart;
static const flecs::entity_t PreFrame = EcsPreFrame;
static const flecs::entity_t OnLoad = EcsOnLoad;
static const flecs::entity_t PostLoad = EcsPostLoad;
static const flecs::entity_t PreUpdate = EcsPreUpdate;
static const flecs::entity_t OnUpdate = EcsOnUpdate;
static const flecs::entity_t OnValidate = EcsOnValidate;
static const flecs::entity_t PostUpdate = EcsPostUpdate;
static const flecs::entity_t PreStore = EcsPreStore;
static const flecs::entity_t OnStore = EcsOnStore;
static const flecs::entity_t PostFrame = EcsPostFrame;
}
#endif
#ifdef FLECS_TIMER
#pragma once
namespace flecs {
using Timer = EcsTimer;
using RateFilter = EcsRateFilter;
struct timer;
namespace _ {
void timer_init(flecs::world& world);
} }
#endif
#ifdef FLECS_SNAPSHOT
#pragma once
namespace flecs {
using snapshot_t = ecs_snapshot_t;
struct snapshot;
}
#endif
#ifdef FLECS_DOC
#pragma once
namespace flecs {
namespace doc {
using Description = EcsDocDescription;
static const flecs::entity_t Brief = EcsDocBrief;
static const flecs::entity_t Detail = EcsDocDetail;
static const flecs::entity_t Link = EcsDocLink;
static const flecs::entity_t Color = EcsDocColor;
namespace _ {
void init(flecs::world& world);
}
}
}
#endif
#ifdef FLECS_REST
#pragma once
namespace flecs {
using Rest = EcsRest;
namespace rest {
namespace _ {
void init(flecs::world& world);
}
}
}
#endif
#ifdef FLECS_RULES
#pragma once
namespace flecs {
struct rule_base;
template<typename ... Components>
struct rule;
template<typename ... Components>
struct rule_builder;
}
#endif
#ifdef FLECS_META
#pragma once
namespace flecs {
using bool_t = ecs_bool_t;
using char_t = ecs_char_t;
using u8_t = ecs_u8_t;
using u16_t = ecs_u16_t;
using u32_t = ecs_u32_t;
using u64_t = ecs_u64_t;
using uptr_t = ecs_uptr_t;
using i8_t = ecs_i8_t;
using i16_t = ecs_i16_t;
using i32_t = ecs_i32_t;
using i64_t = ecs_i64_t;
using iptr_t = ecs_iptr_t;
using f32_t = ecs_f32_t;
using f64_t = ecs_f64_t;
using member_t = ecs_member_t;
using enum_constant_t = ecs_enum_constant_t;
using bitmask_constant_t = ecs_bitmask_constant_t;
using MetaType = EcsMetaType;
using MetaTypeSerialized = EcsMetaTypeSerialized;
using Primitive = EcsPrimitive;
using Enum = EcsEnum;
using Bitmask = EcsBitmask;
using Member = EcsMember;
using MemberRanges = EcsMemberRanges;
using Struct = EcsStruct;
using Array = EcsArray;
using Vector = EcsVector;
using Unit = EcsUnit;
struct bitmask {
uint32_t value;
};
static const flecs::entity_t Bool = ecs_id(ecs_bool_t);
static const flecs::entity_t Char = ecs_id(ecs_char_t);
static const flecs::entity_t Byte = ecs_id(ecs_byte_t);
static const flecs::entity_t U8 = ecs_id(ecs_u8_t);
static const flecs::entity_t U16 = ecs_id(ecs_u16_t);
static const flecs::entity_t U32 = ecs_id(ecs_u32_t);
static const flecs::entity_t U64 = ecs_id(ecs_u64_t);
static const flecs::entity_t Uptr = ecs_id(ecs_uptr_t);
static const flecs::entity_t I8 = ecs_id(ecs_i8_t);
static const flecs::entity_t I16 = ecs_id(ecs_i16_t);
static const flecs::entity_t I32 = ecs_id(ecs_i32_t);
static const flecs::entity_t I64 = ecs_id(ecs_i64_t);
static const flecs::entity_t Iptr = ecs_id(ecs_iptr_t);
static const flecs::entity_t F32 = ecs_id(ecs_f32_t);
static const flecs::entity_t F64 = ecs_id(ecs_f64_t);
static const flecs::entity_t String = ecs_id(ecs_string_t);
static const flecs::entity_t Entity = ecs_id(ecs_entity_t);
static const flecs::entity_t Constant = EcsConstant;
static const flecs::entity_t Quantity = EcsQuantity;
namespace meta {
using type_kind_t = ecs_type_kind_t;
static const type_kind_t PrimitiveType = EcsPrimitiveType;
static const type_kind_t BitmaskType = EcsBitmaskType;
static const type_kind_t EnumType = EcsEnumType;
static const type_kind_t StructType = EcsStructType;
static const type_kind_t ArrayType = EcsArrayType;
static const type_kind_t VectorType = EcsVectorType;
static const type_kind_t CustomType = EcsOpaqueType;
static const type_kind_t TypeKindLast = EcsTypeKindLast;
using primitive_kind_t = ecs_primitive_kind_t;
static const primitive_kind_t Bool = EcsBool;
static const primitive_kind_t Char = EcsChar;
static const primitive_kind_t Byte = EcsByte;
static const primitive_kind_t U8 = EcsU8;
static const primitive_kind_t U16 = EcsU16;
static const primitive_kind_t U32 = EcsU32;
static const primitive_kind_t U64 = EcsU64;
static const primitive_kind_t I8 = EcsI8;
static const primitive_kind_t I16 = EcsI16;
static const primitive_kind_t I32 = EcsI32;
static const primitive_kind_t I64 = EcsI64;
static const primitive_kind_t F32 = EcsF32;
static const primitive_kind_t F64 = EcsF64;
static const primitive_kind_t UPtr = EcsUPtr;
static const primitive_kind_t IPtr = EcsIPtr;
static const primitive_kind_t String = EcsString;
static const primitive_kind_t Entity = EcsEntity;
static const primitive_kind_t PrimitiveKindLast = EcsPrimitiveKindLast;
namespace _ {
void init(flecs::world& world);
} } }
#pragma once
namespace flecs {
struct cursor {
cursor(flecs::world_t *world, flecs::entity_t type_id, void *ptr) {
m_cursor = ecs_meta_cursor(world, type_id, ptr);
}
int push() {
return ecs_meta_push(&m_cursor);
}
int pop() {
return ecs_meta_pop(&m_cursor);
}
int next() {
return ecs_meta_next(&m_cursor);
}
int member(const char *name) {
return ecs_meta_member(&m_cursor, name);
}
int elem(int32_t elem) {
return ecs_meta_elem(&m_cursor, elem);
}
bool is_collection() {
return ecs_meta_is_collection(&m_cursor);
}
flecs::string_view get_member() const {
return flecs::string_view(ecs_meta_get_member(&m_cursor));
}
flecs::entity get_type() const;
flecs::entity get_unit() const;
void* get_ptr() {
return ecs_meta_get_ptr(&m_cursor);
}
int set_bool(bool value) {
return ecs_meta_set_bool(&m_cursor, value);
}
int set_char(char value) {
return ecs_meta_set_char(&m_cursor, value);
}
int set_int(int64_t value) {
return ecs_meta_set_int(&m_cursor, value);
}
int set_uint(uint64_t value) {
return ecs_meta_set_uint(&m_cursor, value);
}
int set_float(double value) {
return ecs_meta_set_float(&m_cursor, value);
}
int set_string(const char *value) {
return ecs_meta_set_string(&m_cursor, value);
}
int set_string_literal(const char *value) {
return ecs_meta_set_string_literal(&m_cursor, value);
}
int set_entity(flecs::entity_t value) {
return ecs_meta_set_entity(&m_cursor, value);
}
int set_null() {
return ecs_meta_set_null(&m_cursor);
}
bool get_bool() const {
return ecs_meta_get_bool(&m_cursor);
}
char get_char() const {
return ecs_meta_get_char(&m_cursor);
}
int64_t get_int() const {
return ecs_meta_get_int(&m_cursor);
}
uint64_t get_uint() const {
return ecs_meta_get_uint(&m_cursor);
}
double get_float() const {
return ecs_meta_get_float(&m_cursor);
}
const char *get_string() const {
return ecs_meta_get_string(&m_cursor);
}
flecs::entity get_entity() const;
ecs_meta_cursor_t m_cursor;
};
}
#pragma once
#include <stdio.h>
namespace flecs {
using serializer = ecs_serializer_t;
using serialize_t = ecs_meta_serialize_t;
template <typename T>
using serialize = int(*)(const serializer *, const T*);
template <typename T, typename ElemType = void>
struct opaque {
opaque(flecs::world_t *w = nullptr) : world(w) {
if (world) {
desc.entity = _::cpp_type<T>::id(world);
}
}
opaque& as_type(flecs::id_t func) {
this->desc.type.as_type = func;
return *this;
}
opaque& serialize(flecs::serialize<T> func) {
this->desc.type.serialize =
reinterpret_cast<decltype(
this->desc.type.serialize)>(func);
return *this;
}
opaque& assign_bool(void (*func)(T *dst, bool value)) {
this->desc.type.assign_bool =
reinterpret_cast<decltype(
this->desc.type.assign_bool)>(func);
return *this;
}
opaque& assign_char(void (*func)(T *dst, char value)) {
this->desc.type.assign_char =
reinterpret_cast<decltype(
this->desc.type.assign_char)>(func);
return *this;
}
opaque& assign_int(void (*func)(T *dst, int64_t value)) {
this->desc.type.assign_int =
reinterpret_cast<decltype(
this->desc.type.assign_int)>(func);
return *this;
}
opaque& assign_uint(void (*func)(T *dst, uint64_t value)) {
this->desc.type.assign_uint =
reinterpret_cast<decltype(
this->desc.type.assign_uint)>(func);
return *this;
}
opaque& assign_float(void (*func)(T *dst, double value)) {
this->desc.type.assign_float =
reinterpret_cast<decltype(
this->desc.type.assign_float)>(func);
return *this;
}
opaque& assign_string(void (*func)(T *dst, const char *value)) {
this->desc.type.assign_string =
reinterpret_cast<decltype(
this->desc.type.assign_string)>(func);
return *this;
}
opaque& assign_entity(
void (*func)(T *dst, ecs_world_t *world, ecs_entity_t entity))
{
this->desc.type.assign_entity =
reinterpret_cast<decltype(
this->desc.type.assign_entity)>(func);
return *this;
}
opaque& assign_null(void (*func)(T *dst)) {
this->desc.type.assign_null =
reinterpret_cast<decltype(
this->desc.type.assign_null)>(func);
return *this;
}
opaque& clear(void (*func)(T *dst)) {
this->desc.type.clear =
reinterpret_cast<decltype(
this->desc.type.clear)>(func);
return *this;
}
opaque& ensure_element(ElemType* (*func)(T *dst, size_t elem)) {
this->desc.type.ensure_element =
reinterpret_cast<decltype(
this->desc.type.ensure_element)>(func);
return *this;
}
opaque& ensure_member(void* (*func)(T *dst, const char *member)) {
this->desc.type.ensure_member =
reinterpret_cast<decltype(
this->desc.type.ensure_member)>(func);
return *this;
}
opaque& count(size_t (*func)(const T *dst)) {
this->desc.type.count =
reinterpret_cast<decltype(
this->desc.type.count)>(func);
return *this;
}
opaque& resize(void (*func)(T *dst, size_t count)) {
this->desc.type.resize =
reinterpret_cast<decltype(
this->desc.type.resize)>(func);
return *this;
}
~opaque() {
if (world) {
ecs_opaque_init(world, &desc);
}
}
flecs::world_t *world = nullptr;
ecs_opaque_desc_t desc = {};
};
}
#endif
#ifdef FLECS_UNITS
#pragma once
namespace flecs {
struct units {
struct Prefixes { };
struct Yocto { };
struct Zepto { };
struct Atto { };
struct Femto { };
struct Pico { };
struct Nano { };
struct Micro { };
struct Milli { };
struct Centi { };
struct Deci { };
struct Deca { };
struct Hecto { };
struct Kilo { };
struct Mega { };
struct Giga { };
struct Tera { };
struct Peta { };
struct Exa { };
struct Zetta { };
struct Yotta { };
struct Kibi { };
struct Mebi { };
struct Gibi { };
struct Tebi { };
struct Pebi { };
struct Exbi { };
struct Zebi { };
struct Yobi { };
struct Duration { };
struct Time { };
struct Mass { };
struct ElectricCurrent { };
struct LuminousIntensity { };
struct Force { };
struct Amount { };
struct Length { };
struct Pressure { };
struct Speed { };
struct Temperature { };
struct Data { };
struct DataRate { };
struct Angle { };
struct Frequency { };
struct Uri { };
struct duration {
struct PicoSeconds { };
struct NanoSeconds { };
struct MicroSeconds { };
struct MilliSeconds { };
struct Seconds { };
struct Minutes { };
struct Hours { };
struct Days { };
};
struct angle {
struct Radians { };
struct Degrees { };
};
struct time {
struct Date { };
};
struct mass {
struct Grams { };
struct KiloGrams { };
};
struct electric_current {
struct Ampere { };
};
struct amount {
struct Mole { };
};
struct luminous_intensity {
struct Candela { };
};
struct force {
struct Newton { };
};
struct length {
struct Meters { };
struct PicoMeters { };
struct NanoMeters { };
struct MicroMeters { };
struct MilliMeters { };
struct CentiMeters { };
struct KiloMeters { };
struct Miles { };
struct Pixels { };
};
struct pressure {
struct Pascal { };
struct Bar { };
};
struct speed {
struct MetersPerSecond { };
struct KiloMetersPerSecond { };
struct KiloMetersPerHour { };
struct MilesPerHour { };
};
struct temperature {
struct Kelvin { };
struct Celsius { };
struct Fahrenheit { };
};
struct data {
struct Bits { };
struct KiloBits { };
struct MegaBits { };
struct GigaBits { };
struct Bytes { };
struct KiloBytes { };
struct MegaBytes { };
struct GigaBytes { };
struct KibiBytes { };
struct MebiBytes { };
struct GibiBytes { };
};
struct datarate {
struct BitsPerSecond { };
struct KiloBitsPerSecond { };
struct MegaBitsPerSecond { };
struct GigaBitsPerSecond { };
struct BytesPerSecond { };
struct KiloBytesPerSecond { };
struct MegaBytesPerSecond { };
struct GigaBytesPerSecond { };
};
struct frequency {
struct Hertz { };
struct KiloHertz { };
struct MegaHertz { };
struct GigaHertz { };
};
struct uri {
struct Hyperlink { };
struct Image { };
struct File { };
};
struct Percentage { };
struct Bel { };
struct DeciBel { };
units(flecs::world& world);
};
}
#endif
#ifdef FLECS_MONITOR
#pragma once
namespace flecs {
using WorldStats = EcsWorldStats;
using PipelineStats = EcsPipelineStats;
struct monitor {
monitor(flecs::world& world);
};
}
#endif
#ifdef FLECS_METRICS
#pragma once
#pragma once
#define ECS_EVENT_DESC_ID_COUNT_MAX (8)
namespace flecs {
struct metric_builder {
metric_builder(flecs::world_t *world, flecs::entity_t entity)
: m_world(world)
{
m_desc.entity = entity;
}
~metric_builder();
metric_builder& member(flecs::entity_t e) {
m_desc.member = e;
return *this;
}
metric_builder& member(const char *name);
template <typename T>
metric_builder& member(const char *name);
metric_builder& dotmember(const char *name);
template <typename T>
metric_builder& dotmember(const char *name);
metric_builder& id(flecs::id_t the_id) {
m_desc.id = the_id;
return *this;
}
metric_builder& id(flecs::entity_t first, flecs::entity_t second) {
m_desc.id = ecs_pair(first, second);
return *this;
}
template <typename T>
metric_builder& id() {
return id(_::cpp_type<T>::id(m_world));
}
template <typename First>
metric_builder& id(flecs::entity_t second) {
return id(_::cpp_type<First>::id(m_world), second);
}
template <typename First, typename Second>
metric_builder& id() {
return id<First>(_::cpp_type<Second>::id(m_world));
}
metric_builder& targets(bool value = true) {
m_desc.targets = value;
return *this;
}
metric_builder& kind(flecs::entity_t the_kind) {
m_desc.kind = the_kind;
return *this;
}
template <typename Kind>
metric_builder& kind() {
return kind(_::cpp_type<Kind>::id(m_world));
}
metric_builder& brief(const char *b) {
m_desc.brief = b;
return *this;
}
operator flecs::entity();
protected:
flecs::world_t *m_world;
ecs_metric_desc_t m_desc = {};
bool m_created = false;
};
}
namespace flecs {
struct metrics {
using Value = EcsMetricValue;
using Source = EcsMetricSource;
struct Instance { };
struct Metric { };
struct Counter { };
struct CounterIncrement { };
struct CounterId { };
struct Gauge { };
metrics(flecs::world& world);
};
}
#endif
#ifdef FLECS_ALERTS
#pragma once
namespace flecs {
struct alerts {
using AlertsActive = EcsAlertsActive;
using Instance = EcsAlertInstance;
struct Alert { };
struct Info { };
struct Warning { };
struct Error { };
alerts(flecs::world& world);
};
template <typename ... Components>
struct alert;
template <typename ... Components>
struct alert_builder;
}
#endif
#ifdef FLECS_JSON
#pragma once
namespace flecs {
using from_json_desc_t = ecs_from_json_desc_t;
using entity_to_json_desc_t = ecs_entity_to_json_desc_t;
using iter_to_json_desc_t = ecs_iter_to_json_desc_t;
}
#endif
#ifdef FLECS_APP
#pragma once
#pragma once
namespace flecs {
struct app_builder {
app_builder(flecs::world_t *world)
: m_world(world)
, m_desc{}
{
const ecs_world_info_t *stats = ecs_get_world_info(world);
m_desc.target_fps = stats->target_fps;
ecs_ftime_t t_zero = 0.0;
if (ECS_EQ(m_desc.target_fps, t_zero)) {
m_desc.target_fps = 60;
}
}
app_builder& target_fps(ecs_ftime_t value) {
m_desc.target_fps = value;
return *this;
}
app_builder& delta_time(ecs_ftime_t value) {
m_desc.delta_time = value;
return *this;
}
app_builder& threads(int32_t value) {
m_desc.threads = value;
return *this;
}
app_builder& frames(int32_t value) {
m_desc.frames = value;
return *this;
}
app_builder& enable_rest(uint16_t port = 0) {
m_desc.enable_rest = true;
m_desc.port = port;
return *this;
}
app_builder& enable_monitor(bool value = true) {
m_desc.enable_monitor = value;
return *this;
}
app_builder& init(ecs_app_init_action_t value) {
m_desc.init = value;
return *this;
}
app_builder& ctx(void *value) {
m_desc.ctx = value;
return *this;
}
int run() {
int result = ecs_app_run(m_world, &m_desc);
if (ecs_should_quit(m_world)) {
ecs_fini(m_world);
}
return result;
}
private:
flecs::world_t *m_world;
ecs_app_desc_t m_desc;
};
}
#endif
#pragma once
namespace flecs {
namespace log {
inline void set_level(int level) {
ecs_log_set_level(level);
}
inline int get_level(void) {
return ecs_log_get_level();
}
inline void enable_colors(bool enabled = true) {
ecs_log_enable_colors(enabled);
}
inline void enable_timestamp(bool enabled = true) {
ecs_log_enable_timestamp(enabled);
}
inline void enable_timedelta(bool enabled = true) {
ecs_log_enable_timedelta(enabled);
}
inline void dbg(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
ecs_logv(1, fmt, args);
va_end(args);
}
inline void trace(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
ecs_logv(0, fmt, args);
va_end(args);
}
inline void warn(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
ecs_logv(-2, fmt, args);
va_end(args);
}
inline void err(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
ecs_logv(-3, fmt, args);
va_end(args);
}
inline void push(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
ecs_logv(0, fmt, args);
va_end(args);
ecs_log_push();
}
inline void push() {
ecs_log_push();
}
inline void pop() {
ecs_log_pop();
}
}
}
#pragma once
namespace flecs {
namespace _ {
struct pair_base { };
}
template <typename First, typename Second>
struct pair : _::pair_base {
using type = conditional_t<!is_empty<First>::value || is_empty<Second>::value, First, Second>;
using first = First;
using second = Second;
pair(type& v) : ref_(v) { }
pair(const type& v) : ref_(const_cast<type&>(v)) { }
operator type&() {
return ref_;
}
operator const type&() const {
return ref_;
}
type* operator->() {
return &ref_;
}
const type* operator->() const {
return &ref_;
}
type& operator*() {
return ref_;
}
const type& operator*() const {
return ref_;
}
private:
type& ref_;
};
template <typename First, typename Second, if_t<is_empty<First>::value> = 0>
using pair_object = pair<First, Second>;
template <typename T>
struct is_pair {
static constexpr bool value = is_base_of<_::pair_base, remove_reference_t<T> >::value;
};
template <typename P>
using pair_first_t = transcribe_cv_t<remove_reference_t<P>, typename remove_reference_t<P>::first>;
template <typename P>
using pair_second_t = transcribe_cv_t<remove_reference_t<P>, typename remove_reference_t<P>::second>;
template <typename P>
using pair_type_t = transcribe_cv_t<remove_reference_t<P>, typename remove_reference_t<P>::type>;
template <typename T, typename U = int>
struct actual_type;
template <typename T>
struct actual_type<T, if_not_t< is_pair<T>::value >> {
using type = T;
};
template <typename T>
struct actual_type<T, if_t< is_pair<T>::value >> {
using type = pair_type_t<T>;
};
template <typename T>
using actual_type_t = typename actual_type<T>::type;
template<typename T>
struct base_type {
using type = decay_t< remove_pointer_t< actual_type_t<T> > >;
};
template <typename T>
using base_type_t = typename base_type<T>::type;
template<typename T>
struct base_arg_type {
using type = remove_pointer_t< remove_reference_t< actual_type_t<T> > >;
};
template <typename T>
using base_arg_type_t = typename base_arg_type<T>::type;
template <typename T>
struct is_actual {
static constexpr bool value =
std::is_same<T, actual_type_t<T> >::value && !is_enum<T>::value;
};
}
#pragma once
namespace flecs
{
namespace _
{
inline void ecs_ctor_illegal(void *, int32_t, const ecs_type_info_t *ti) {
ecs_abort(ECS_INVALID_OPERATION, "invalid constructor for %s", ti->name);
}
inline void ecs_dtor_illegal(void *, int32_t, const ecs_type_info_t *ti) {
ecs_abort(ECS_INVALID_OPERATION, "invalid destructor for %s", ti->name);
}
inline void ecs_copy_illegal(
void *, const void *, int32_t, const ecs_type_info_t *ti)
{
ecs_abort(ECS_INVALID_OPERATION, "invalid copy assignment for %s", ti->name);
}
inline void ecs_move_illegal(void *, void *, int32_t, const ecs_type_info_t *ti) {
ecs_abort(ECS_INVALID_OPERATION, "invalid move assignment for %s", ti->name);
}
inline void ecs_copy_ctor_illegal(
void *, const void *, int32_t, const ecs_type_info_t *ti)
{
ecs_abort(ECS_INVALID_OPERATION, "invalid copy construct for %s", ti->name);
}
inline void ecs_move_ctor_illegal(
void *, void *, int32_t, const ecs_type_info_t *ti)
{
ecs_abort(ECS_INVALID_OPERATION, "invalid move construct for %s", ti->name);
}
template <typename T>
void ctor_impl(void *ptr, int32_t count, const ecs_type_info_t *info) {
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *arr = static_cast<T*>(ptr);
for (int i = 0; i < count; i ++) {
FLECS_PLACEMENT_NEW(&arr[i], T);
}
}
template <typename T>
void dtor_impl(void *ptr, int32_t count, const ecs_type_info_t *info) {
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *arr = static_cast<T*>(ptr);
for (int i = 0; i < count; i ++) {
arr[i].~T();
}
}
template <typename T>
void copy_impl(void *dst_ptr, const void *src_ptr, int32_t count,
const ecs_type_info_t *info)
{
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *dst_arr = static_cast<T*>(dst_ptr);
const T *src_arr = static_cast<const T*>(src_ptr);
for (int i = 0; i < count; i ++) {
dst_arr[i] = src_arr[i];
}
}
template <typename T>
void move_impl(void *dst_ptr, void *src_ptr, int32_t count,
const ecs_type_info_t *info)
{
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *dst_arr = static_cast<T*>(dst_ptr);
T *src_arr = static_cast<T*>(src_ptr);
for (int i = 0; i < count; i ++) {
dst_arr[i] = FLECS_MOV(src_arr[i]);
}
}
template <typename T>
void copy_ctor_impl(void *dst_ptr, const void *src_ptr, int32_t count,
const ecs_type_info_t *info)
{
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *dst_arr = static_cast<T*>(dst_ptr);
const T *src_arr = static_cast<const T*>(src_ptr);
for (int i = 0; i < count; i ++) {
FLECS_PLACEMENT_NEW(&dst_arr[i], T(src_arr[i]));
}
}
template <typename T>
void move_ctor_impl(void *dst_ptr, void *src_ptr, int32_t count,
const ecs_type_info_t *info)
{
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *dst_arr = static_cast<T*>(dst_ptr);
T *src_arr = static_cast<T*>(src_ptr);
for (int i = 0; i < count; i ++) {
FLECS_PLACEMENT_NEW(&dst_arr[i], T(FLECS_MOV(src_arr[i])));
}
}
template <typename T>
void ctor_move_dtor_impl(void *dst_ptr, void *src_ptr, int32_t count,
const ecs_type_info_t *info)
{
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *dst_arr = static_cast<T*>(dst_ptr);
T *src_arr = static_cast<T*>(src_ptr);
for (int i = 0; i < count; i ++) {
FLECS_PLACEMENT_NEW(&dst_arr[i], T(FLECS_MOV(src_arr[i])));
src_arr[i].~T();
}
}
template <typename T, if_not_t<
std::is_trivially_move_assignable<T>::value > = 0>
void move_dtor_impl(void *dst_ptr, void *src_ptr, int32_t count,
const ecs_type_info_t *info)
{
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *dst_arr = static_cast<T*>(dst_ptr);
T *src_arr = static_cast<T*>(src_ptr);
for (int i = 0; i < count; i ++) {
dst_arr[i] = FLECS_MOV(src_arr[i]);
src_arr[i].~T();
}
}
template <typename T, if_t<
std::is_trivially_move_assignable<T>::value > = 0>
void move_dtor_impl(void *dst_ptr, void *src_ptr, int32_t count,
const ecs_type_info_t *info)
{
(void)info; ecs_assert(info->size == ECS_SIZEOF(T),
ECS_INTERNAL_ERROR, NULL);
T *dst_arr = static_cast<T*>(dst_ptr);
T *src_arr = static_cast<T*>(src_ptr);
for (int i = 0; i < count; i ++) {
dst_arr[i].~T();
dst_arr[i] = FLECS_MOV(src_arr[i]);
}
}
}
template <typename T>
struct is_flecs_constructible {
static constexpr bool value =
std::is_default_constructible<actual_type_t<T>>::value;
};
namespace _
{
template <typename T, if_t< std::is_trivially_constructible<T>::value > = 0>
ecs_xtor_t ctor() {
return nullptr;
}
template <typename T, if_t<
! std::is_default_constructible<T>::value > = 0>
ecs_xtor_t ctor() {
return ecs_ctor_illegal;
}
template <typename T, if_t<
! std::is_trivially_constructible<T>::value &&
std::is_default_constructible<T>::value > = 0>
ecs_xtor_t ctor() {
return ctor_impl<T>;
}
template <typename T, if_t< std::is_trivially_destructible<T>::value > = 0>
ecs_xtor_t dtor() {
return nullptr;
}
template <typename T, if_t<
std::is_destructible<T>::value &&
! std::is_trivially_destructible<T>::value > = 0>
ecs_xtor_t dtor() {
return dtor_impl<T>;
}
template <typename T, if_not_t< std::is_destructible<T>::value > = 0>
ecs_xtor_t dtor() {
flecs_static_assert(always_false<T>::value,
"component type must be destructible");
return ecs_dtor_illegal;
}
template <typename T, if_t< std::is_trivially_copyable<T>::value > = 0>
ecs_copy_t copy() {
return nullptr;
}
template <typename T, if_t<
! std::is_trivially_copyable<T>::value &&
! std::is_copy_assignable<T>::value > = 0>
ecs_copy_t copy() {
return ecs_copy_illegal;
}
template <typename T, if_t<
std::is_copy_assignable<T>::value &&
! std::is_trivially_copyable<T>::value > = 0>
ecs_copy_t copy() {
return copy_impl<T>;
}
template <typename T, if_t< std::is_trivially_move_assignable<T>::value > = 0>
ecs_move_t move() {
return nullptr;
}
template <typename T, if_not_t< std::is_move_assignable<T>::value > = 0>
ecs_move_t move() {
flecs_static_assert(always_false<T>::value,
"component type must be move assignable");
return ecs_move_illegal;
}
template <typename T, if_t<
std::is_move_assignable<T>::value &&
! std::is_trivially_move_assignable<T>::value > = 0>
ecs_move_t move() {
return move_impl<T>;
}
template <typename T, if_t<
std::is_trivially_copy_constructible<T>::value > = 0>
ecs_copy_t copy_ctor() {
return nullptr;
}
template <typename T, if_t< ! std::is_copy_constructible<T>::value > = 0>
ecs_copy_t copy_ctor() {
return ecs_copy_ctor_illegal;
}
template <typename T, if_t<
std::is_copy_constructible<T>::value &&
! std::is_trivially_copy_constructible<T>::value > = 0>
ecs_copy_t copy_ctor() {
return copy_ctor_impl<T>;
}
template <typename T, if_t<
std::is_trivially_move_constructible<T>::value > = 0>
ecs_move_t move_ctor() {
return nullptr;
}
template <typename T, if_not_t< std::is_move_constructible<T>::value > = 0>
ecs_move_t move_ctor() {
flecs_static_assert(always_false<T>::value,
"component type must be move constructible");
return ecs_move_ctor_illegal;
}
template <typename T, if_t<
std::is_move_constructible<T>::value &&
! std::is_trivially_move_constructible<T>::value > = 0>
ecs_move_t move_ctor() {
return move_ctor_impl<T>;
}
template <typename T, if_t<
std::is_trivially_move_constructible<T>::value &&
std::is_trivially_destructible<T>::value > = 0>
ecs_move_t ctor_move_dtor() {
return nullptr;
}
template <typename T, if_t<
! std::is_move_constructible<T>::value ||
! std::is_destructible<T>::value > = 0>
ecs_move_t ctor_move_dtor() {
flecs_static_assert(always_false<T>::value,
"component type must be move constructible and destructible");
return ecs_move_ctor_illegal;
}
template <typename T, if_t<
!(std::is_trivially_move_constructible<T>::value &&
std::is_trivially_destructible<T>::value) &&
std::is_move_constructible<T>::value &&
std::is_destructible<T>::value > = 0>
ecs_move_t ctor_move_dtor() {
return ctor_move_dtor_impl<T>;
}
template <typename T, if_t<
std::is_trivially_move_assignable<T>::value &&
std::is_trivially_destructible<T>::value > = 0>
ecs_move_t move_dtor() {
return nullptr;
}
template <typename T, if_t<
! std::is_move_assignable<T>::value ||
! std::is_destructible<T>::value > = 0>
ecs_move_t move_dtor() {
flecs_static_assert(always_false<T>::value,
"component type must be move constructible and destructible");
return ecs_move_ctor_illegal;
}
template <typename T, if_t<
!(std::is_trivially_move_assignable<T>::value &&
std::is_trivially_destructible<T>::value) &&
std::is_move_assignable<T>::value &&
std::is_destructible<T>::value > = 0>
ecs_move_t move_dtor() {
return move_dtor_impl<T>;
}
} }
#pragma once
namespace flecs
{
template <typename T>
struct ref {
ref(world_t *world, entity_t entity, flecs::id_t id = 0)
: m_ref()
{
m_world = world ? const_cast<flecs::world_t *>(ecs_get_world(world))
: nullptr;
if (!id) {
id = _::cpp_type<T>::id(world);
}
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
m_ref = ecs_ref_init_id(m_world, entity, id);
}
T* operator->() {
T* result = static_cast<T*>(ecs_ref_get_id(
m_world, &m_ref, this->m_ref.id));
ecs_assert(result != NULL, ECS_INVALID_PARAMETER, NULL);
return result;
}
T* get() {
return static_cast<T*>(ecs_ref_get_id(
m_world, &m_ref, this->m_ref.id));
}
flecs::entity entity() const;
private:
world_t *m_world;
flecs::ref_t m_ref;
};
}
#pragma once
namespace flecs
{
template <typename T, if_t< is_flecs_constructible<T>::value > = 0>
inline void set(world_t *world, flecs::entity_t entity, T&& value, flecs::id_t id) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
if (!ecs_is_deferred(world)) {
T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id));
dst = FLECS_MOV(value);
ecs_modified_id(world, entity, id);
} else {
T& dst = *static_cast<T*>(ecs_get_mut_modified_id(world, entity, id));
dst = FLECS_MOV(value);
}
}
template <typename T, if_t< is_flecs_constructible<T>::value > = 0>
inline void set(world_t *world, flecs::entity_t entity, const T& value, flecs::id_t id) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
if (!ecs_is_deferred(world)) {
T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id));
dst = FLECS_MOV(value);
ecs_modified_id(world, entity, id);
} else {
T& dst = *static_cast<T*>(ecs_get_mut_modified_id(world, entity, id));
dst = FLECS_MOV(value);
}
}
template <typename T, if_not_t< is_flecs_constructible<T>::value > = 0>
inline void set(world_t *world, flecs::entity_t entity, T&& value, flecs::id_t id) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
if (!ecs_is_deferred(world)) {
T& dst = *static_cast<remove_reference_t<T>*>(ecs_get_mut_id(world, entity, id));
dst = FLECS_MOV(value);
ecs_modified_id(world, entity, id);
} else {
T& dst = *static_cast<remove_reference_t<T>*>(ecs_get_mut_modified_id(world, entity, id));
dst = FLECS_MOV(value);
}
}
template <typename T, if_not_t< is_flecs_constructible<T>::value > = 0>
inline void set(world_t *world, flecs::entity_t entity, const T& value, flecs::id_t id) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
if (!ecs_is_deferred(world)) {
T& dst = *static_cast<remove_reference_t<T>*>(ecs_get_mut_id(world, entity, id));
dst = FLECS_MOV(value);
ecs_modified_id(world, entity, id);
} else {
T& dst = *static_cast<remove_reference_t<T>*>(ecs_get_mut_modified_id(world, entity, id));
dst = FLECS_MOV(value);
}
}
template <typename T, typename ... Args, if_t<
std::is_constructible<actual_type_t<T>, Args...>::value ||
std::is_default_constructible<actual_type_t<T>>::value > = 0>
inline void emplace(world_t *world, flecs::entity_t entity, flecs::id_t id, Args&&... args) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
T& dst = *static_cast<T*>(ecs_emplace_id(world, entity, id));
FLECS_PLACEMENT_NEW(&dst, T{FLECS_FWD(args)...});
ecs_modified_id(world, entity, id);
}
template <typename T, typename A>
inline void set(world_t *world, entity_t entity, A&& value) {
id_t id = _::cpp_type<T>::id(world);
flecs::set(world, entity, FLECS_FWD(value), id);
}
template <typename T, typename A>
inline void set(world_t *world, entity_t entity, const A& value) {
id_t id = _::cpp_type<T>::id(world);
flecs::set(world, entity, value, id);
}
inline flecs::id_t strip_generation(flecs::entity_t e) {
return ecs_strip_generation(e);
}
inline uint32_t get_generation(flecs::entity_t e) {
return ECS_GENERATION(e);
}
struct scoped_world;
struct world {
explicit world()
: m_world( ecs_init() )
, m_owned( true ) { init_builtin_components(); }
explicit world(int argc, char *argv[])
: m_world( ecs_init_w_args(argc, argv) )
, m_owned( true ) { init_builtin_components(); }
explicit world(world_t *w)
: m_world( w )
, m_owned( false ) { }
world(const world& obj) = delete;
world(world&& obj) {
m_world = obj.m_world;
m_owned = obj.m_owned;
obj.m_world = nullptr;
obj.m_owned = false;
}
operator world_t*() const { return m_world; }
world& operator=(const world& obj) = delete;
world& operator=(world&& obj) {
this->~world();
m_world = obj.m_world;
m_owned = obj.m_owned;
obj.m_world = nullptr;
obj.m_owned = false;
return *this;
}
~world() {
if (m_owned && ecs_stage_is_async(m_world)) {
ecs_async_stage_free(m_world);
} else
if (m_owned && m_world) {
ecs_fini(m_world);
}
}
void reset() {
ecs_assert(this->m_owned, ECS_INVALID_OPERATION, NULL);
ecs_fini(m_world);
m_world = ecs_init();
}
world_t* c_ptr() const {
return m_world;
}
void quit() const {
ecs_quit(m_world);
}
void atfini(ecs_fini_action_t action, void *ctx) const {
ecs_atfini(m_world, action, ctx);
}
bool should_quit() const {
return ecs_should_quit(m_world);
}
ecs_ftime_t frame_begin(float delta_time = 0) const {
return ecs_frame_begin(m_world, delta_time);
}
void frame_end() const {
ecs_frame_end(m_world);
}
bool readonly_begin() const {
return ecs_readonly_begin(m_world);
}
void readonly_end() const {
ecs_readonly_end(m_world);
}
bool defer_begin() const {
return ecs_defer_begin(m_world);
}
bool defer_end() const {
return ecs_defer_end(m_world);
}
bool is_deferred() const {
return ecs_is_deferred(m_world);
}
void set_stage_count(int32_t stages) const {
ecs_set_stage_count(m_world, stages);
}
int32_t get_stage_count() const {
return ecs_get_stage_count(m_world);
}
int32_t get_stage_id() const {
return ecs_get_stage_id(m_world);
}
bool is_stage() const {
ecs_assert(
ecs_poly_is(m_world, ecs_world_t) ||
ecs_poly_is(m_world, ecs_stage_t),
ECS_INVALID_PARAMETER, NULL);
return ecs_poly_is(m_world, ecs_stage_t);
}
void set_automerge(bool automerge) const {
ecs_set_automerge(m_world, automerge);
}
void merge() const {
ecs_merge(m_world);
}
flecs::world get_stage(int32_t stage_id) const {
return flecs::world(ecs_get_stage(m_world, stage_id));
}
flecs::world async_stage() const {
auto result = flecs::world(ecs_async_stage_new(m_world));
result.m_owned = true;
return result;
}
flecs::world get_world() const {
return flecs::world(
m_world ? const_cast<flecs::world_t*>(ecs_get_world(m_world)) : nullptr);
}
bool is_readonly() const {
return ecs_stage_is_readonly(m_world);
}
void set_ctx(void* ctx, ecs_ctx_free_t ctx_free = nullptr) const {
ecs_set_ctx(m_world, ctx, ctx_free);
}
void* get_ctx() const {
return ecs_get_ctx(m_world);
}
void set_binding_ctx(void* ctx, ecs_ctx_free_t ctx_free = nullptr) const {
ecs_set_binding_ctx(m_world, ctx, ctx_free);
}
void* get_binding_ctx() const {
return ecs_get_binding_ctx(m_world);
}
void dim(int32_t entity_count) const {
ecs_dim(m_world, entity_count);
}
void set_entity_range(entity_t min, entity_t max) const {
ecs_set_entity_range(m_world, min, max);
}
void enable_range_check(bool enabled) const {
ecs_enable_range_check(m_world, enabled);
}
flecs::entity set_scope(const flecs::entity_t scope) const;
flecs::entity get_scope() const;
template <typename T>
flecs::entity set_scope() const;
flecs::entity_t* set_lookup_path(const flecs::entity_t *search_path) const {
return ecs_set_lookup_path(m_world, search_path);
}
flecs::entity lookup(const char *name, bool search_path = true) const;
template <typename T, if_t< !is_callable<T>::value > = 0>
void set(const T& value) const {
flecs::set<T>(m_world, _::cpp_type<T>::id(m_world), value);
}
template <typename T, if_t< !is_callable<T>::value > = 0>
void set(T&& value) const {
flecs::set<T>(m_world, _::cpp_type<T>::id(m_world),
FLECS_FWD(value));
}
template <typename First, typename Second, typename P = flecs::pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
void set(const A& value) const {
flecs::set<P>(m_world, _::cpp_type<First>::id(m_world), value);
}
template <typename First, typename Second, typename P = flecs::pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
void set(A&& value) const {
flecs::set<P>(m_world, _::cpp_type<First>::id(m_world), FLECS_FWD(value));
}
template <typename First, typename Second>
void set(Second second, const First& value) const;
template <typename First, typename Second>
void set(Second second, First&& value) const;
template <typename Func, if_t< is_callable<Func>::value > = 0 >
void set(const Func& func) const;
template <typename T, typename ... Args>
void emplace(Args&&... args) const {
flecs::id_t component_id = _::cpp_type<T>::id(m_world);
flecs::emplace<T>(m_world, component_id, component_id,
FLECS_FWD(args)...);
}
template <typename T>
T* get_mut() const;
template <typename T>
void modified() const;
template <typename T>
ref<T> get_ref() const;
template <typename T>
const T* get() const;
template <typename First, typename Second, typename P = flecs::pair<First, Second>,
typename A = actual_type_t<P>>
const A* get() const;
template <typename First, typename Second>
const First* get(Second second) const;
template <typename Func, if_t< is_callable<Func>::value > = 0 >
void get(const Func& func) const;
template <typename T>
bool has() const;
template <typename First, typename Second>
bool has() const;
template <typename First>
bool has(flecs::id_t second) const;
bool has(flecs::id_t first, flecs::id_t second) const;
template <typename T>
void add() const;
template <typename First, typename Second>
void add() const;
template <typename First>
void add(flecs::entity_t second) const;
void add(flecs::entity_t first, flecs::entity_t second) const;
template <typename T>
void remove() const;
template <typename First, typename Second>
void remove() const;
template <typename First>
void remove(flecs::entity_t second) const;
void remove(flecs::entity_t first, flecs::entity_t second) const;
template <typename Func>
void children(Func&& f) const;
template <typename T>
flecs::entity singleton() const;
template<typename First>
flecs::entity target(int32_t index = 0) const;
template<typename T>
flecs::entity target(flecs::entity_t first, int32_t index = 0) const;
flecs::entity target(flecs::entity_t first, int32_t index = 0) const;
template <typename T>
flecs::entity use(const char *alias = nullptr) const;
flecs::entity use(const char *name, const char *alias = nullptr) const;
void use(flecs::entity entity, const char *alias = nullptr) const;
int count(flecs::id_t component_id) const {
return ecs_count_id(m_world, component_id);
}
int count(flecs::entity_t first, flecs::entity_t second) const {
return ecs_count_id(m_world, ecs_pair(first, second));
}
template <typename T>
int count() const {
return count(_::cpp_type<T>::id(m_world));
}
template <typename First>
int count(flecs::entity_t second) const {
return count(_::cpp_type<First>::id(m_world), second);
}
template <typename First, typename Second>
int count() const {
return count(
_::cpp_type<First>::id(m_world),
_::cpp_type<Second>::id(m_world));
}
template <typename Func>
void with(id_t with_id, const Func& func) const {
ecs_id_t prev = ecs_set_with(m_world, with_id);
func();
ecs_set_with(m_world, prev);
}
template <typename T, typename Func>
void with(const Func& func) const {
with(this->id<T>(), func);
}
template <typename First, typename Second, typename Func>
void with(const Func& func) const {
with(ecs_pair(this->id<First>(), this->id<Second>()), func);
}
template <typename First, typename Func>
void with(id_t second, const Func& func) const {
with(ecs_pair(this->id<First>(), second), func);
}
template <typename Func>
void with(id_t first, id_t second, const Func& func) const {
with(ecs_pair(first, second), func);
}
template <typename Func>
void scope(id_t parent, const Func& func) const {
ecs_entity_t prev = ecs_set_scope(m_world, parent);
func();
ecs_set_scope(m_world, prev);
}
template <typename T, typename Func>
void scope(const Func& func) const {
flecs::id_t parent = _::cpp_type<T>::id(m_world);
scope(parent, func);
}
flecs::scoped_world scope(id_t parent) const;
template <typename T>
flecs::scoped_world scope() const;
flecs::scoped_world scope(const char* name) const;
void delete_with(id_t the_id) const {
ecs_delete_with(m_world, the_id);
}
void delete_with(entity_t first, entity_t second) const {
delete_with(ecs_pair(first, second));
}
template <typename T>
void delete_with() const {
delete_with(_::cpp_type<T>::id(m_world));
}
template <typename First, typename Second>
void delete_with() const {
delete_with(_::cpp_type<First>::id(m_world), _::cpp_type<Second>::id(m_world));
}
void remove_all(id_t the_id) const {
ecs_remove_all(m_world, the_id);
}
void remove_all(entity_t first, entity_t second) const {
remove_all(ecs_pair(first, second));
}
template <typename T>
void remove_all() const {
remove_all(_::cpp_type<T>::id(m_world));
}
template <typename First, typename Second>
void remove_all() const {
remove_all(_::cpp_type<First>::id(m_world), _::cpp_type<Second>::id(m_world));
}
template <typename Func>
void defer(const Func& func) const {
ecs_defer_begin(m_world);
func();
ecs_defer_end(m_world);
}
void defer_suspend() const {
ecs_defer_suspend(m_world);
}
void defer_resume() const {
ecs_defer_resume(m_world);
}
bool exists(flecs::entity_t e) const {
return ecs_exists(m_world, e);
}
bool is_alive(flecs::entity_t e) const {
return ecs_is_alive(m_world, e);
}
bool is_valid(flecs::entity_t e) const {
return ecs_is_valid(m_world, e);
}
flecs::entity get_alive(flecs::entity_t e) const;
#ifndef ensure
flecs::entity ensure(flecs::entity_t e) const;
#endif
void run_post_frame(ecs_fini_action_t action, void *ctx) const {
ecs_run_post_frame(m_world, action, ctx);
}
const flecs::world_info_t* get_info() const{
return ecs_get_world_info(m_world);
}
ecs_ftime_t delta_time() const {
return get_info()->delta_time;
}
template <typename T>
flecs::id id() const;
template <typename ... Args>
flecs::id id(Args&&... args) const;
template <typename First, typename Second>
flecs::id pair() const;
template <typename First>
flecs::id pair(entity_t o) const;
flecs::id pair(entity_t r, entity_t o) const;
template <typename T, typename... Args>
flecs::component<T> component(Args &&... args) const;
template <typename... Args>
flecs::untyped_component component(Args &&... args) const;
template <typename... Args>
flecs::entity entity(Args &&... args) const;
template <typename E, if_t< is_enum<E>::value > = 0>
flecs::id id(E value) const;
template <typename E, if_t< is_enum<E>::value > = 0>
flecs::entity entity(E value) const;
template <typename... Args>
flecs::entity prefab(Args &&... args) const;
template <typename T>
flecs::entity entity(const char *name = nullptr) const;
template <typename T>
flecs::entity prefab(const char *name = nullptr) const;
flecs::event_builder event(flecs::entity_t evt) const;
template <typename E>
flecs::event_builder_typed<E> event() const;
template<typename... Args>
flecs::term term(Args &&... args) const;
template<typename T>
flecs::term term() const;
template<typename First, typename Second>
flecs::term term() const;
template <typename... Comps, typename... Args>
flecs::filter<Comps...> filter(Args &&... args) const;
template <typename... Comps, typename... Args>
flecs::filter_builder<Comps...> filter_builder(Args &&... args) const;
template <typename Func>
void each(Func&& func) const;
template <typename T, typename Func>
void each(Func&& func) const;
template <typename Func>
void each(flecs::id_t term_id, Func&& func) const;
flecs::observer observer(flecs::entity e) const;
template <typename... Components, typename... Args>
flecs::observer_builder<Components...> observer(Args &&... args) const;
template <typename... Comps, typename... Args>
flecs::query<Comps...> query(Args &&... args) const;
template <typename... Comps, typename... Args>
flecs::query<Comps...> query(flecs::query_base& parent, Args &&... args) const;
template <typename... Comps, typename... Args>
flecs::query_builder<Comps...> query_builder(Args &&... args) const;
template <typename E, if_t< is_enum<E>::value > = 0>
flecs::entity to_entity(E constant) const;
# ifdef FLECS_MODULE
template <typename Module>
flecs::entity module(const char *name = nullptr) const;
template <typename Module>
flecs::entity import();
# endif
# ifdef FLECS_PIPELINE
flecs::pipeline_builder<> pipeline() const;
template <typename Pipeline, if_not_t< is_enum<Pipeline>::value > = 0>
flecs::pipeline_builder<> pipeline() const;
void set_pipeline(const flecs::entity pip) const;
template <typename Pipeline>
void set_pipeline() const;
flecs::entity get_pipeline() const;
bool progress(ecs_ftime_t delta_time = 0.0) const;
void run_pipeline(const flecs::entity_t pip, ecs_ftime_t delta_time = 0.0) const;
template <typename Pipeline, if_not_t< is_enum<Pipeline>::value > = 0>
void run_pipeline(ecs_ftime_t delta_time = 0.0) const;
void set_time_scale(ecs_ftime_t mul) const;
void set_target_fps(ecs_ftime_t target_fps) const;
void reset_clock() const;
void set_threads(int32_t threads) const;
int32_t get_threads() const;
void set_task_threads(int32_t task_threads) const;
bool using_task_threads() const;
# endif
# ifdef FLECS_SNAPSHOT
template <typename... Args>
flecs::snapshot snapshot(Args &&... args) const;
# endif
# ifdef FLECS_SYSTEM
flecs::system system(flecs::entity e) const;
template <typename... Components, typename... Args>
flecs::system_builder<Components...> system(Args &&... args) const;
# endif
# ifdef FLECS_TIMER
template <typename... Args>
flecs::timer timer(Args &&... args) const;
void randomize_timers() const;
# endif
# ifdef FLECS_RULES
template <typename... Comps, typename... Args>
flecs::rule<Comps...> rule(Args &&... args) const;
template <typename... Comps, typename... Args>
flecs::rule<Comps...> rule(flecs::rule_base& parent, Args &&... args) const;
template <typename... Comps, typename... Args>
flecs::rule_builder<Comps...> rule_builder(Args &&... args) const;
# endif
# ifdef FLECS_PLECS
int plecs_from_str(const char *name, const char *str) const {
return ecs_plecs_from_str(m_world, name, str);
}
int plecs_from_file(const char *filename) const {
return ecs_plecs_from_file(m_world, filename);
}
# endif
# ifdef FLECS_META
flecs::string to_expr(flecs::entity_t tid, const void* value) {
char *expr = ecs_ptr_to_expr(m_world, tid, value);
return flecs::string(expr);
}
template <typename T>
flecs::string to_expr(const T* value) {
flecs::entity_t tid = _::cpp_type<T>::id(m_world);
return to_expr(tid, value);
}
flecs::cursor cursor(flecs::entity_t tid, void *ptr) {
return flecs::cursor(m_world, tid, ptr);
}
template <typename T>
flecs::cursor cursor(void *ptr) {
flecs::entity_t tid = _::cpp_type<T>::id(m_world);
return cursor(tid, ptr);
}
flecs::entity primitive(flecs::meta::primitive_kind_t kind);
flecs::entity array(flecs::entity_t elem_id, int32_t array_count);
template <typename T>
flecs::entity array(int32_t array_count);
flecs::entity vector(flecs::entity_t elem_id);
template <typename T>
flecs::entity vector();
# endif
# ifdef FLECS_JSON
flecs::string to_json(flecs::entity_t tid, const void* value) {
char *json = ecs_ptr_to_json(m_world, tid, value);
return flecs::string(json);
}
template <typename T>
flecs::string to_json(const T* value) {
flecs::entity_t tid = _::cpp_type<T>::id(m_world);
return to_json(tid, value);
}
flecs::string to_json() {
return flecs::string( ecs_world_to_json(m_world, nullptr) );
}
const char* from_json(flecs::entity_t tid, void* value, const char *json, flecs::from_json_desc_t *desc = nullptr) {
return ecs_ptr_from_json(m_world, tid, value, json, desc);
}
template <typename T>
const char* from_json(T* value, const char *json, flecs::from_json_desc_t *desc = nullptr) {
return ecs_ptr_from_json(m_world, _::cpp_type<T>::id(m_world),
value, json, desc);
}
const char* from_json(const char *json, flecs::from_json_desc_t *desc = nullptr) {
return ecs_world_from_json(m_world, json, desc);
}
# endif
# ifdef FLECS_APP
flecs::app_builder app() {
m_owned = false; return flecs::app_builder(m_world);
}
# endif
# ifdef FLECS_METRICS
template <typename... Args>
flecs::metric_builder metric(Args &&... args) const;
# endif
# ifdef FLECS_ALERTS
template <typename... Comps, typename... Args>
flecs::alert_builder<Comps...> alert(Args &&... args) const;
# endif
public:
void init_builtin_components();
world_t *m_world;
bool m_owned;
};
struct scoped_world : world {
scoped_world(
flecs::world_t *w,
flecs::entity_t s) : world(nullptr)
{
m_prev_scope = ecs_set_scope(w, s);
m_world = w;
m_owned = false;
}
~scoped_world() {
ecs_set_scope(m_world, m_prev_scope);
}
scoped_world(const scoped_world& obj) : world(nullptr) {
m_prev_scope = obj.m_prev_scope;
m_world = obj.m_world;
m_owned = obj.m_owned;
}
flecs::entity_t m_prev_scope;
};
}
#pragma once
namespace flecs
{
struct untyped_column {
untyped_column(void* array, size_t size, size_t count, bool is_shared = false)
: m_array(array)
, m_size(size)
, m_count(count)
, m_is_shared(is_shared) {}
void* operator[](size_t index) const {
ecs_assert(index < m_count, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
ecs_assert(!m_is_shared, ECS_INVALID_PARAMETER, NULL);
return ECS_OFFSET(m_array, m_size * index);
}
protected:
void* m_array;
size_t m_size;
size_t m_count;
bool m_is_shared;
};
template <typename T>
struct column {
static_assert(std::is_empty<T>::value == false,
"invalid type for column, cannot iterate empty type");
column(T* array, size_t count, bool is_shared = false)
: m_array(array)
, m_count(count)
, m_is_shared(is_shared) {}
column(iter &iter, int column);
T& operator[](size_t index) const {
ecs_assert(index < m_count, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
ecs_assert(!index || !m_is_shared, ECS_INVALID_PARAMETER, NULL);
ecs_assert(m_array != nullptr, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
return m_array[index];
}
T& operator*() const {
ecs_assert(m_array != nullptr, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
return *m_array;
}
T* operator->() const {
ecs_assert(m_array != nullptr, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
return m_array;
}
protected:
T* m_array;
size_t m_count;
bool m_is_shared;
};
namespace _ {
template <typename T>
struct range_iterator
{
explicit range_iterator(T value)
: m_value(value){}
bool operator!=(range_iterator const& other) const
{
return m_value != other.m_value;
}
T const& operator*() const
{
return m_value;
}
range_iterator& operator++()
{
++m_value;
return *this;
}
private:
T m_value;
};
}
}
namespace flecs
{
struct iter {
private:
using row_iterator = _::range_iterator<size_t>;
public:
iter(ecs_iter_t *it) : m_iter(it) {
m_begin = 0;
m_end = static_cast<std::size_t>(it->count);
}
row_iterator begin() const {
return row_iterator(m_begin);
}
row_iterator end() const {
return row_iterator(m_end);
}
flecs::entity system() const;
flecs::entity event() const;
flecs::id event_id() const;
flecs::world world() const;
const flecs::iter_t* c_ptr() const {
return m_iter;
}
size_t count() const {
return static_cast<size_t>(m_iter->count);
}
ecs_ftime_t delta_time() const {
return m_iter->delta_time;
}
ecs_ftime_t delta_system_time() const {
return m_iter->delta_system_time;
}
flecs::type type() const;
flecs::table table() const;
flecs::table_range range() const;
void* ctx() {
return m_iter->ctx;
}
template <typename T>
T* ctx() {
return static_cast<T*>(m_iter->ctx);
}
void* param() {
return m_iter->param;
}
template <typename T>
T* param() {
return static_cast<T*>(m_iter->param);
}
flecs::entity entity(size_t row) const;
bool is_self(int32_t index) const {
return ecs_field_is_self(m_iter, index);
}
bool is_set(int32_t index) const {
return ecs_field_is_set(m_iter, index);
}
bool is_readonly(int32_t index) const {
return ecs_field_is_readonly(m_iter, index);
}
int32_t field_count() const {
return m_iter->field_count;
}
size_t size(int32_t index) const {
return ecs_field_size(m_iter, index);
}
flecs::entity src(int32_t index) const;
flecs::id id(int32_t index) const;
flecs::id pair(int32_t index) const;
int32_t column_index(int32_t index) const {
return ecs_field_column_index(m_iter, index);
}
flecs::string str() const {
char *s = ecs_iter_str(m_iter);
return flecs::string(s);
}
template <typename T, typename A = actual_type_t<T>,
typename std::enable_if<std::is_const<T>::value, void>::type* = nullptr>
flecs::column<A> field(int32_t index) const {
return get_field<A>(index);
}
template <typename T, typename A = actual_type_t<T>,
typename std::enable_if<
std::is_const<T>::value == false, void>::type* = nullptr>
flecs::column<A> field(int32_t index) const {
ecs_assert(!ecs_field_is_readonly(m_iter, index),
ECS_ACCESS_VIOLATION, NULL);
return get_field<A>(index);
}
flecs::untyped_column field(int32_t index) const {
return get_unchecked_field(index);
}
flecs::column<const flecs::entity_t> entities() const {
return flecs::column<const flecs::entity_t>(m_iter->entities, static_cast<size_t>(m_iter->count), false);
}
int32_t table_count() const {
return m_iter->table_count;
}
bool changed() {
return ecs_query_changed(nullptr, m_iter);
}
void skip() {
ecs_query_skip(m_iter);
}
uint64_t group_id() const {
return m_iter->group_id;
}
#ifdef FLECS_RULES
flecs::entity get_var(int var_id) const;
flecs::entity get_var(const char *name) const;
#endif
private:
template <typename T, typename A = actual_type_t<T>>
flecs::column<T> get_field(int32_t index) const {
#ifndef FLECS_NDEBUG
ecs_entity_t term_id = ecs_field_id(m_iter, index);
ecs_assert(ECS_HAS_ID_FLAG(term_id, PAIR) ||
term_id == _::cpp_type<T>::id(m_iter->world),
ECS_COLUMN_TYPE_MISMATCH, NULL);
#endif
size_t count;
bool is_shared = !ecs_field_is_self(m_iter, index);
if (is_shared) {
count = 1;
} else {
count = static_cast<size_t>(m_iter->count);
}
return flecs::column<A>(
static_cast<T*>(ecs_field_w_size(m_iter, sizeof(A), index)),
count, is_shared);
}
flecs::untyped_column get_unchecked_field(int32_t index) const {
size_t count;
size_t size = ecs_field_size(m_iter, index);
bool is_shared = !ecs_field_is_self(m_iter, index);
if (is_shared) {
count = 1;
} else {
count = static_cast<size_t>(m_iter->count);
}
return flecs::untyped_column(
ecs_field_w_size(m_iter, 0, index), size, count, is_shared);
}
flecs::iter_t *m_iter;
std::size_t m_begin;
std::size_t m_end;
};
}
#pragma once
#pragma once
namespace flecs
{
struct entity_view : public id {
entity_view() : flecs::id() { }
explicit entity_view(flecs::world_t *world, flecs::id_t id)
: flecs::id(world
? const_cast<flecs::world_t*>(ecs_get_world(world))
: nullptr
, id ) { }
entity_view(entity_t id)
: flecs::id( nullptr, id ) { }
entity_t id() const {
return m_id;
}
bool is_valid() const {
return m_world && ecs_is_valid(m_world, m_id);
}
explicit operator bool() const {
return is_valid();
}
bool is_alive() const {
return m_world && ecs_is_alive(m_world, m_id);
}
flecs::string_view name() const {
return flecs::string_view(ecs_get_name(m_world, m_id));
}
flecs::string_view symbol() const {
return flecs::string_view(ecs_get_symbol(m_world, m_id));
}
flecs::string path(const char *sep = "::", const char *init_sep = "::") const {
return path_from(0, sep, init_sep);
}
flecs::string path_from(flecs::entity_t parent, const char *sep = "::", const char *init_sep = "::") const {
char *path = ecs_get_path_w_sep(m_world, parent, m_id, sep, init_sep);
return flecs::string(path);
}
template <typename Parent>
flecs::string path_from(const char *sep = "::", const char *init_sep = "::") const {
return path_from(_::cpp_type<Parent>::id(m_world), sep, init_sep);
}
bool enabled() const {
return !ecs_has_id(m_world, m_id, flecs::Disabled);
}
flecs::type type() const;
flecs::table table() const;
flecs::table_range range() const;
template <typename Func>
void each(const Func& func) const;
template <typename Func>
void each(flecs::id_t first, flecs::id_t second, const Func& func) const;
template <typename Func>
void each(const flecs::entity_view& rel, const Func& func) const;
template <typename First, typename Func>
void each(const Func& func) const {
return each(_::cpp_type<First>::id(m_world), func);
}
template <typename Func>
void children(flecs::entity_t rel, Func&& func) const {
if (m_id == flecs::Wildcard || m_id == flecs::Any) {
return;
}
flecs::world world(m_world);
ecs_term_t terms[2];
ecs_filter_t f = ECS_FILTER_INIT;
f.terms = terms;
f.term_count = 2;
ecs_filter_desc_t desc = {};
desc.terms[0].first.id = rel;
desc.terms[0].second.id = m_id;
desc.terms[0].second.flags = EcsIsEntity;
desc.terms[1].id = flecs::Prefab;
desc.terms[1].oper = EcsOptional;
desc.storage = &f;
if (ecs_filter_init(m_world, &desc) != nullptr) {
ecs_iter_t it = ecs_filter_iter(m_world, &f);
while (ecs_filter_next(&it)) {
_::each_invoker<Func>(FLECS_MOV(func)).invoke(&it);
}
ecs_filter_fini(&f);
}
}
template <typename Rel, typename Func>
void children(Func&& func) const {
children(_::cpp_type<Rel>::id(m_world), FLECS_MOV(func));
}
template <typename Func>
void children(Func&& func) const {
children(flecs::ChildOf, FLECS_MOV(func));
}
template <typename T, if_t< is_actual<T>::value > = 0>
const T* get() const {
auto comp_id = _::cpp_type<T>::id(m_world);
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
return static_cast<const T*>(ecs_get_id(m_world, m_id, comp_id));
}
template <typename T, typename A = actual_type_t<T>,
if_t< flecs::is_pair<T>::value > = 0>
const A* get() const {
auto comp_id = _::cpp_type<T>::id(m_world);
ecs_assert(_::cpp_type<A>::size() != 0, ECS_INVALID_PARAMETER, NULL);
return static_cast<const A*>(ecs_get_id(m_world, m_id, comp_id));
}
template <typename First, typename Second, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value > = 0>
const A* get() const {
return this->get<P>();
}
template<typename First, typename Second, if_not_t< is_enum<Second>::value> = 0>
const First* get(Second second) const {
auto comp_id = _::cpp_type<First>::id(m_world);
ecs_assert(_::cpp_type<First>::size() != 0, ECS_INVALID_PARAMETER, NULL);
return static_cast<const First*>(
ecs_get_id(m_world, m_id, ecs_pair(comp_id, second)));
}
template<typename First, typename Second, if_t<is_enum<Second>::value> = 0>
const First* get(Second constant) const {
const auto& et = enum_type<Second>(this->m_world);
flecs::entity_t target = et.entity(constant);
return get<First>(target);
}
const void* get(flecs::id_t comp) const {
return ecs_get_id(m_world, m_id, comp);
}
const void* get(flecs::entity_t first, flecs::entity_t second) const {
return ecs_get_id(m_world, m_id, ecs_pair(first, second));
}
template <typename Func, if_t< is_callable<Func>::value > = 0>
bool get(const Func& func) const;
template <typename T, if_t< is_enum<T>::value > = 0>
const T* get() const;
template<typename Second>
const Second* get_second(flecs::entity_t first) const {
auto second = _::cpp_type<Second>::id(m_world);
ecs_assert(_::cpp_type<Second>::size() != 0, ECS_INVALID_PARAMETER, NULL);
return static_cast<const Second*>(
ecs_get_id(m_world, m_id, ecs_pair(first, second)));
}
template<typename First, typename Second>
const Second* get_second() const {
return get<pair_object<First, Second>>();
}
template<typename First>
flecs::entity target(int32_t index = 0) const;
flecs::entity target(flecs::entity_t first, int32_t index = 0) const;
flecs::entity target_for(flecs::entity_t relationship, flecs::id_t id) const;
template <typename T>
flecs::entity target_for(flecs::entity_t relationship) const;
template <typename First, typename Second>
flecs::entity target_for(flecs::entity_t relationship) const;
int32_t depth(flecs::entity_t rel) const {
return ecs_get_depth(m_world, m_id, rel);
}
template<typename Rel>
int32_t depth() const {
return this->depth(_::cpp_type<Rel>::id(m_world));
}
flecs::entity parent() const;
flecs::entity lookup(const char *path, bool search_path = false) const;
bool has(flecs::id_t e) const {
return ecs_has_id(m_world, m_id, e);
}
template <typename T>
bool has() const {
flecs::id_t cid = _::cpp_type<T>::id(m_world);
bool result = ecs_has_id(m_world, m_id, cid);
if (result) {
return result;
}
if (is_enum<T>::value) {
return ecs_has_pair(m_world, m_id, cid, flecs::Wildcard);
}
return false;
}
template <typename E, if_t< is_enum<E>::value > = 0>
bool has(E value) const {
auto r = _::cpp_type<E>::id(m_world);
auto o = enum_type<E>(m_world).entity(value);
return ecs_has_pair(m_world, m_id, r, o);
}
template <typename First, typename Second>
bool has() const {
return this->has<First>(_::cpp_type<Second>::id(m_world));
}
template<typename First, typename Second, if_not_t< is_enum<Second>::value > = 0>
bool has(Second second) const {
auto comp_id = _::cpp_type<First>::id(m_world);
return ecs_has_id(m_world, m_id, ecs_pair(comp_id, second));
}
template <typename Second>
bool has_second(flecs::entity_t first) const {
return this->has(first, _::cpp_type<Second>::id(m_world));
}
template<typename First, typename E, if_t< is_enum<E>::value > = 0>
bool has(E value) const {
const auto& et = enum_type<E>(this->m_world);
flecs::entity_t second = et.entity(value);
return has<First>(second);
}
bool has(flecs::id_t first, flecs::id_t second) const {
return ecs_has_id(m_world, m_id, ecs_pair(first, second));
}
bool owns(flecs::id_t e) const {
return ecs_owns_id(m_world, m_id, e);
}
template <typename First>
bool owns(flecs::id_t second) const {
auto comp_id = _::cpp_type<First>::id(m_world);
return owns(ecs_pair(comp_id, second));
}
bool owns(flecs::id_t first, flecs::id_t second) const {
return owns(ecs_pair(first, second));
}
template <typename T>
bool owns() const {
return owns(_::cpp_type<T>::id(m_world));
}
template <typename First, typename Second>
bool owns() const {
return owns(
_::cpp_type<First>::id(m_world),
_::cpp_type<Second>::id(m_world));
}
bool enabled(flecs::id_t id) const {
return ecs_is_enabled_id(m_world, m_id, id);
}
template<typename T>
bool enabled() const {
return this->enabled(_::cpp_type<T>::id(m_world));
}
bool enabled(flecs::id_t first, flecs::id_t second) const {
return this->enabled(ecs_pair(first, second));
}
template <typename First>
bool enabled(flecs::id_t second) const {
return this->enabled(_::cpp_type<First>::id(m_world), second);
}
template <typename First, typename Second>
bool enabled() const {
return this->enabled<First>(_::cpp_type<Second>::id(m_world));
}
flecs::entity clone(bool clone_value = true, flecs::entity_t dst_id = 0) const;
flecs::entity mut(const flecs::world& stage) const;
flecs::entity mut(const flecs::iter& it) const;
flecs::entity mut(const flecs::entity_view& e) const;
# ifdef FLECS_JSON
flecs::string to_json(const flecs::entity_to_json_desc_t *desc = nullptr) {
char *json = ecs_entity_to_json(m_world, m_id, desc);
return flecs::string(json);
}
# endif
# ifdef FLECS_DOC
const char* doc_name() {
return ecs_doc_get_name(m_world, m_id);
}
const char* doc_brief() {
return ecs_doc_get_brief(m_world, m_id);
}
const char* doc_detail() {
return ecs_doc_get_detail(m_world, m_id);
}
const char* doc_link() {
return ecs_doc_get_link(m_world, m_id);
}
const char* doc_color() {
return ecs_doc_get_color(m_world, m_id);
}
# endif
# ifdef FLECS_ALERTS
int32_t alert_count(flecs::entity_t alert = 0) const {
return ecs_get_alert_count(m_world, m_id, alert);
}
# endif
template <typename E>
E to_constant() const;
private:
flecs::entity set_stage(world_t *stage);
};
}
#pragma once
namespace flecs
{
template <typename Self>
struct entity_builder : entity_view {
using entity_view::entity_view;
template <typename T>
Self& add() {
flecs_static_assert(is_flecs_constructible<T>::value,
"cannot default construct type: add T::T() or use emplace<T>()");
ecs_add_id(this->m_world, this->m_id, _::cpp_type<T>::id(this->m_world));
return to_base();
}
template <typename E, if_t< is_enum<E>::value > = 0>
Self& add(E value) {
flecs::entity_t first = _::cpp_type<E>::id(this->m_world);
const auto& et = enum_type<E>(this->m_world);
flecs::entity_t second = et.entity(value);
return this->add(first, second);
}
Self& add(id_t component) {
ecs_add_id(this->m_world, this->m_id, component);
return to_base();
}
Self& add(entity_t first, entity_t second) {
ecs_add_pair(this->m_world, this->m_id, first, second);
return to_base();
}
template<typename First, typename Second>
Self& add() {
return this->add<First>(_::cpp_type<Second>::id(this->m_world));
}
template<typename First, typename Second, if_not_t< is_enum<Second>::value > = 0>
Self& add(Second second) {
flecs_static_assert(is_flecs_constructible<First>::value,
"cannot default construct type: add T::T() or use emplace<T>()");
return this->add(_::cpp_type<First>::id(this->m_world), second);
}
template<typename First, typename Second, if_t< is_enum<Second>::value > = 0>
Self& add(Second constant) {
flecs_static_assert(is_flecs_constructible<First>::value,
"cannot default construct type: add T::T() or use emplace<T>()");
const auto& et = enum_type<Second>(this->m_world);
return this->add<First>(et.entity(constant));
}
template<typename Second>
Self& add_second(flecs::entity_t first) {
return this->add(first, _::cpp_type<Second>::id(this->m_world));
}
Self& add_if(bool cond, flecs::id_t component) {
if (cond) {
return this->add(component);
} else {
return this->remove(component);
}
}
template <typename T>
Self& add_if(bool cond) {
if (cond) {
return this->add<T>();
} else {
return this->remove<T>();
}
}
Self& add_if(bool cond, flecs::entity_t first, flecs::entity_t second) {
if (cond) {
return this->add(first, second);
} else {
if (!second || ecs_has_id(this->m_world, first, flecs::Exclusive)) {
second = flecs::Wildcard;
}
return this->remove(first, second);
}
}
template <typename First>
Self& add_if(bool cond, flecs::entity_t second) {
return this->add_if(cond, _::cpp_type<First>::id(this->m_world), second);
}
template <typename First, typename Second>
Self& add_if(bool cond) {
return this->add_if<First>(cond, _::cpp_type<Second>::id(this->m_world));
}
template <typename E, if_t< is_enum<E>::value > = 0>
Self& add_if(bool cond, E constant) {
const auto& et = enum_type<E>(this->m_world);
return this->add_if<E>(cond, et.entity(constant));
}
Self& is_a(entity_t second) {
return this->add(flecs::IsA, second);
}
template <typename T>
Self& is_a() {
return this->add(flecs::IsA, _::cpp_type<T>::id(this->m_world));
}
Self& child_of(entity_t second) {
return this->add(flecs::ChildOf, second);
}
Self& depends_on(entity_t second) {
return this->add(flecs::DependsOn, second);
}
Self& slot_of(entity_t second) {
return this->add(flecs::SlotOf, second);
}
Self& slot() {
ecs_check(ecs_get_target(m_world, m_id, flecs::ChildOf, 0),
ECS_INVALID_PARAMETER, "add ChildOf pair before using slot()");
return this->slot_of(this->target(flecs::ChildOf));
error:
return to_base();
}
template <typename T>
Self& child_of() {
return this->child_of(_::cpp_type<T>::id(this->m_world));
}
template <typename T>
Self& depends_on() {
return this->depends_on(_::cpp_type<T>::id(this->m_world));
}
template <typename T>
Self& slot_of() {
return this->slot_of(_::cpp_type<T>::id(this->m_world));
}
template <typename T, if_not_t< is_enum<T>::value > = 0>
Self& remove() {
ecs_remove_id(this->m_world, this->m_id, _::cpp_type<T>::id(this->m_world));
return to_base();
}
template <typename E, if_t< is_enum<E>::value > = 0>
Self& remove() {
flecs::entity_t first = _::cpp_type<E>::id(this->m_world);
return this->remove(first, flecs::Wildcard);
}
Self& remove(entity_t entity) {
ecs_remove_id(this->m_world, this->m_id, entity);
return to_base();
}
Self& remove(entity_t first, entity_t second) {
ecs_remove_pair(this->m_world, this->m_id, first, second);
return to_base();
}
template<typename First, typename Second>
Self& remove() {
return this->remove<First>(_::cpp_type<Second>::id(this->m_world));
}
template<typename First, typename Second, if_not_t< is_enum<Second>::value > = 0>
Self& remove(Second second) {
return this->remove(_::cpp_type<First>::id(this->m_world), second);
}
template<typename Second>
Self& remove_second(flecs::entity_t first) {
return this->remove(first, _::cpp_type<Second>::id(this->m_world));
}
template<typename First, typename Second, if_t< is_enum<Second>::value > = 0>
Self& remove(Second constant) {
const auto& et = enum_type<Second>(this->m_world);
flecs::entity_t second = et.entity(constant);
return this->remove<First>(second);
}
Self& override(flecs::id_t id) {
return this->add(ECS_OVERRIDE | id);
}
Self& override(flecs::entity_t first, flecs::entity_t second) {
return this->override(ecs_pair(first, second));
}
template <typename T>
Self& override() {
return this->override(_::cpp_type<T>::id(this->m_world));
}
template <typename First>
Self& override(flecs::entity_t second) {
return this->override(_::cpp_type<First>::id(this->m_world), second);
}
template <typename First, typename Second>
Self& override() {
return this->override<First>(_::cpp_type<Second>::id(this->m_world));
}
template <typename T>
Self& set_override(const T& val) {
this->override<T>();
return this->set<T>(val);
}
template <typename T>
Self& set_override(T&& val) {
this->override<T>();
return this->set<T>(FLECS_FWD(val));
}
template <typename First>
Self& set_override(flecs::entity_t second, const First& val) {
this->override<First>(second);
return this->set<First>(second, val);
}
template <typename First>
Self& set_override(flecs::entity_t second, First&& val) {
this->override<First>(second);
return this->set<First>(second, FLECS_FWD(val));
}
template <typename First, typename Second, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
Self& set_override(const A& val) {
this->override<First, Second>();
return this->set<First, Second>(val);
}
template <typename First, typename Second, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
Self& set_override(A&& val) {
this->override<First, Second>();
return this->set<First, Second>(FLECS_FWD(val));
}
template <typename T, typename ... Args>
Self& emplace_override(Args&&... args) {
this->override<T>();
flecs::emplace<T>(this->m_world, this->m_id,
_::cpp_type<T>::id(this->m_world), FLECS_FWD(args)...);
return to_base();
}
template <typename First, typename Second, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0,
typename ... Args>
Self& emplace_override(Args&&... args) {
this->override<First, Second>();
flecs::emplace<A>(this->m_world, this->m_id,
ecs_pair(_::cpp_type<First>::id(this->m_world),
_::cpp_type<Second>::id(this->m_world)),
FLECS_FWD(args)...);
return to_base();
}
Self& enable() {
ecs_enable(this->m_world, this->m_id, true);
return to_base();
}
Self& disable() {
ecs_enable(this->m_world, this->m_id, false);
return to_base();
}
Self& enable(flecs::id_t id, bool toggle = true) {
ecs_enable_id(this->m_world, this->m_id, id, toggle);
return to_base();
}
template<typename T>
Self& enable() {
return this->enable(_::cpp_type<T>::id(this->m_world));
}
Self& enable(flecs::id_t first, flecs::id_t second) {
return this->enable(ecs_pair(first, second));
}
template<typename First>
Self& enable(flecs::id_t second) {
return this->enable(_::cpp_type<First>::id(), second);
}
template<typename First, typename Second>
Self& enable() {
return this->enable<First>(_::cpp_type<Second>::id());
}
Self& disable(flecs::id_t id) {
return this->enable(id, false);
}
template<typename T>
Self& disable() {
return this->disable(_::cpp_type<T>::id());
}
Self& disable(flecs::id_t first, flecs::id_t second) {
return this->disable(ecs_pair(first, second));
}
template<typename First>
Self& disable(flecs::id_t second) {
return this->disable(_::cpp_type<First>::id(), second);
}
template<typename First, typename Second>
Self& disable() {
return this->disable<First>(_::cpp_type<Second>::id());
}
Self& set_ptr(entity_t comp, size_t size, const void *ptr) {
ecs_set_id(this->m_world, this->m_id, comp, size, ptr);
return to_base();
}
Self& set_ptr(entity_t comp, const void *ptr) {
const flecs::Component *cptr = ecs_get(
this->m_world, comp, EcsComponent);
ecs_assert(cptr != NULL, ECS_INVALID_PARAMETER, NULL);
return set_ptr(comp, cptr->size, ptr);
}
template<typename T, if_t<
!is_callable<T>::value && is_actual<T>::value> = 0 >
Self& set(T&& value) {
flecs::set<T>(this->m_world, this->m_id, FLECS_FWD(value));
return to_base();
}
template<typename T, if_t<
!is_callable<T>::value && is_actual<T>::value > = 0>
Self& set(const T& value) {
flecs::set<T>(this->m_world, this->m_id, value);
return to_base();
}
template<typename T, typename A = actual_type_t<T>, if_not_t<
is_callable<T>::value || is_actual<T>::value > = 0>
Self& set(A&& value) {
flecs::set<T>(this->m_world, this->m_id, FLECS_FWD(value));
return to_base();
}
template<typename T, typename A = actual_type_t<T>, if_not_t<
is_callable<T>::value || is_actual<T>::value > = 0>
Self& set(const A& value) {
flecs::set<T>(this->m_world, this->m_id, value);
return to_base();
}
template <typename First, typename Second, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
Self& set(A&& value) {
flecs::set<P>(this->m_world, this->m_id, FLECS_FWD(value));
return to_base();
}
template <typename First, typename Second, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
Self& set(const A& value) {
flecs::set<P>(this->m_world, this->m_id, value);
return to_base();
}
template <typename First, typename Second, if_not_t< is_enum<Second>::value > = 0>
Self& set(Second second, const First& value) {
auto first = _::cpp_type<First>::id(this->m_world);
flecs::set(this->m_world, this->m_id, value,
ecs_pair(first, second));
return to_base();
}
template <typename First, typename Second, if_not_t< is_enum<Second>::value > = 0>
Self& set(Second second, First&& value) {
auto first = _::cpp_type<First>::id(this->m_world);
flecs::set(this->m_world, this->m_id, FLECS_FWD(value),
ecs_pair(first, second));
return to_base();
}
template <typename First, typename Second, if_t< is_enum<Second>::value > = 0>
Self& set(Second constant, const First& value) {
const auto& et = enum_type<Second>(this->m_world);
flecs::entity_t second = et.entity(constant);
return set<First>(second, value);
}
template <typename Second>
Self& set_second(entity_t first, const Second& value) {
auto second = _::cpp_type<Second>::id(this->m_world);
flecs::set(this->m_world, this->m_id, value,
ecs_pair(first, second));
return to_base();
}
template <typename Second>
Self& set_second(entity_t first, Second&& value) {
auto second = _::cpp_type<Second>::id(this->m_world);
flecs::set(this->m_world, this->m_id, FLECS_FWD(value),
ecs_pair(first, second));
return to_base();
}
template <typename First, typename Second>
Self& set_second(const Second& value) {
flecs::set<pair_object<First, Second>>(this->m_world, this->m_id, value);
return to_base();
}
template <typename Func, if_t< is_callable<Func>::value > = 0>
Self& set(const Func& func);
template<typename T, typename ... Args, typename A = actual_type_t<T>>
Self& emplace(Args&&... args) {
flecs::emplace<A>(this->m_world, this->m_id,
_::cpp_type<T>::id(this->m_world), FLECS_FWD(args)...);
return to_base();
}
template <typename First, typename Second, typename ... Args, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
Self& emplace(Args&&... args) {
flecs::emplace<A>(this->m_world, this->m_id,
ecs_pair(_::cpp_type<First>::id(this->m_world),
_::cpp_type<Second>::id(this->m_world)),
FLECS_FWD(args)...);
return to_base();
}
template <typename First, typename ... Args>
Self& emplace_first(flecs::entity_t second, Args&&... args) {
flecs::emplace<First>(this->m_world, this->m_id,
ecs_pair(_::cpp_type<First>::id(this->m_world), second),
FLECS_FWD(args)...);
return to_base();
}
template <typename Second, typename ... Args>
Self& emplace_second(flecs::entity_t first, Args&&... args) {
flecs::emplace<Second>(this->m_world, this->m_id,
ecs_pair(first, _::cpp_type<Second>::id(this->m_world)),
FLECS_FWD(args)...);
return to_base();
}
template <typename Func>
Self& with(const Func& func) {
ecs_id_t prev = ecs_set_with(this->m_world, this->m_id);
func();
ecs_set_with(this->m_world, prev);
return to_base();
}
template <typename First, typename Func>
Self& with(const Func& func) {
with(_::cpp_type<First>::id(this->m_world), func);
return to_base();
}
template <typename Func>
Self& with(entity_t first, const Func& func) {
ecs_id_t prev = ecs_set_with(this->m_world,
ecs_pair(first, this->m_id));
func();
ecs_set_with(this->m_world, prev);
return to_base();
}
template <typename Func>
Self& scope(const Func& func) {
ecs_entity_t prev = ecs_set_scope(this->m_world, this->m_id);
func();
ecs_set_scope(this->m_world, prev);
return to_base();
}
scoped_world scope() const {
return scoped_world(m_world, m_id);
}
Self& set_name(const char *name) {
ecs_set_name(this->m_world, this->m_id, name);
return to_base();
}
Self& set_alias(const char *name) {
ecs_set_alias(this->m_world, this->m_id, name);
return to_base();
}
# ifdef FLECS_DOC
Self& set_doc_name(const char *name) {
ecs_doc_set_name(m_world, m_id, name);
return to_base();
}
Self& set_doc_brief(const char *brief) {
ecs_doc_set_brief(m_world, m_id, brief);
return to_base();
}
Self& set_doc_detail(const char *detail) {
ecs_doc_set_detail(m_world, m_id, detail);
return to_base();
}
Self& set_doc_link(const char *link) {
ecs_doc_set_link(m_world, m_id, link);
return to_base();
}
Self& set_doc_color(const char *link) {
ecs_doc_set_color(m_world, m_id, link);
return to_base();
}
# endif
# ifdef FLECS_META
Self& unit(
const char *symbol,
flecs::entity_t prefix = 0,
flecs::entity_t base = 0,
flecs::entity_t over = 0,
int32_t factor = 0,
int32_t power = 0)
{
ecs_unit_desc_t desc = {};
desc.entity = this->m_id;
desc.symbol = const_cast<char*>(symbol);
desc.base = base;
desc.over = over;
desc.prefix = prefix;
desc.translation.factor = factor;
desc.translation.power = power;
ecs_unit_init(this->world(), &desc);
return to_base();
}
Self& unit(
flecs::entity_t prefix = 0,
flecs::entity_t base = 0,
flecs::entity_t over = 0,
int32_t factor = 0,
int32_t power = 0)
{
ecs_unit_desc_t desc = {};
desc.entity = this->m_id;
desc.base = base;
desc.over = over;
desc.prefix = prefix;
desc.translation.factor = factor;
desc.translation.power = power;
ecs_unit_init(this->world(), &desc);
return to_base();
}
Self& unit_prefix(
const char *symbol,
int32_t factor = 0,
int32_t power = 0)
{
ecs_unit_prefix_desc_t desc = {};
desc.entity = this->m_id;
desc.symbol = const_cast<char*>(symbol);
desc.translation.factor = factor;
desc.translation.power = power;
ecs_unit_prefix_init(this->world(), &desc);
return to_base();
}
Self& quantity(flecs::entity_t quantity) {
ecs_add_pair(this->world(), this->id(), flecs::Quantity, quantity);
return to_base();
}
template <typename Quantity>
Self& quantity() {
return this->quantity(_::cpp_type<Quantity>::id(this->world()));
}
Self& quantity() {
ecs_add_id(this->world(), this->id(), flecs::Quantity);
return to_base();
}
# endif
# ifdef FLECS_JSON
Self& set_json(
flecs::id_t e,
const char *json,
flecs::from_json_desc_t *desc = nullptr)
{
flecs::entity_t type = ecs_get_typeid(m_world, e);
if (!type) {
ecs_err("id is not a type");
return to_base();
}
void *ptr = ecs_get_mut_id(m_world, m_id, e);
ecs_assert(ptr != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_ptr_from_json(m_world, type, ptr, json, desc);
ecs_modified_id(m_world, m_id, e);
return to_base();
}
Self& set_json(
flecs::entity_t r,
flecs::entity_t t,
const char *json,
flecs::from_json_desc_t *desc = nullptr)
{
return set_json(ecs_pair(r, t), json, desc);
}
template <typename T>
Self& set_json(
const char *json,
flecs::from_json_desc_t *desc = nullptr)
{
return set_json(_::cpp_type<T>::id(m_world), json, desc);
}
template <typename R, typename T>
Self& set_json(
const char *json,
flecs::from_json_desc_t *desc = nullptr)
{
return set_json(
_::cpp_type<R>::id(m_world),
_::cpp_type<T>::id(m_world),
json, desc);
}
template <typename R>
Self& set_json(
flecs::entity_t t,
const char *json,
flecs::from_json_desc_t *desc = nullptr)
{
return set_json(
_::cpp_type<R>::id(m_world), t,
json, desc);
}
template <typename T>
Self& set_json_second(
flecs::entity_t r,
const char *json,
flecs::from_json_desc_t *desc = nullptr)
{
return set_json(
r, _::cpp_type<T>::id(m_world),
json, desc);
}
# endif
protected:
Self& to_base() {
return *static_cast<Self*>(this);
}
};
}
namespace flecs
{
struct entity : entity_builder<entity>
{
entity() : entity_builder<entity>() { }
explicit entity(world_t *world)
: entity_builder()
{
m_world = world;
m_id = ecs_new(world, 0);
}
explicit entity(const flecs::world_t *world, flecs::id_t id) {
m_world = const_cast<flecs::world_t*>(world);
m_id = id;
}
explicit entity(world_t *world, const char *name)
: entity_builder()
{
m_world = world;
ecs_entity_desc_t desc = {};
desc.name = name;
desc.sep = "::";
desc.root_sep = "::";
m_id = ecs_entity_init(world, &desc);
}
explicit entity(entity_t id)
: entity_builder( nullptr, id ) { }
template <typename T>
T* get_mut() const {
auto comp_id = _::cpp_type<T>::id(m_world);
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
return static_cast<T*>(ecs_get_mut_id(m_world, m_id, comp_id));
}
void* get_mut(entity_t comp) const {
return ecs_get_mut_id(m_world, m_id, comp);
}
template <typename First, typename Second, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
A* get_mut() const {
return static_cast<A*>(ecs_get_mut_id(m_world, m_id, ecs_pair(
_::cpp_type<First>::id(m_world),
_::cpp_type<Second>::id(m_world))));
}
template <typename First>
First* get_mut(entity_t second) const {
auto comp_id = _::cpp_type<First>::id(m_world);
ecs_assert(_::cpp_type<First>::size() != 0, ECS_INVALID_PARAMETER, NULL);
return static_cast<First*>(
ecs_get_mut_id(m_world, m_id, ecs_pair(comp_id, second)));
}
void* get_mut(entity_t first, entity_t second) const {
return ecs_get_mut_id(m_world, m_id, ecs_pair(first, second));
}
template <typename Second>
Second* get_mut_second(entity_t first) const {
auto second = _::cpp_type<Second>::id(m_world);
ecs_assert(_::cpp_type<Second>::size() != 0, ECS_INVALID_PARAMETER, NULL);
return static_cast<Second*>(
ecs_get_mut_id(m_world, m_id, ecs_pair(first, second)));
}
template <typename T>
void modified() const {
auto comp_id = _::cpp_type<T>::id(m_world);
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
this->modified(comp_id);
}
template <typename First, typename Second>
void modified() const {
this->modified<First>(_::cpp_type<Second>::id(m_world));
}
template <typename First>
void modified(entity_t second) const {
auto first = _::cpp_type<First>::id(m_world);
ecs_assert(_::cpp_type<First>::size() != 0, ECS_INVALID_PARAMETER, NULL);
this->modified(first, second);
}
void modified(entity_t first, entity_t second) const {
this->modified(ecs_pair(first, second));
}
void modified(entity_t comp) const {
ecs_modified_id(m_world, m_id, comp);
}
template <typename T>
ref<T> get_ref() const {
return ref<T>(m_world, m_id, _::cpp_type<T>::id(m_world));
}
template <typename First, typename Second, typename P = flecs::pair<First, Second>,
typename A = actual_type_t<P>>
ref<A> get_ref() const {
return ref<A>(m_world, m_id,
ecs_pair(_::cpp_type<First>::id(m_world),
_::cpp_type<Second>::id(m_world)));
}
template <typename First>
ref<First> get_ref(flecs::entity_t second) const {
return ref<First>(m_world, m_id,
ecs_pair(_::cpp_type<First>::id(m_world), second));
}
template <typename Second>
ref<Second> get_ref_second(flecs::entity_t first) const {
return ref<Second>(m_world, m_id,
ecs_pair(first, _::cpp_type<Second>::id(m_world)));
}
void flatten(flecs::entity_t r, const ecs_flatten_desc_t *desc = nullptr) {
ecs_flatten(m_world, ecs_pair(r, m_id), desc);
}
void clear() const {
ecs_clear(m_world, m_id);
}
void destruct() const {
ecs_delete(m_world, m_id);
}
flecs::entity_view view() const {
return flecs::entity_view(
const_cast<flecs::world_t*>(ecs_get_world(m_world)), m_id);
}
static
flecs::entity null(const flecs::world_t *world) {
flecs::entity result;
result.m_world = const_cast<flecs::world_t*>(world);
return result;
}
static
flecs::entity null() {
return flecs::entity();
}
# ifdef FLECS_JSON
const char* from_json(const char *json) {
return ecs_entity_from_json(m_world, m_id, json, nullptr);
}
# endif
};
}
#pragma once
namespace flecs
{
namespace _
{
struct component_binding_ctx {
void *on_add = nullptr;
void *on_remove = nullptr;
void *on_set = nullptr;
ecs_ctx_free_t free_on_add = nullptr;
ecs_ctx_free_t free_on_remove = nullptr;
ecs_ctx_free_t free_on_set = nullptr;
~component_binding_ctx() {
if (on_add && free_on_add) {
free_on_add(on_add);
}
if (on_remove && free_on_remove) {
free_on_remove(on_remove);
}
if (on_set && free_on_set) {
free_on_set(on_set);
}
}
};
struct term_ptr {
void *ptr;
bool is_ref;
};
template <typename ... Components>
struct term_ptrs {
using array = flecs::array<_::term_ptr, sizeof...(Components)>;
bool populate(const ecs_iter_t *iter) {
return populate(iter, 0, static_cast<
remove_reference_t<
remove_pointer_t<Components>>
*>(nullptr)...);
}
array m_terms;
private:
bool populate(const ecs_iter_t*, size_t) { return false; }
template <typename T, typename... Targs>
bool populate(const ecs_iter_t *iter, size_t index, T, Targs... comps) {
m_terms[index].ptr = iter->ptrs[index];
bool is_ref = iter->sources && iter->sources[index] != 0;
m_terms[index].is_ref = is_ref;
is_ref |= populate(iter, index + 1, comps ...);
return is_ref;
}
};
struct invoker { };
template <typename T, typename = int>
struct each_column { };
struct each_column_base {
each_column_base(const _::term_ptr& term, size_t row)
: m_term(term), m_row(row) { }
protected:
const _::term_ptr& m_term;
size_t m_row;
};
template <typename T>
struct each_column<T, if_t< !is_pointer<T>::value &&
!is_empty<actual_type_t<T>>::value && is_actual<T>::value > >
: each_column_base
{
each_column(const _::term_ptr& term, size_t row)
: each_column_base(term, row) { }
T& get_row() {
return static_cast<T*>(this->m_term.ptr)[this->m_row];
}
};
template <typename T>
struct each_column<T, if_t< !is_pointer<T>::value &&
!is_empty<actual_type_t<T>>::value && !is_actual<T>::value> >
: each_column_base
{
each_column(const _::term_ptr& term, size_t row)
: each_column_base(term, row) { }
T get_row() {
return static_cast<actual_type_t<T>*>(this->m_term.ptr)[this->m_row];
}
};
template <typename T>
struct each_column<T, if_t< is_empty<actual_type_t<T>>::value &&
!is_pointer<T>::value > >
: each_column_base
{
each_column(const _::term_ptr& term, size_t row)
: each_column_base(term, row) { }
T get_row() {
return actual_type_t<T>();
}
};
template <typename T>
struct each_column<T, if_t< is_pointer<T>::value &&
!is_empty<actual_type_t<T>>::value > >
: each_column_base
{
each_column(const _::term_ptr& term, size_t row)
: each_column_base(term, row) { }
T get_row() {
if (this->m_term.ptr) {
return &static_cast<actual_type_t<T>>(this->m_term.ptr)[this->m_row];
} else {
return nullptr;
}
}
};
template <typename T, typename = int>
struct each_ref_column : public each_column<T> {
each_ref_column(const _::term_ptr& term, size_t row)
: each_column<T>(term, row) {
if (term.is_ref) {
this->m_row = 0;
}
}
};
template <typename Func, typename ... Components>
struct each_invoker : public invoker {
static constexpr bool PassEntity =
(sizeof...(Components) + 1) == (arity<Func>::value);
static constexpr bool PassIter =
(sizeof...(Components) + 2) == (arity<Func>::value);
static_assert(arity<Func>::value > 0,
"each() must have at least one argument");
using Terms = typename term_ptrs<Components ...>::array;
template < if_not_t< is_same< decay_t<Func>, decay_t<Func>& >::value > = 0>
explicit each_invoker(Func&& func) noexcept
: m_func(FLECS_MOV(func)) { }
explicit each_invoker(const Func& func) noexcept
: m_func(func) { }
void invoke(ecs_iter_t *iter) const {
term_ptrs<Components...> terms;
if (terms.populate(iter)) {
invoke_callback< each_ref_column >(iter, m_func, 0, terms.m_terms);
} else {
invoke_callback< each_column >(iter, m_func, 0, terms.m_terms);
}
}
static void run(ecs_iter_t *iter) {
auto self = static_cast<const each_invoker*>(iter->binding_ctx);
ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL);
self->invoke(iter);
}
static void run_add(ecs_iter_t *iter) {
component_binding_ctx *ctx = reinterpret_cast<component_binding_ctx*>(
iter->binding_ctx);
iter->binding_ctx = ctx->on_add;
run(iter);
}
static void run_remove(ecs_iter_t *iter) {
component_binding_ctx *ctx = reinterpret_cast<component_binding_ctx*>(
iter->binding_ctx);
iter->binding_ctx = ctx->on_remove;
run(iter);
}
static void run_set(ecs_iter_t *iter) {
component_binding_ctx *ctx = reinterpret_cast<component_binding_ctx*>(
iter->binding_ctx);
iter->binding_ctx = ctx->on_set;
run(iter);
}
static bool instanced() {
return true;
}
private:
template <template<typename X, typename = int> class ColumnType,
typename... Args, if_t<
sizeof...(Components) == sizeof...(Args) && PassEntity> = 0>
static void invoke_callback(
ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps)
{
ECS_TABLE_LOCK(iter->world, iter->table);
ecs_world_t *world = iter->world;
size_t count = static_cast<size_t>(iter->count);
ecs_assert(count > 0, ECS_INVALID_OPERATION,
"no entities returned, use each() without flecs::entity argument");
for (size_t i = 0; i < count; i ++) {
func(flecs::entity(world, iter->entities[i]),
(ColumnType< remove_reference_t<Components> >(comps, i)
.get_row())...);
}
ECS_TABLE_UNLOCK(iter->world, iter->table);
}
template <template<typename X, typename = int> class ColumnType,
typename... Args, int Enabled = PassIter, if_t<
sizeof...(Components) == sizeof...(Args) && Enabled> = 0>
static void invoke_callback(
ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps)
{
size_t count = static_cast<size_t>(iter->count);
if (count == 0) {
count = 1;
}
flecs::iter it(iter);
ECS_TABLE_LOCK(iter->world, iter->table);
for (size_t i = 0; i < count; i ++) {
func(it, i, (ColumnType< remove_reference_t<Components> >(comps, i)
.get_row())...);
}
ECS_TABLE_UNLOCK(iter->world, iter->table);
}
template <template<typename X, typename = int> class ColumnType,
typename... Args, if_t<
sizeof...(Components) == sizeof...(Args) && !PassEntity && !PassIter> = 0>
static void invoke_callback(
ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps)
{
size_t count = static_cast<size_t>(iter->count);
if (count == 0) {
count = 1;
}
flecs::iter it(iter);
ECS_TABLE_LOCK(iter->world, iter->table);
for (size_t i = 0; i < count; i ++) {
func( (ColumnType< remove_reference_t<Components> >(comps, i)
.get_row())...);
}
ECS_TABLE_UNLOCK(iter->world, iter->table);
}
template <template<typename X, typename = int> class ColumnType,
typename... Args, if_t< sizeof...(Components) != sizeof...(Args) > = 0>
static void invoke_callback(ecs_iter_t *iter, const Func& func,
size_t index, Terms& columns, Args... comps)
{
invoke_callback<ColumnType>(
iter, func, index + 1, columns, comps..., columns[index]);
}
Func m_func;
};
template <typename Func, typename ... Components>
struct find_invoker : public invoker {
static constexpr bool PassEntity =
(sizeof...(Components) + 1) == (arity<Func>::value);
static constexpr bool PassIter =
(sizeof...(Components) + 2) == (arity<Func>::value);
static_assert(arity<Func>::value > 0,
"each() must have at least one argument");
using Terms = typename term_ptrs<Components ...>::array;
template < if_not_t< is_same< decay_t<Func>, decay_t<Func>& >::value > = 0>
explicit find_invoker(Func&& func) noexcept
: m_func(FLECS_MOV(func)) { }
explicit find_invoker(const Func& func) noexcept
: m_func(func) { }
flecs::entity invoke(ecs_iter_t *iter) const {
term_ptrs<Components...> terms;
if (terms.populate(iter)) {
return invoke_callback< each_ref_column >(iter, m_func, 0, terms.m_terms);
} else {
return invoke_callback< each_column >(iter, m_func, 0, terms.m_terms);
}
}
static bool instanced() {
return true;
}
private:
template <template<typename X, typename = int> class ColumnType,
typename... Args, if_t<
sizeof...(Components) == sizeof...(Args) && PassEntity> = 0>
static flecs::entity invoke_callback(
ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps)
{
ECS_TABLE_LOCK(iter->world, iter->table);
ecs_world_t *world = iter->world;
size_t count = static_cast<size_t>(iter->count);
flecs::entity result;
ecs_assert(count > 0, ECS_INVALID_OPERATION,
"no entities returned, use find() without flecs::entity argument");
for (size_t i = 0; i < count; i ++) {
if (func(flecs::entity(world, iter->entities[i]),
(ColumnType< remove_reference_t<Components> >(comps, i)
.get_row())...))
{
result = flecs::entity(world, iter->entities[i]);
break;
}
}
ECS_TABLE_UNLOCK(iter->world, iter->table);
return result;
}
template <template<typename X, typename = int> class ColumnType,
typename... Args, int Enabled = PassIter, if_t<
sizeof...(Components) == sizeof...(Args) && Enabled> = 0>
static flecs::entity invoke_callback(
ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps)
{
size_t count = static_cast<size_t>(iter->count);
if (count == 0) {
count = 1;
}
flecs::iter it(iter);
flecs::entity result;
ECS_TABLE_LOCK(iter->world, iter->table);
for (size_t i = 0; i < count; i ++) {
if (func(it, i, (ColumnType< remove_reference_t<Components> >(comps, i)
.get_row())...))
{
result = flecs::entity(iter->world, iter->entities[i]);
break;
}
}
ECS_TABLE_UNLOCK(iter->world, iter->table);
return result;
}
template <template<typename X, typename = int> class ColumnType,
typename... Args, if_t<
sizeof...(Components) == sizeof...(Args) && !PassEntity && !PassIter> = 0>
static flecs::entity invoke_callback(
ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps)
{
size_t count = static_cast<size_t>(iter->count);
if (count == 0) {
count = 1;
}
flecs::iter it(iter);
flecs::entity result;
ECS_TABLE_LOCK(iter->world, iter->table);
for (size_t i = 0; i < count; i ++) {
if (func( (ColumnType< remove_reference_t<Components> >(comps, i)
.get_row())...))
{
result = flecs::entity(iter->world, iter->entities[i]);
break;
}
}
ECS_TABLE_UNLOCK(iter->world, iter->table);
return result;
}
template <template<typename X, typename = int> class ColumnType,
typename... Args, if_t< sizeof...(Components) != sizeof...(Args) > = 0>
static flecs::entity invoke_callback(ecs_iter_t *iter, const Func& func,
size_t index, Terms& columns, Args... comps)
{
return invoke_callback<ColumnType>(
iter, func, index + 1, columns, comps..., columns[index]);
}
Func m_func;
};
template <typename Func, typename ... Components>
struct iter_invoker : invoker {
private:
static constexpr bool IterOnly = arity<Func>::value == 1;
using Terms = typename term_ptrs<Components ...>::array;
public:
template < if_not_t< is_same< decay_t<Func>, decay_t<Func>& >::value > = 0>
explicit iter_invoker(Func&& func) noexcept
: m_func(FLECS_MOV(func)) { }
explicit iter_invoker(const Func& func) noexcept
: m_func(func) { }
void invoke(ecs_iter_t *iter) const {
term_ptrs<Components...> terms;
terms.populate(iter);
invoke_callback(iter, m_func, 0, terms.m_terms);
}
static void run(ecs_iter_t *iter) {
auto self = static_cast<const iter_invoker*>(iter->binding_ctx);
ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL);
self->invoke(iter);
}
static bool instanced() {
return false;
}
private:
template <typename... Args, if_t<!sizeof...(Args) && IterOnly> = 0>
static void invoke_callback(ecs_iter_t *iter, const Func& func,
size_t, Terms&, Args...)
{
flecs::iter it(iter);
ECS_TABLE_LOCK(iter->world, iter->table);
func(it);
ECS_TABLE_UNLOCK(iter->world, iter->table);
}
template <typename... Targs, if_t<!IterOnly &&
(sizeof...(Targs) == sizeof...(Components))> = 0>
static void invoke_callback(ecs_iter_t *iter, const Func& func, size_t,
Terms&, Targs... comps)
{
flecs::iter it(iter);
ECS_TABLE_LOCK(iter->world, iter->table);
func(it, ( static_cast<
remove_reference_t<
remove_pointer_t<
actual_type_t<Components> > >* >
(comps.ptr))...);
ECS_TABLE_UNLOCK(iter->world, iter->table);
}
template <typename... Targs, if_t<!IterOnly &&
(sizeof...(Targs) != sizeof...(Components)) > = 0>
static void invoke_callback(ecs_iter_t *iter, const Func& func,
size_t index, Terms& columns, Targs... comps)
{
invoke_callback(iter, func, index + 1, columns, comps...,
columns[index]);
}
Func m_func;
};
template<typename ... Args>
struct entity_with_invoker_impl;
template<typename ... Args>
struct entity_with_invoker_impl<arg_list<Args ...>> {
using ColumnArray = flecs::array<int32_t, sizeof...(Args)>;
using ArrayType = flecs::array<void*, sizeof...(Args)>;
using DummyArray = flecs::array<int, sizeof...(Args)>;
using IdArray = flecs::array<id_t, sizeof...(Args)>;
static bool const_args() {
static flecs::array<bool, sizeof...(Args)> is_const_args ({
flecs::is_const<flecs::remove_reference_t<Args>>::value...
});
for (auto is_const : is_const_args) {
if (!is_const) {
return false;
}
}
return true;
}
static
bool get_ptrs(world_t *world, const ecs_record_t *r, ecs_table_t *table,
ArrayType& ptrs)
{
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
if (!ecs_table_column_count(table)) {
return false;
}
const flecs::world_t *real_world = ecs_get_world(world);
ColumnArray columns ({
ecs_table_get_column_index(real_world, table,
_::cpp_type<Args>().id(world))...
});
size_t i = 0;
for (int32_t column : columns) {
if (column == -1) {
return false;
}
ptrs[i ++] = ecs_record_get_column(r, column, 0);
}
return true;
}
static bool get_mut_ptrs(world_t *world, ecs_entity_t e, ArrayType& ptrs) {
size_t i = 0;
DummyArray dummy ({
(ptrs[i ++] = ecs_get_mut_id(world, e,
_::cpp_type<Args>().id(world)), 0)...
});
return true;
}
template <typename Func>
static bool invoke_read(world_t *world, entity_t e, const Func& func) {
const ecs_record_t *r = ecs_read_begin(world, e);
if (!r) {
return false;
}
ecs_table_t *table = r->table;
if (!table) {
return false;
}
ArrayType ptrs;
bool has_components;
if ((has_components = get_ptrs(world, r, table, ptrs))) {
invoke_callback(func, 0, ptrs);
}
ecs_read_end(r);
return has_components;
}
template <typename Func>
static bool invoke_write(world_t *world, entity_t e, const Func& func) {
ecs_record_t *r = ecs_write_begin(world, e);
if (!r) {
return false;
}
ecs_table_t *table = r->table;
if (!table) {
return false;
}
ArrayType ptrs;
bool has_components;
if ((has_components = get_ptrs(world, r, table, ptrs))) {
invoke_callback(func, 0, ptrs);
}
ecs_write_end(r);
return has_components;
}
template <typename Func>
static bool invoke_get(world_t *world, entity_t e, const Func& func) {
if (const_args()) {
return invoke_read(world, e, func);
} else {
return invoke_write(world, e, func);
}
}
static size_t store_added(IdArray& added, size_t elem, ecs_table_t *prev,
ecs_table_t *next, id_t id)
{
if (prev != next) {
added[elem] = id;
elem ++;
}
return elem;
}
template <typename Func>
static bool invoke_get_mut(world_t *world, entity_t id, const Func& func) {
flecs::world w(world);
ArrayType ptrs;
ecs_table_t *table = NULL;
if (!w.is_deferred()) {
ecs_assert(!w.is_stage(), ECS_INVALID_PARAMETER, NULL);
ecs_record_t *r = ecs_record_find(world, id);
if (r) {
table = r->table;
}
ecs_table_t *prev = table, *next;
size_t elem = 0;
IdArray added;
DummyArray dummy_before ({ (
next = ecs_table_add_id(world, prev, w.id<Args>()),
elem = store_added(added, elem, prev, next, w.id<Args>()),
prev = next, 0
)... });
(void)dummy_before;
if (table != next) {
ecs_type_t ids;
ids.array = added.ptr();
ids.count = static_cast<ecs_size_t>(elem);
ecs_commit(world, id, r, next, &ids, NULL);
table = next;
}
if (!get_ptrs(w, r, table, ptrs)) {
ecs_abort(ECS_INTERNAL_ERROR, NULL);
}
ECS_TABLE_LOCK(world, table);
} else {
get_mut_ptrs(world, id, ptrs);
}
invoke_callback(func, 0, ptrs);
if (!w.is_deferred()) {
ECS_TABLE_UNLOCK(world, table);
}
DummyArray dummy_after ({
( ecs_modified_id(world, id, w.id<Args>()), 0)...
});
(void)dummy_after;
return true;
}
private:
template <typename Func, typename ... TArgs,
if_t<sizeof...(TArgs) == sizeof...(Args)> = 0>
static void invoke_callback(
const Func& f, size_t, ArrayType&, TArgs&& ... comps)
{
f(*static_cast<typename base_arg_type<Args>::type*>(comps)...);
}
template <typename Func, typename ... TArgs,
if_t<sizeof...(TArgs) != sizeof...(Args)> = 0>
static void invoke_callback(const Func& f, size_t arg, ArrayType& ptrs,
TArgs&& ... comps)
{
invoke_callback(f, arg + 1, ptrs, comps..., ptrs[arg]);
}
};
template <typename Func, typename U = int>
struct entity_with_invoker {
static_assert(function_traits<Func>::value, "type is not callable");
};
template <typename Func>
struct entity_with_invoker<Func, if_t< is_callable<Func>::value > >
: entity_with_invoker_impl< arg_list_t<Func> >
{
static_assert(function_traits<Func>::arity > 0,
"function must have at least one argument");
};
}
}
namespace flecs {
template <typename ... Components>
struct iter_iterable;
template <typename ... Components>
struct page_iterable;
template <typename ... Components>
struct worker_iterable;
template <typename ... Components>
struct iterable {
template <typename Func>
void each(Func&& func) const {
each(nullptr, FLECS_FWD(func));
}
template <typename Func>
void each(flecs::world_t *world, Func&& func) const {
iterate<_::each_invoker>(world, FLECS_FWD(func),
this->next_each_action());
}
template <typename Func>
void each(flecs::iter& it, Func&& func) const {
iterate<_::each_invoker>(it.world(), FLECS_FWD(func),
this->next_each_action());
}
template <typename Func>
void each(flecs::entity e, Func&& func) const {
iterate<_::each_invoker>(e.world(), FLECS_FWD(func),
this->next_each_action());
}
template <typename Func>
flecs::entity find(Func&& func) const {
return iterate_find<_::find_invoker>(nullptr, FLECS_FWD(func),
this->next_each_action());
}
template <typename Func>
void iter(Func&& func) const {
iterate<_::iter_invoker>(nullptr, FLECS_FWD(func),
this->next_action());
}
template <typename Func>
void iter(flecs::world_t *world, Func&& func) const {
iterate<_::iter_invoker>(world, FLECS_FWD(func),
this->next_action());
}
template <typename Func>
void iter(flecs::iter& it, Func&& func) const {
iterate<_::iter_invoker>(it.world(), FLECS_FWD(func),
this->next_action());
}
template <typename Func>
void iter(flecs::entity e, Func&& func) const {
iterate<_::iter_invoker>(e.world(), FLECS_FWD(func),
this->next_action());
}
iter_iterable<Components...> iter(flecs::world_t *world = nullptr) const;
page_iterable<Components...> page(int32_t offset, int32_t limit);
worker_iterable<Components...> worker(int32_t index, int32_t count);
int32_t count() const {
return this->iter().count();
}
bool is_true() const {
return this->iter().is_true();
}
flecs::entity first() const {
return this->iter().first();
}
virtual ~iterable() { }
protected:
friend iter_iterable<Components...>;
friend page_iterable<Components...>;
friend worker_iterable<Components...>;
virtual ecs_iter_t get_iter(flecs::world_t *stage) const = 0;
virtual ecs_iter_next_action_t next_action() const = 0;
virtual ecs_iter_next_action_t next_each_action() const = 0;
template < template<typename Func, typename ... Comps> class Invoker, typename Func, typename NextFunc, typename ... Args>
void iterate(flecs::world_t *stage, Func&& func, NextFunc next, Args &&... args) const {
ecs_iter_t it = this->get_iter(stage);
if (Invoker<Func, Components...>::instanced()) {
ECS_BIT_SET(it.flags, EcsIterIsInstanced);
}
while (next(&it, FLECS_FWD(args)...)) {
Invoker<Func, Components...>(func).invoke(&it);
}
}
template < template<typename Func, typename ... Comps> class Invoker, typename Func, typename NextFunc, typename ... Args>
flecs::entity iterate_find(flecs::world_t *stage, Func&& func, NextFunc next, Args &&... args) const {
ecs_iter_t it = this->get_iter(stage);
if (Invoker<Func, Components...>::instanced()) {
ECS_BIT_SET(it.flags, EcsIterIsInstanced);
}
flecs::entity result;
while (!result && next(&it, FLECS_FWD(args)...)) {
result = Invoker<Func, Components...>(func).invoke(&it);
}
if (result) {
ecs_iter_fini(&it);
}
return result;
}
};
template <typename ... Components>
struct iter_iterable final : iterable<Components...> {
template <typename Iterable>
iter_iterable(Iterable *it, flecs::world_t *world)
{
m_it = it->get_iter(world);
m_next = it->next_action();
m_next_each = it->next_action();
}
iter_iterable<Components...>& set_var(int var_id, flecs::entity_t value) {
ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, 0);
ecs_iter_set_var(&m_it, var_id, value);
return *this;
}
# ifdef FLECS_RULES
iter_iterable<Components...>& set_var(const char *name, flecs::entity_t value) {
ecs_rule_iter_t *rit = &m_it.priv.iter.rule;
int var_id = ecs_rule_find_var(rit->rule, name);
ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, name);
ecs_iter_set_var(&m_it, var_id, value);
return *this;
}
# endif
# ifdef FLECS_JSON
flecs::string to_json(flecs::iter_to_json_desc_t *desc = nullptr) {
char *json = ecs_iter_to_json(m_it.real_world, &m_it, desc);
return flecs::string(json);
}
# endif
int32_t count() {
int32_t result = 0;
while (m_next_each(&m_it)) {
result += m_it.count;
}
return result;
}
bool is_true() {
bool result = m_next_each(&m_it);
if (result) {
ecs_iter_fini(&m_it);
}
return result;
}
flecs::entity first() {
flecs::entity result;
if (m_next_each(&m_it) && m_it.count) {
result = flecs::entity(m_it.world, m_it.entities[0]);
ecs_iter_fini(&m_it);
}
return result;
}
iter_iterable<Components...>& set_group(uint64_t group_id) {
ecs_query_set_group(&m_it, group_id);
return *this;
}
template <typename Group>
iter_iterable<Components...>& set_group() {
ecs_query_set_group(&m_it, _::cpp_type<Group>().id(m_it.real_world));
return *this;
}
protected:
ecs_iter_t get_iter(flecs::world_t *world) const {
if (world) {
ecs_iter_t result = m_it;
result.world = world;
return result;
}
return m_it;
}
ecs_iter_next_action_t next_action() const {
return m_next;
}
ecs_iter_next_action_t next_each_action() const {
return m_next_each;
}
private:
ecs_iter_t m_it;
ecs_iter_next_action_t m_next;
ecs_iter_next_action_t m_next_each;
};
template <typename ... Components>
iter_iterable<Components...> iterable<Components...>::iter(flecs::world_t *world) const
{
return iter_iterable<Components...>(this, world);
}
template <typename ... Components>
struct page_iterable final : iterable<Components...> {
template <typename Iterable>
page_iterable(int32_t offset, int32_t limit, Iterable *it)
: m_offset(offset)
, m_limit(limit)
{
m_chain_it = it->get_iter(nullptr);
}
protected:
ecs_iter_t get_iter(flecs::world_t*) const {
return ecs_page_iter(&m_chain_it, m_offset, m_limit);
}
ecs_iter_next_action_t next_action() const {
return ecs_page_next;
}
ecs_iter_next_action_t next_each_action() const {
return ecs_page_next;
}
private:
ecs_iter_t m_chain_it;
int32_t m_offset;
int32_t m_limit;
};
template <typename ... Components>
page_iterable<Components...> iterable<Components...>::page(
int32_t offset,
int32_t limit)
{
return page_iterable<Components...>(offset, limit, this);
}
template <typename ... Components>
struct worker_iterable final : iterable<Components...> {
worker_iterable(int32_t offset, int32_t limit, iterable<Components...> *it)
: m_offset(offset)
, m_limit(limit)
{
m_chain_it = it->get_iter(nullptr);
}
protected:
ecs_iter_t get_iter(flecs::world_t*) const {
return ecs_worker_iter(&m_chain_it, m_offset, m_limit);
}
ecs_iter_next_action_t next_action() const {
return ecs_worker_next;
}
ecs_iter_next_action_t next_each_action() const {
return ecs_worker_next;
}
private:
ecs_iter_t m_chain_it;
int32_t m_offset;
int32_t m_limit;
};
template <typename ... Components>
worker_iterable<Components...> iterable<Components...>::worker(
int32_t index,
int32_t count)
{
return worker_iterable<Components...>(index, count, this);
}
}
#pragma once
#include <ctype.h>
#include <stdio.h>
namespace flecs {
namespace _ {
#if defined(__GNUC__) || defined(_WIN32)
template <typename T>
inline static const char* type_name() {
static const size_t len = ECS_FUNC_TYPE_LEN(const char*, type_name, ECS_FUNC_NAME);
static char result[len + 1] = {};
static const size_t front_len = ECS_FUNC_NAME_FRONT(const char*, type_name);
return ecs_cpp_get_type_name(result, ECS_FUNC_NAME, len, front_len);
}
#else
#error "implicit component registration not supported"
#endif
template <typename T>
inline static const char* symbol_name() {
static const size_t len = ECS_FUNC_TYPE_LEN(const char*, symbol_name, ECS_FUNC_NAME);
static char result[len + 1] = {};
return ecs_cpp_get_symbol_name(result, type_name<T>(), len);
}
template <> inline const char* symbol_name<uint8_t>() {
return "u8";
}
template <> inline const char* symbol_name<uint16_t>() {
return "u16";
}
template <> inline const char* symbol_name<uint32_t>() {
return "u32";
}
template <> inline const char* symbol_name<uint64_t>() {
return "u64";
}
template <> inline const char* symbol_name<int8_t>() {
return "i8";
}
template <> inline const char* symbol_name<int16_t>() {
return "i16";
}
template <> inline const char* symbol_name<int32_t>() {
return "i32";
}
template <> inline const char* symbol_name<int64_t>() {
return "i64";
}
template <> inline const char* symbol_name<float>() {
return "f32";
}
template <> inline const char* symbol_name<double>() {
return "f64";
}
template<typename T, enable_if_t<
std::is_trivial<T>::value == true
>* = nullptr>
void register_lifecycle_actions(ecs_world_t*, ecs_entity_t) { }
template<typename T, enable_if_t<
std::is_trivial<T>::value == false
>* = nullptr>
void register_lifecycle_actions(
ecs_world_t *world,
ecs_entity_t component)
{
ecs_type_hooks_t cl{};
cl.ctor = ctor<T>();
cl.dtor = dtor<T>();
cl.copy = copy<T>();
cl.copy_ctor = copy_ctor<T>();
cl.move = move<T>();
cl.move_ctor = move_ctor<T>();
cl.ctor_move_dtor = ctor_move_dtor<T>();
cl.move_dtor = move_dtor<T>();
ecs_set_hooks_id( world, component, &cl);
}
template <typename T>
struct cpp_type_impl {
static void init(
entity_t entity,
bool allow_tag = true)
{
if (s_reset_count != ecs_cpp_reset_count_get()) {
reset();
}
if (s_id) {
ecs_assert(s_id == entity, ECS_INCONSISTENT_COMPONENT_ID,
type_name<T>());
ecs_assert(allow_tag == s_allow_tag, ECS_INVALID_PARAMETER, NULL);
return;
}
s_id = entity;
s_allow_tag = allow_tag;
s_size = sizeof(T);
s_alignment = alignof(T);
if (is_empty<T>::value && allow_tag) {
s_size = 0;
s_alignment = 0;
}
s_reset_count = ecs_cpp_reset_count_get();
}
static entity_t id_explicit(world_t *world = nullptr,
const char *name = nullptr, bool allow_tag = true, flecs::id_t id = 0,
bool is_component = true, bool *existing = nullptr)
{
if (!s_id) {
ecs_assert(world != nullptr, ECS_COMPONENT_NOT_REGISTERED, name);
} else {
ecs_assert(!id || s_id == id, ECS_INCONSISTENT_COMPONENT_ID, NULL);
}
if (!s_id || (world && !ecs_exists(world, s_id))) {
init(s_id ? s_id : id, allow_tag);
ecs_assert(!id || s_id == id, ECS_INTERNAL_ERROR, NULL);
const char *symbol = nullptr;
if (id) {
symbol = ecs_get_symbol(world, id);
}
if (!symbol) {
symbol = symbol_name<T>();
}
entity_t entity = ecs_cpp_component_register_explicit(
world, s_id, id, name, type_name<T>(), symbol,
s_size, s_alignment, is_component, existing);
s_id = entity;
#if FLECS_CPP_ENUM_REFLECTION_SUPPORT
_::init_enum<T>(world, entity);
#endif
}
ecs_assert(s_id != 0 && ecs_exists(world, s_id),
ECS_INTERNAL_ERROR, NULL);
return s_id;
}
static id_t id(world_t *world = nullptr, const char *name = nullptr,
bool allow_tag = true)
{
if (!registered(world)) {
ecs_entity_t prev_scope = 0;
ecs_id_t prev_with = 0;
if (world) {
prev_scope = ecs_set_scope(world, 0);
prev_with = ecs_set_with(world, 0);
}
bool existing;
id_explicit(world, name, allow_tag, 0, true, &existing);
if (size() && !existing) {
register_lifecycle_actions<T>(world, s_id);
}
if (prev_with) {
ecs_set_with(world, prev_with);
}
if (prev_scope) {
ecs_set_scope(world, prev_scope);
}
}
ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL);
return s_id;
}
static size_t size() {
ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL);
return s_size;
}
static size_t alignment() {
ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL);
return s_alignment;
}
static bool registered(flecs::world_t *world) {
if (s_reset_count != ecs_cpp_reset_count_get()) {
reset();
}
if (s_id == 0) {
return false;
}
if (world && !ecs_exists(world, s_id)) {
return false;
}
return true;
}
static void reset() {
s_id = 0;
s_size = 0;
s_alignment = 0;
s_allow_tag = true;
}
static entity_t s_id;
static size_t s_size;
static size_t s_alignment;
static bool s_allow_tag;
static int32_t s_reset_count;
};
template <typename T> entity_t cpp_type_impl<T>::s_id;
template <typename T> size_t cpp_type_impl<T>::s_size;
template <typename T> size_t cpp_type_impl<T>::s_alignment;
template <typename T> bool cpp_type_impl<T>::s_allow_tag( true );
template <typename T> int32_t cpp_type_impl<T>::s_reset_count;
template <typename T>
struct cpp_type<T, if_not_t< is_pair<T>::value >>
: cpp_type_impl<base_type_t<T>> { };
template <typename T>
struct cpp_type<T, if_t< is_pair<T>::value >>
{
static id_t id(world_t *world = nullptr) {
return ecs_pair(
cpp_type< pair_first_t<T> >::id(world),
cpp_type< pair_second_t<T> >::id(world));
}
};
}
struct untyped_component : entity {
using entity::entity;
# ifdef FLECS_META
untyped_component& member(flecs::entity_t type_id, flecs::entity_t unit, const char *name, int32_t count = 0, size_t offset = 0) {
ecs_entity_desc_t desc = {};
desc.name = name;
desc.add[0] = ecs_pair(flecs::ChildOf, m_id);
ecs_entity_t eid = ecs_entity_init(m_world, &desc);
ecs_assert(eid != 0, ECS_INTERNAL_ERROR, NULL);
flecs::entity e(m_world, eid);
Member m = {};
m.type = type_id;
m.unit = unit;
m.count = count;
m.offset = static_cast<int32_t>(offset);
e.set<Member>(m);
return *this;
}
untyped_component& member(flecs::entity_t type_id, const char* name, int32_t count = 0, size_t offset = 0) {
return member(type_id, 0, name, count, offset);
}
template <typename MemberType>
untyped_component& member(const char *name, int32_t count = 0, size_t offset = 0) {
flecs::entity_t type_id = _::cpp_type<MemberType>::id(m_world);
return member(type_id, name, count, offset);
}
template <typename MemberType>
untyped_component& member(flecs::entity_t unit, const char *name, int32_t count = 0, size_t offset = 0) {
flecs::entity_t type_id = _::cpp_type<MemberType>::id(m_world);
return member(type_id, unit, name, count, offset);
}
template <typename MemberType, typename UnitType>
untyped_component& member(const char *name, int32_t count = 0, size_t offset = 0) {
flecs::entity_t type_id = _::cpp_type<MemberType>::id(m_world);
flecs::entity_t unit_id = _::cpp_type<UnitType>::id(m_world);
return member(type_id, unit_id, name, count, offset);
}
template <typename MemberType, typename ComponentType, typename RealType = typename std::remove_extent<MemberType>::type>
untyped_component& member(const char* name, const MemberType ComponentType::* ptr) {
flecs::entity_t type_id = _::cpp_type<RealType>::id(m_world);
size_t offset = reinterpret_cast<size_t>(&(static_cast<ComponentType*>(nullptr)->*ptr));
return member(type_id, name, std::extent<MemberType>::value, offset);
}
template <typename MemberType, typename ComponentType, typename RealType = typename std::remove_extent<MemberType>::type>
untyped_component& member(flecs::entity_t unit, const char* name, const MemberType ComponentType::* ptr) {
flecs::entity_t type_id = _::cpp_type<RealType>::id(m_world);
size_t offset = reinterpret_cast<size_t>(&(static_cast<ComponentType*>(nullptr)->*ptr));
return member(type_id, unit, name, std::extent<MemberType>::value, offset);
}
template <typename UnitType, typename MemberType, typename ComponentType, typename RealType = typename std::remove_extent<MemberType>::type>
untyped_component& member(const char* name, const MemberType ComponentType::* ptr) {
flecs::entity_t type_id = _::cpp_type<RealType>::id(m_world);
flecs::entity_t unit_id = _::cpp_type<UnitType>::id(m_world);
size_t offset = reinterpret_cast<size_t>(&(static_cast<ComponentType*>(nullptr)->*ptr));
return member(type_id, unit_id, name, std::extent<MemberType>::value, offset);
}
untyped_component& constant(const char *name, int32_t value) {
ecs_add_id(m_world, m_id, _::cpp_type<flecs::Enum>::id(m_world));
ecs_entity_desc_t desc = {};
desc.name = name;
desc.add[0] = ecs_pair(flecs::ChildOf, m_id);
ecs_entity_t eid = ecs_entity_init(m_world, &desc);
ecs_assert(eid != 0, ECS_INTERNAL_ERROR, NULL);
ecs_set_id(m_world, eid,
ecs_pair(flecs::Constant, flecs::I32), sizeof(int32_t),
&value);
return *this;
}
untyped_component& bit(const char *name, uint32_t value) {
ecs_add_id(m_world, m_id, _::cpp_type<flecs::Bitmask>::id(m_world));
ecs_entity_desc_t desc = {};
desc.name = name;
desc.add[0] = ecs_pair(flecs::ChildOf, m_id);
ecs_entity_t eid = ecs_entity_init(m_world, &desc);
ecs_assert(eid != 0, ECS_INTERNAL_ERROR, NULL);
ecs_set_id(m_world, eid,
ecs_pair(flecs::Constant, flecs::U32), sizeof(uint32_t),
&value);
return *this;
}
untyped_component& range(double min, double max) {
const flecs::member_t *m = ecs_cpp_last_member(m_world, m_id);
if (!m) {
return *this;
}
flecs::world w(m_world);
flecs::entity me = w.entity(m->member);
flecs::MemberRanges *mr = me.get_mut<flecs::MemberRanges>();
mr->value.min = min;
mr->value.max = max;
me.modified<flecs::MemberRanges>();
return *this;
}
untyped_component& warning_range(double min, double max) {
const flecs::member_t *m = ecs_cpp_last_member(m_world, m_id);
if (!m) {
return *this;
}
flecs::world w(m_world);
flecs::entity me = w.entity(m->member);
flecs::MemberRanges *mr = me.get_mut<flecs::MemberRanges>();
mr->warning.min = min;
mr->warning.max = max;
me.modified<flecs::MemberRanges>();
return *this;
}
untyped_component& error_range(double min, double max) {
const flecs::member_t *m = ecs_cpp_last_member(m_world, m_id);
if (!m) {
return *this;
}
flecs::world w(m_world);
flecs::entity me = w.entity(m->member);
flecs::MemberRanges *mr = me.get_mut<flecs::MemberRanges>();
mr->error.min = min;
mr->error.max = max;
me.modified<flecs::MemberRanges>();
return *this;
}
# endif
# ifdef FLECS_METRICS
template <typename Kind>
untyped_component& metric(
flecs::entity_t parent = 0,
const char *brief = nullptr,
const char *name = nullptr);
# endif
};
template <typename T>
struct component : untyped_component {
component(
flecs::world_t *world,
const char *name = nullptr,
bool allow_tag = true,
flecs::id_t id = 0)
{
const char *n = name;
bool implicit_name = false;
if (!n) {
n = _::type_name<T>();
implicit_name = true;
}
if (_::cpp_type<T>::registered(world)) {
id = _::cpp_type<T>::id_explicit(world, name, allow_tag, id);
ecs_cpp_component_validate(world, id, n, _::symbol_name<T>(),
_::cpp_type<T>::size(),
_::cpp_type<T>::alignment(),
implicit_name);
} else {
if (implicit_name && (ecs_get_scope(world) != 0)) {
const char *start = strchr(n, '<'), *last_elem = NULL;
if (start) {
const char *ptr = start;
while (ptr[0] && (ptr[0] != ':') && (ptr > n)) {
ptr --;
}
if (ptr[0] == ':') {
last_elem = ptr;
}
} else {
last_elem = strrchr(n, ':');
}
if (last_elem) {
name = last_elem + 1;
}
}
bool existing;
id = ecs_cpp_component_register(world, id, n, _::symbol_name<T>(),
ECS_SIZEOF(T), ECS_ALIGNOF(T), implicit_name, &existing);
id = _::cpp_type<T>::id_explicit(world, name, allow_tag, id);
if (_::cpp_type<T>::size() && !existing) {
_::register_lifecycle_actions<T>(world, id);
}
}
m_world = world;
m_id = id;
}
template <typename Func>
component<T>& on_add(Func&& func) {
using Invoker = typename _::each_invoker<
typename std::decay<Func>::type, T>;
flecs::type_hooks_t h = get_hooks();
ecs_assert(h.on_add == nullptr, ECS_INVALID_OPERATION,
"on_add hook is already set");
BindingCtx *ctx = get_binding_ctx(h);
h.on_add = Invoker::run_add;
ctx->on_add = FLECS_NEW(Invoker)(FLECS_FWD(func));
ctx->free_on_add = reinterpret_cast<ecs_ctx_free_t>(
_::free_obj<Invoker>);
ecs_set_hooks_id(m_world, m_id, &h);
return *this;
}
template <typename Func>
component<T>& on_remove(Func&& func) {
using Invoker = typename _::each_invoker<
typename std::decay<Func>::type, T>;
flecs::type_hooks_t h = get_hooks();
ecs_assert(h.on_remove == nullptr, ECS_INVALID_OPERATION,
"on_remove hook is already set");
BindingCtx *ctx = get_binding_ctx(h);
h.on_remove = Invoker::run_remove;
ctx->on_remove = FLECS_NEW(Invoker)(FLECS_FWD(func));
ctx->free_on_remove = reinterpret_cast<ecs_ctx_free_t>(
_::free_obj<Invoker>);
ecs_set_hooks_id(m_world, m_id, &h);
return *this;
}
template <typename Func>
component<T>& on_set(Func&& func) {
using Invoker = typename _::each_invoker<
typename std::decay<Func>::type, T>;
flecs::type_hooks_t h = get_hooks();
ecs_assert(h.on_set == nullptr, ECS_INVALID_OPERATION,
"on_set hook is already set");
BindingCtx *ctx = get_binding_ctx(h);
h.on_set = Invoker::run_set;
ctx->on_set = FLECS_NEW(Invoker)(FLECS_FWD(func));
ctx->free_on_set = reinterpret_cast<ecs_ctx_free_t>(
_::free_obj<Invoker>);
ecs_set_hooks_id(m_world, m_id, &h);
return *this;
}
# ifdef FLECS_META
template <typename Func>
component& opaque(const Func& type_support) {
flecs::world world(m_world);
auto ts = type_support(world);
ts.desc.entity = _::cpp_type<T>::id(m_world);
ecs_opaque_init(m_world, &ts.desc);
return *this;
}
flecs::opaque<T> opaque(flecs::entity_t as_type) {
return flecs::opaque<T>(m_world).as_type(as_type);
}
flecs::opaque<T> opaque(flecs::entity as_type) {
return this->opaque(as_type.id());
}
flecs::opaque<T> opaque(flecs::untyped_component as_type) {
return this->opaque(as_type.id());
}
template <typename ElemType>
flecs::opaque<T, ElemType> opaque(flecs::id_t as_type) {
return flecs::opaque<T, ElemType>(m_world).as_type(as_type);
}
component<T>& constant(const char *name, T value) {
int32_t v = static_cast<int32_t>(value);
untyped_component::constant(name, v);
return *this;
}
# endif
private:
using BindingCtx = _::component_binding_ctx;
BindingCtx* get_binding_ctx(flecs::type_hooks_t& h){
BindingCtx *result = static_cast<BindingCtx*>(h.binding_ctx);
if (!result) {
result = FLECS_NEW(BindingCtx);
h.binding_ctx = result;
h.binding_ctx_free = reinterpret_cast<ecs_ctx_free_t>(
_::free_obj<BindingCtx>);
}
return result;
}
flecs::type_hooks_t get_hooks() {
const flecs::type_hooks_t* h = ecs_get_hooks_id(m_world, m_id);
if (h) {
return *h;
} else {
return {};
}
}
};
template <typename T>
flecs::entity_t type_id() {
if (_::cpp_type<T>::s_reset_count == ecs_cpp_reset_count_get()) {
return _::cpp_type<T>::s_id;
} else {
return 0;
}
}
inline void reset() {
ecs_cpp_reset_count_inc();
}
}
#pragma once
namespace flecs {
struct type {
type() : m_world(nullptr), m_type(nullptr) { }
type(world_t *world, const type_t *t)
: m_world(world)
, m_type(t) { }
flecs::string str() const {
return flecs::string(ecs_type_str(m_world, m_type));
}
int32_t count() const {
if (!m_type) {
return 0;
}
return m_type->count;
}
flecs::id_t* array() const {
if (!m_type) {
return nullptr;
}
return m_type->array;
}
flecs::id get(int32_t index) const {
ecs_assert(m_type != NULL, ECS_INVALID_PARAMETER, NULL);
ecs_assert(m_type->count > index, ECS_OUT_OF_RANGE, NULL);
if (!m_type) {
return flecs::id();
}
return flecs::id(m_world, m_type->array[index]);
}
flecs::id_t* begin() const {
return m_type->array;
}
flecs::id_t* end() const {
return &m_type->array[m_type->count];
}
operator const type_t*() const {
return m_type;
}
private:
world_t *m_world;
const type_t *m_type;
};
}
#pragma once
namespace flecs {
struct table {
table() : m_world(nullptr), m_table(nullptr) { }
table(world_t *world, table_t *t)
: m_world(world)
, m_table(t) { }
virtual ~table() { }
flecs::string str() const {
return flecs::string(ecs_table_str(m_world, m_table));
}
flecs::type type() const {
return flecs::type(m_world, ecs_table_get_type(m_table));
}
int32_t count() const {
return ecs_table_count(m_table);
}
int32_t type_index(flecs::id_t id) const {
return ecs_table_get_type_index(m_world, m_table, id);
}
template <typename T>
int32_t type_index() const {
return type_index(_::cpp_type<T>::id(m_world));
}
int32_t type_index(flecs::entity_t first, flecs::entity_t second) const {
return type_index(ecs_pair(first, second));
}
template <typename First>
int32_t type_index(flecs::entity_t second) const {
return type_index(_::cpp_type<First>::id(m_world), second);
}
template <typename First, typename Second>
int32_t type_index() const {
return type_index<First>(_::cpp_type<Second>::id(m_world));
}
int32_t column_index(flecs::id_t id) const {
return ecs_table_get_column_index(m_world, m_table, id);
}
template <typename T>
int32_t column_index() const {
return column_index(_::cpp_type<T>::id(m_world));
}
int32_t column_index(flecs::entity_t first, flecs::entity_t second) const {
return column_index(ecs_pair(first, second));
}
template <typename First>
int32_t column_index(flecs::entity_t second) const {
return column_index(_::cpp_type<First>::id(m_world), second);
}
template <typename First, typename Second>
int32_t column_index() const {
return column_index<First>(_::cpp_type<Second>::id(m_world));
}
bool has(flecs::id_t id) const {
return type_index(id) != -1;
}
template <typename T>
bool has() const {
return type_index<T>() != -1;
}
bool has(flecs::entity_t first, flecs::entity_t second) const {
return type_index(first, second) != -1;
}
template <typename First>
bool has(flecs::entity_t second) const {
return type_index<First>(second) != -1;
}
template <typename First, typename Second>
bool has() const {
return type_index<First, Second>() != -1;
}
virtual void* get_column(int32_t index) const {
return ecs_table_get_column(m_table, index, 0);
}
void* get(flecs::id_t id) const {
int32_t index = column_index(id);
if (index == -1) {
return NULL;
}
return get_column(index);
}
void* get(flecs::entity_t first, flecs::entity_t second) const {
return get(ecs_pair(first, second));
}
template <typename T, if_t< is_actual<T>::value > = 0>
T* get() const {
return static_cast<T*>(get(_::cpp_type<T>::id(m_world)));
}
template <typename T, if_t< is_enum<T>::value > = 0>
T* get() const {
return static_cast<T*>(get(_::cpp_type<T>::id(m_world)));
}
template <typename T, typename A = actual_type_t<T>,
if_t< flecs::is_pair<T>::value > = 0>
A* get() const {
return static_cast<A*>(get(_::cpp_type<T>::id(m_world)));
}
template <typename First>
First* get(flecs::entity_t second) const {
return static_cast<First*>(get(_::cpp_type<First>::id(m_world), second));
}
template <typename First, typename Second, typename P = flecs::pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
A* get() const {
return static_cast<A*>(get<First>(_::cpp_type<Second>::id(m_world)));
}
size_t column_size(int32_t index) {
return ecs_table_get_column_size(m_table, index);
}
int32_t depth(flecs::entity_t rel) {
return ecs_table_get_depth(m_world, m_table, rel);
}
template <typename Rel>
int32_t depth() {
return depth(_::cpp_type<Rel>::id(m_world));
}
operator table_t*() const {
return m_table;
}
protected:
world_t *m_world;
table_t *m_table;
};
struct table_range : table {
table_range()
: table()
, m_offset(0)
, m_count(0) { }
table_range(world_t *world, table_t *t, int32_t offset, int32_t count)
: table(world, t)
, m_offset(offset)
, m_count(count) { }
int32_t offset() const {
return m_offset;
}
int32_t count() const {
return m_count;
}
void* get_column(int32_t index) const override {
return ecs_table_get_column(m_table, index, m_offset);
}
private:
int32_t m_offset = 0;
int32_t m_count = 0;
};
}
#pragma once
namespace flecs {
inline flecs::entity id::entity() const {
ecs_assert(!is_pair(), ECS_INVALID_OPERATION, NULL);
ecs_assert(!flags(), ECS_INVALID_OPERATION, NULL);
return flecs::entity(m_world, m_id);
}
inline flecs::entity id::flags() const {
return flecs::entity(m_world, m_id & ECS_ID_FLAGS_MASK);
}
inline flecs::entity id::first() const {
ecs_assert(is_pair(), ECS_INVALID_OPERATION, NULL);
flecs::entity_t e = ECS_PAIR_FIRST(m_id);
if (m_world) {
return flecs::entity(m_world, ecs_get_alive(m_world, e));
} else {
return flecs::entity(e);
}
}
inline flecs::entity id::second() const {
flecs::entity_t e = ECS_PAIR_SECOND(m_id);
if (m_world) {
return flecs::entity(m_world, ecs_get_alive(m_world, e));
} else {
return flecs::entity(e);
}
}
inline flecs::entity id::add_flags(flecs::id_t flags) const {
return flecs::entity(m_world, m_id | flags);
}
inline flecs::entity id::remove_flags(flecs::id_t flags) const {
(void)flags;
ecs_assert((m_id & ECS_ID_FLAGS_MASK) == flags, ECS_INVALID_PARAMETER, NULL);
return flecs::entity(m_world, m_id & ECS_COMPONENT_MASK);
}
inline flecs::entity id::remove_flags() const {
return flecs::entity(m_world, m_id & ECS_COMPONENT_MASK);
}
inline flecs::entity id::remove_generation() const {
return flecs::entity(m_world, static_cast<uint32_t>(m_id));
}
inline flecs::world id::world() const {
return flecs::world(m_world);
}
inline flecs::entity id::type_id() const {
return flecs::entity(m_world, ecs_get_typeid(m_world, m_id));
}
template <typename T>
inline flecs::id world::id() const {
return flecs::id(m_world, _::cpp_type<T>::id(m_world));
}
template <typename ... Args>
inline flecs::id world::id(Args&&... args) const {
return flecs::id(m_world, FLECS_FWD(args)...);
}
template <typename First, typename Second>
inline flecs::id world::pair() const {
return flecs::id(
m_world,
ecs_pair(
_::cpp_type<First>::id(m_world),
_::cpp_type<Second>::id(m_world)));
}
template <typename First>
inline flecs::id world::pair(entity_t o) const {
ecs_assert(!ECS_IS_PAIR(o), ECS_INVALID_PARAMETER,
"cannot create nested pairs");
return flecs::id(
m_world,
ecs_pair(
_::cpp_type<First>::id(m_world),
o));
}
inline flecs::id world::pair(entity_t r, entity_t o) const {
ecs_assert(!ECS_IS_PAIR(r) && !ECS_IS_PAIR(o), ECS_INVALID_PARAMETER,
"cannot create nested pairs");
return flecs::id(
m_world,
ecs_pair(r, o));
}
}
#pragma once
namespace flecs {
template <typename T>
flecs::entity ref<T>::entity() const {
return flecs::entity(m_world, m_ref.entity);
}
template <typename Self>
template <typename Func, if_t< is_callable<Func>::value > >
inline Self& entity_builder<Self>::set(const Func& func) {
_::entity_with_invoker<Func>::invoke_get_mut(
this->m_world, this->m_id, func);
return to_base();
}
template <typename T, if_t< is_enum<T>::value > >
const T* entity_view::get() const {
entity_t r = _::cpp_type<T>::id(m_world);
entity_t c = ecs_get_target(m_world, m_id, r, 0);
if (c) {
const T* v = static_cast<const T*>(ecs_get_id(m_world, c, r));
ecs_assert(v != NULL, ECS_INTERNAL_ERROR,
"missing enum constant value");
return v;
} else {
return static_cast<const T*>(ecs_get_id(m_world, m_id, r));
}
}
template<typename First>
inline flecs::entity entity_view::target(int32_t index) const
{
return flecs::entity(m_world,
ecs_get_target(m_world, m_id, _::cpp_type<First>::id(m_world), index));
}
inline flecs::entity entity_view::target(
flecs::entity_t relationship,
int32_t index) const
{
return flecs::entity(m_world,
ecs_get_target(m_world, m_id, relationship, index));
}
inline flecs::entity entity_view::target_for(
flecs::entity_t relationship,
flecs::id_t id) const
{
return flecs::entity(m_world,
ecs_get_target_for_id(m_world, m_id, relationship, id));
}
template <typename T>
inline flecs::entity entity_view::target_for(flecs::entity_t relationship) const {
return target_for(relationship, _::cpp_type<T>::id(m_world));
}
template <typename First, typename Second>
inline flecs::entity entity_view::target_for(flecs::entity_t relationship) const {
return target_for(relationship, _::cpp_type<First, Second>::id(m_world));
}
inline flecs::entity entity_view::parent() const {
return target(flecs::ChildOf);
}
inline flecs::entity entity_view::mut(const flecs::world& stage) const {
ecs_assert(!stage.is_readonly(), ECS_INVALID_PARAMETER,
"cannot use readonly world/stage to create mutable handle");
return flecs::entity(m_id).set_stage(stage.c_ptr());
}
inline flecs::entity entity_view::mut(const flecs::iter& it) const {
ecs_assert(!it.world().is_readonly(), ECS_INVALID_PARAMETER,
"cannot use iterator created for readonly world/stage to create mutable handle");
return flecs::entity(m_id).set_stage(it.world().c_ptr());
}
inline flecs::entity entity_view::mut(const flecs::entity_view& e) const {
ecs_assert(!e.world().is_readonly(), ECS_INVALID_PARAMETER,
"cannot use entity created for readonly world/stage to create mutable handle");
return flecs::entity(m_id).set_stage(e.m_world);
}
inline flecs::entity entity_view::set_stage(world_t *stage) {
return flecs::entity(stage, m_id);
}
inline flecs::type entity_view::type() const {
return flecs::type(m_world, ecs_get_type(m_world, m_id));
}
inline flecs::table entity_view::table() const {
return flecs::table(m_world, ecs_get_table(m_world, m_id));
}
inline flecs::table_range entity_view::range() const {
ecs_record_t *r = ecs_record_find(m_world, m_id);
if (r) {
return flecs::table_range(m_world, r->table,
ECS_RECORD_TO_ROW(r->row), 1);
}
return flecs::table_range();
}
template <typename Func>
inline void entity_view::each(const Func& func) const {
const ecs_type_t *type = ecs_get_type(m_world, m_id);
if (!type) {
return;
}
const ecs_id_t *ids = type->array;
int32_t count = type->count;
for (int i = 0; i < count; i ++) {
ecs_id_t id = ids[i];
flecs::id ent(m_world, id);
func(ent);
if (ECS_PAIR_FIRST(id) == EcsUnion) {
ent = flecs::id(m_world, ECS_PAIR_SECOND(id),
ecs_get_target(m_world, m_id, ECS_PAIR_SECOND(id), 0));
func(ent);
}
}
}
template <typename Func>
inline void entity_view::each(flecs::id_t pred, flecs::id_t obj, const Func& func) const {
flecs::world_t *real_world = const_cast<flecs::world_t*>(
ecs_get_world(m_world));
const ecs_table_t *table = ecs_get_table(m_world, m_id);
if (!table) {
return;
}
const ecs_type_t *type = ecs_table_get_type(table);
if (!type) {
return;
}
flecs::id_t pattern = pred;
if (obj) {
pattern = ecs_pair(pred, obj);
}
int32_t cur = 0;
id_t *ids = type->array;
while (-1 != (cur = ecs_search_offset(real_world, table, cur, pattern, 0)))
{
flecs::id ent(m_world, ids[cur]);
func(ent);
cur ++;
}
}
template <typename Func>
inline void entity_view::each(const flecs::entity_view& rel, const Func& func) const {
return this->each(rel, flecs::Wildcard, [&](flecs::id id) {
flecs::entity obj = id.second();
func(obj);
});
}
template <typename Func, if_t< is_callable<Func>::value > >
inline bool entity_view::get(const Func& func) const {
return _::entity_with_invoker<Func>::invoke_get(m_world, m_id, func);
}
inline flecs::entity entity_view::lookup(const char *path, bool search_path) const {
ecs_assert(m_id != 0, ECS_INVALID_PARAMETER, "invalid lookup from null handle");
auto id = ecs_lookup_path_w_sep(m_world, m_id, path, "::", "::", search_path);
return flecs::entity(m_world, id);
}
inline flecs::entity entity_view::clone(bool copy_value, flecs::entity_t dst_id) const {
if (!dst_id) {
dst_id = ecs_new_id(m_world);
}
flecs::entity dst = flecs::entity(m_world, dst_id);
ecs_clone(m_world, dst_id, m_id, copy_value);
return dst;
}
template <typename... Args>
inline flecs::entity world::entity(Args &&... args) const {
return flecs::entity(m_world, FLECS_FWD(args)...);
}
template <typename E, if_t< is_enum<E>::value >>
inline flecs::id world::id(E value) const {
flecs::entity_t constant = enum_type<E>(m_world).entity(value);
return flecs::id(m_world, constant);
}
template <typename E, if_t< is_enum<E>::value >>
inline flecs::entity world::entity(E value) const {
flecs::entity_t constant = enum_type<E>(m_world).entity(value);
return flecs::entity(m_world, constant);
}
template <typename T>
inline flecs::entity world::entity(const char *name) const {
return flecs::entity(m_world,
_::cpp_type<T>::id_explicit(m_world, name, true, 0, false) );
}
template <typename... Args>
inline flecs::entity world::prefab(Args &&... args) const {
flecs::entity result = flecs::entity(m_world, FLECS_FWD(args)...);
result.add(flecs::Prefab);
return result;
}
template <typename T>
inline flecs::entity world::prefab(const char *name) const {
flecs::entity result = flecs::component<T>(m_world, name, true);
result.add(flecs::Prefab);
return result;
}
}
#pragma once
namespace flecs {
template <typename T, typename... Args>
inline flecs::component<T> world::component(Args &&... args) const {
return flecs::component<T>(m_world, FLECS_FWD(args)...);
}
template <typename... Args>
inline flecs::untyped_component world::component(Args &&... args) const {
return flecs::untyped_component(m_world, FLECS_FWD(args)...);
}
}
#pragma once
#pragma once
#pragma once
#include <stdio.h>
namespace flecs {
namespace _ {
template <typename T, if_t< is_const_p<T>::value > = 0>
static constexpr flecs::inout_kind_t type_to_inout() {
return flecs::In;
}
template <typename T, if_t< is_reference<T>::value > = 0>
static constexpr flecs::inout_kind_t type_to_inout() {
return flecs::Out;
}
template <typename T, if_not_t<
is_const_p<T>::value || is_reference<T>::value > = 0>
static constexpr flecs::inout_kind_t type_to_inout() {
return flecs::InOutDefault;
}
template <typename T, if_t< is_pointer<T>::value > = 0>
static constexpr flecs::oper_kind_t type_to_oper() {
return flecs::Optional;
}
template <typename T, if_not_t< is_pointer<T>::value > = 0>
static constexpr flecs::oper_kind_t type_to_oper() {
return flecs::And;
}
template <typename ... Components>
struct sig {
sig(flecs::world_t *world)
: m_world(world)
, ids({ (_::cpp_type<Components>::id(world))... })
, inout ({ (type_to_inout<Components>())... })
, oper ({ (type_to_oper<Components>())... })
{ }
flecs::world_t *m_world;
flecs::array<flecs::id_t, sizeof...(Components)> ids;
flecs::array<flecs::inout_kind_t, sizeof...(Components)> inout;
flecs::array<flecs::oper_kind_t, sizeof...(Components)> oper;
template <typename Builder>
void populate(const Builder& b) {
size_t i = 0;
for (auto id : ids) {
if (!(id & ECS_ID_FLAGS_MASK)) {
const flecs::type_info_t *ti = ecs_get_type_info(m_world, id);
if (ti) {
ecs_assert(!ti->size || !ecs_has_id(m_world, id, flecs::Union),
ECS_INVALID_PARAMETER,
"use term() method to add union relationship");
}
}
b->term(id).inout(inout[i]).oper(oper[i]);
i ++;
}
}
};
} }
namespace flecs
{
template<typename Base>
struct term_id_builder_i {
term_id_builder_i() : m_term_id(nullptr) { }
virtual ~term_id_builder_i() { }
Base& self() {
this->assert_term_id();
m_term_id->flags |= flecs::Self;
return *this;
}
Base& up(flecs::entity_t trav = 0) {
this->assert_term_id();
m_term_id->flags |= flecs::Up;
if (trav) {
m_term_id->trav = trav;
}
return *this;
}
template <typename Trav>
Base& up() {
return this->up(_::cpp_type<Trav>::id(this->world_v()));
}
Base& cascade(flecs::entity_t trav = 0) {
this->assert_term_id();
m_term_id->flags |= flecs::Cascade;
if (trav) {
m_term_id->trav = trav;
}
return *this;
}
template <typename Trav>
Base& cascade() {
return this->cascade(_::cpp_type<Trav>::id(this->world_v()));
}
Base& parent() {
this->assert_term_id();
m_term_id->flags |= flecs::Parent;
return *this;
}
Base& trav(flecs::entity_t trav, flecs::flags32_t flags = 0) {
this->assert_term_id();
m_term_id->trav = trav;
m_term_id->flags |= flags;
return *this;
}
Base& id(flecs::entity_t id) {
this->assert_term_id();
m_term_id->id = id;
return *this;
}
Base& entity(flecs::entity_t entity) {
this->assert_term_id();
m_term_id->flags = flecs::IsEntity;
m_term_id->id = entity;
return *this;
}
Base& name(const char *name) {
this->assert_term_id();
m_term_id->flags |= flecs::IsEntity;
m_term_id->name = const_cast<char*>(name);
return *this;
}
Base& var(const char *var_name) {
this->assert_term_id();
m_term_id->flags |= flecs::IsVariable;
m_term_id->name = const_cast<char*>(var_name);
return *this;
}
Base& flags(flecs::flags32_t flags) {
this->assert_term_id();
m_term_id->flags = flags;
return *this;
}
ecs_term_id_t *m_term_id;
protected:
virtual flecs::world_t* world_v() = 0;
private:
void assert_term_id() {
ecs_assert(m_term_id != NULL, ECS_INVALID_PARAMETER,
"no active term (call .term() first)");
}
operator Base&() {
return *static_cast<Base*>(this);
}
};
template<typename Base>
struct term_builder_i : term_id_builder_i<Base> {
term_builder_i() : m_term(nullptr) { }
term_builder_i(ecs_term_t *term_ptr) {
set_term(term_ptr);
}
Base& term(id_t id) {
return this->id(id);
}
Base& src() {
this->assert_term();
this->m_term_id = &m_term->src;
return *this;
}
Base& first() {
this->assert_term();
this->m_term_id = &m_term->first;
return *this;
}
Base& second() {
this->assert_term();
this->m_term_id = &m_term->second;
return *this;
}
Base& src(flecs::entity_t id) {
this->src();
this->id(id);
return *this;
}
template<typename T>
Base& src() {
this->src(_::cpp_type<T>::id(this->world_v()));
return *this;
}
Base& src(const char *name) {
ecs_assert(name != NULL, ECS_INVALID_PARAMETER, NULL);
this->src();
if (name[0] == '$') {
this->var(&name[1]);
} else {
this->name(name);
}
return *this;
}
Base& first(flecs::entity_t id) {
this->first();
this->id(id);
return *this;
}
template<typename T>
Base& first() {
this->first(_::cpp_type<T>::id(this->world_v()));
return *this;
}
Base& first(const char *name) {
ecs_assert(name != NULL, ECS_INVALID_PARAMETER, NULL);
this->first();
if (name[0] == '$') {
this->var(&name[1]);
} else {
this->name(name);
}
return *this;
}
Base& second(flecs::entity_t id) {
this->second();
this->id(id);
return *this;
}
template<typename T>
Base& second() {
this->second(_::cpp_type<T>::id(this->world_v()));
return *this;
}
Base& second(const char *name) {
ecs_assert(name != NULL, ECS_INVALID_PARAMETER, NULL);
this->second();
if (name[0] == '$') {
this->var(&name[1]);
} else {
this->name(name);
}
return *this;
}
Base& role(id_t role) {
this->assert_term();
m_term->id_flags = role;
return *this;
}
Base& inout(flecs::inout_kind_t inout) {
this->assert_term();
m_term->inout = static_cast<ecs_inout_kind_t>(inout);
return *this;
}
Base& inout_stage(flecs::inout_kind_t inout) {
this->assert_term();
m_term->inout = static_cast<ecs_inout_kind_t>(inout);
if (m_term->oper != EcsNot) {
this->src().entity(0);
}
return *this;
}
Base& write() {
return this->inout_stage(flecs::Out);
}
Base& read() {
return this->inout_stage(flecs::In);
}
Base& read_write() {
return this->inout_stage(flecs::InOut);
}
Base& in() {
return this->inout(flecs::In);
}
Base& out() {
return this->inout(flecs::Out);
}
Base& inout() {
return this->inout(flecs::InOut);
}
Base& inout_none() {
return this->inout(flecs::InOutNone);
}
Base& oper(flecs::oper_kind_t oper) {
this->assert_term();
m_term->oper = static_cast<ecs_oper_kind_t>(oper);
return *this;
}
Base& and_() {
return this->oper(flecs::And);
}
Base& or_() {
return this->oper(flecs::Or);
}
Base& not_() {
return this->oper(flecs::Not);
}
Base& optional() {
return this->oper(flecs::Optional);
}
Base& and_from() {
return this->oper(flecs::AndFrom);
}
Base& or_from() {
return this->oper(flecs::OrFrom);
}
Base& not_from() {
return this->oper(flecs::NotFrom);
}
Base& singleton() {
this->assert_term();
ecs_assert(m_term->id || m_term->first.id, ECS_INVALID_PARAMETER,
"no component specified for singleton");
flecs::id_t sid = m_term->id;
if (!sid) {
sid = m_term->first.id;
}
ecs_assert(sid != 0, ECS_INVALID_PARAMETER, NULL);
if (!ECS_IS_PAIR(sid)) {
m_term->src.id = sid;
} else {
m_term->src.id = ecs_pair_first(world(), sid);
}
return *this;
}
Base& filter() {
m_term->src.flags |= flecs::Filter;
return *this;
}
ecs_term_t *m_term;
protected:
virtual flecs::world_t* world_v() = 0;
void set_term(ecs_term_t *term) {
m_term = term;
if (term) {
this->m_term_id = &m_term->src; } else {
this->m_term_id = nullptr;
}
}
private:
void assert_term() {
ecs_assert(m_term != NULL, ECS_INVALID_PARAMETER,
"no active term (call .term() first)");
}
operator Base&() {
return *static_cast<Base*>(this);
}
};
}
namespace flecs {
struct term final : term_builder_i<term> {
term()
: term_builder_i<term>(&value)
, value({})
, m_world(nullptr) { value.move = true; }
term(flecs::world_t *world_ptr)
: term_builder_i<term>(&value)
, value({})
, m_world(world_ptr) { value.move = true; }
term(flecs::world_t *world_ptr, ecs_term_t t)
: term_builder_i<term>(&value)
, value({})
, m_world(world_ptr) {
value = t;
value.move = false;
this->set_term(&value);
}
term(flecs::world_t *world_ptr, id_t id)
: term_builder_i<term>(&value)
, value({})
, m_world(world_ptr) {
if (id & ECS_ID_FLAGS_MASK) {
value.id = id;
} else {
value.first.id = id;
}
value.move = false;
this->set_term(&value);
}
term(flecs::world_t *world_ptr, entity_t r, entity_t o)
: term_builder_i<term>(&value)
, value({})
, m_world(world_ptr) {
value.id = ecs_pair(r, o);
value.move = false;
this->set_term(&value);
}
term(id_t id)
: term_builder_i<term>(&value)
, value({})
, m_world(nullptr) {
if (id & ECS_ID_FLAGS_MASK) {
value.id = id;
} else {
value.first.id = id;
}
value.move = true;
}
term(id_t r, id_t o)
: term_builder_i<term>(&value)
, value({})
, m_world(nullptr) {
value.id = ecs_pair(r, o);
value.move = true;
}
term(const term& t) : term_builder_i<term>(&value) {
m_world = t.m_world;
value = ecs_term_copy(&t.value);
this->set_term(&value);
}
term(term&& t) : term_builder_i<term>(&value) {
m_world = t.m_world;
value = ecs_term_move(&t.value);
t.reset();
this->set_term(&value);
}
term& operator=(const term& t) {
ecs_assert(m_world == t.m_world, ECS_INVALID_PARAMETER, NULL);
ecs_term_fini(&value);
value = ecs_term_copy(&t.value);
this->set_term(&value);
return *this;
}
term& operator=(term&& t) {
ecs_assert(m_world == t.m_world, ECS_INVALID_PARAMETER, NULL);
ecs_term_fini(&value);
value = t.value;
this->set_term(&value);
t.reset();
return *this;
}
~term() {
ecs_term_fini(&value);
}
void reset() {
value = {};
this->set_term(nullptr);
}
int finalize() {
return ecs_term_finalize(m_world, &value);
}
bool is_set() {
return ecs_term_is_initialized(&value);
}
flecs::id id() {
return flecs::id(m_world, value.id);
}
flecs::inout_kind_t inout() {
return static_cast<flecs::inout_kind_t>(value.inout);
}
flecs::oper_kind_t oper() {
return static_cast<flecs::oper_kind_t>(value.oper);
}
flecs::entity get_src() {
return flecs::entity(m_world, value.src.id);
}
flecs::entity get_first() {
return flecs::entity(m_world, value.first.id);
}
flecs::entity get_second() {
return flecs::entity(m_world, value.second.id);
}
ecs_term_t move() {
return ecs_term_move(&value);
}
ecs_term_t value;
protected:
flecs::world_t* world_v() override { return m_world; }
private:
flecs::world_t *m_world;
};
template <typename... Args>
inline flecs::term world::term(Args &&... args) const {
return flecs::term(m_world, FLECS_FWD(args)...);
}
template <typename T>
inline flecs::term world::term() const {
return flecs::term(m_world, _::cpp_type<T>::id(m_world));
}
template <typename First, typename Second>
inline flecs::term world::term() const {
return flecs::term(m_world, ecs_pair(
_::cpp_type<First>::id(m_world),
_::cpp_type<Second>::id(m_world)));
}
}
#pragma once
#pragma once
#pragma once
namespace flecs {
namespace _ {
#define FLECS_TBUILDER template<typename ... Components> class
#define FLECS_IBUILDER template<typename IBase, typename ... Components> class
template<FLECS_TBUILDER T, typename TDesc, typename Base, FLECS_IBUILDER IBuilder, typename ... Components>
struct builder : IBuilder<Base, Components ...>
{
using IBase = IBuilder<Base, Components ...>;
public:
builder(flecs::world_t *world)
: IBase(&m_desc)
, m_desc{}
, m_world(world) { }
builder(const builder& f)
: IBase(&m_desc, f.m_term_index)
{
m_world = f.m_world;
m_desc = f.m_desc;
}
builder(builder&& f)
: builder<T, TDesc, Base, IBuilder, Components...>(f) { }
operator TDesc*() {
return &m_desc;
}
T<Components ...> build() {
return T<Components...>(m_world, *static_cast<Base*>(this));
}
protected:
flecs::world_t* world_v() override { return m_world; }
TDesc m_desc;
flecs::world_t *m_world;
};
#undef FLECS_TBUILDER
#undef FLECS_IBUILDER
} }
#pragma once
namespace flecs
{
template<typename Base, typename ... Components>
struct filter_builder_i : term_builder_i<Base> {
filter_builder_i(ecs_filter_desc_t *desc, int32_t term_index = 0)
: m_term_index(term_index)
, m_expr_count(0)
, m_desc(desc) { }
Base& instanced() {
m_desc->instanced = true;
return *this;
}
Base& filter_flags(ecs_flags32_t flags) {
m_desc->flags |= flags;
return *this;
}
Base& expr(const char *expr) {
ecs_check(m_expr_count == 0, ECS_INVALID_OPERATION,
"filter_builder::expr() called more than once");
m_desc->expr = expr;
m_expr_count ++;
error:
return *this;
}
template <typename ... Args>
Base& with(Args&&... args) {
return this->term(FLECS_FWD(args)...);
}
template <typename T, typename ... Args>
Base& with(Args&&... args) {
return this->term<T>(FLECS_FWD(args)...);
}
template <typename First, typename Second>
Base& with() {
return this->term<First, Second>();
}
template <typename ... Args>
Base& without(Args&&... args) {
return this->term(FLECS_FWD(args)...).not_();
}
template <typename T, typename ... Args>
Base& without(Args&&... args) {
return this->term<T>(FLECS_FWD(args)...).not_();
}
template <typename First, typename Second>
Base& without() {
return this->term<First, Second>().not_();
}
Base& write() {
term_builder_i<Base>::write();
return *this;
}
template <typename ... Args>
Base& write(Args&&... args) {
return this->term(FLECS_FWD(args)...).write();
}
template <typename T, typename ... Args>
Base& write(Args&&... args) {
return this->term<T>(FLECS_FWD(args)...).write();
}
template <typename First, typename Second>
Base& write() {
return this->term<First, Second>().write();
}
Base& read() {
term_builder_i<Base>::read();
return *this;
}
template <typename ... Args>
Base& read(Args&&... args) {
return this->term(FLECS_FWD(args)...).read();
}
template <typename T, typename ... Args>
Base& read(Args&&... args) {
return this->term<T>(FLECS_FWD(args)...).read();
}
template <typename First, typename Second>
Base& read() {
return this->term<First, Second>().read();
}
Base& scope_open() {
return this->with(flecs::ScopeOpen).entity(0);
}
Base& scope_close() {
return this->with(flecs::ScopeClose).entity(0);
}
Base& term() {
if (this->m_term) {
ecs_check(ecs_term_is_initialized(this->m_term),
ECS_INVALID_OPERATION,
"filter_builder::term() called without initializing term");
}
if (m_term_index >= FLECS_TERM_DESC_MAX) {
if (m_term_index == FLECS_TERM_DESC_MAX) {
m_desc->terms_buffer = ecs_os_calloc_n(
ecs_term_t, m_term_index + 1);
ecs_os_memcpy_n(m_desc->terms_buffer, m_desc->terms,
ecs_term_t, m_term_index);
ecs_os_memset_n(m_desc->terms, 0,
ecs_term_t, FLECS_TERM_DESC_MAX);
} else {
m_desc->terms_buffer = ecs_os_realloc_n(m_desc->terms_buffer,
ecs_term_t, m_term_index + 1);
}
m_desc->terms_buffer_count = m_term_index + 1;
this->set_term(&m_desc->terms_buffer[m_term_index]);
} else {
this->set_term(&m_desc->terms[m_term_index]);
}
m_term_index ++;
error:
return *this;
}
Base& term_at(int32_t term_index) {
ecs_assert(term_index > 0, ECS_INVALID_PARAMETER, NULL);
int32_t prev_index = m_term_index;
m_term_index = term_index - 1;
this->term();
m_term_index = prev_index;
ecs_assert(ecs_term_is_initialized(this->m_term),
ECS_INVALID_PARAMETER, NULL);
return *this;
}
Base& arg(int32_t term_index) {
return this->term_at(term_index);
}
template<typename T>
Base& term() {
this->term();
*this->m_term = flecs::term(_::cpp_type<T>::id(this->world_v())).move();
this->m_term->inout = static_cast<ecs_inout_kind_t>(
_::type_to_inout<T>());
return *this;
}
Base& term(id_t id) {
this->term();
*this->m_term = flecs::term(id).move();
return *this;
}
Base& term(const char *name) {
this->term();
*this->m_term = flecs::term().first(name).move();
return *this;
}
Base& term(const char *first, const char *second) {
this->term();
*this->m_term = flecs::term().first(first).second(second).move();
return *this;
}
Base& term(entity_t r, entity_t o) {
this->term();
*this->m_term = flecs::term(r, o).move();
return *this;
}
Base& term(entity_t r, const char *o) {
this->term();
*this->m_term = flecs::term(r).second(o).move();
return *this;
}
template<typename First>
Base& term(id_t o) {
return this->term(_::cpp_type<First>::id(this->world_v()), o);
}
template<typename First>
Base& term(const char *second) {
return this->term(_::cpp_type<First>::id(this->world_v())).second(second);
}
template<typename First, typename Second>
Base& term() {
return this->term<First>(_::cpp_type<Second>::id(this->world_v()));
}
template <typename E, if_t< is_enum<E>::value > = 0>
Base& term(E value) {
flecs::entity_t r = _::cpp_type<E>::id(this->world_v());
auto o = enum_type<E>(this->world_v()).entity(value);
return this->term(r, o);
}
Base& term(flecs::term& term) {
this->term();
*this->m_term = term.move();
return *this;
}
Base& term(flecs::term&& term) {
this->term();
*this->m_term = term.move();
return *this;
}
protected:
virtual flecs::world_t* world_v() = 0;
int32_t m_term_index;
int32_t m_expr_count;
private:
operator Base&() {
return *static_cast<Base*>(this);
}
ecs_filter_desc_t *m_desc;
};
}
namespace flecs {
namespace _ {
template <typename ... Components>
using filter_builder_base = builder<
filter, ecs_filter_desc_t, filter_builder<Components...>,
filter_builder_i, Components ...>;
}
template <typename ... Components>
struct filter_builder final : _::filter_builder_base<Components...> {
filter_builder(flecs::world_t* world, const char *name = nullptr)
: _::filter_builder_base<Components...>(world)
{
_::sig<Components...>(world).populate(this);
if (name != nullptr) {
ecs_entity_desc_t entity_desc = {};
entity_desc.name = name;
entity_desc.sep = "::";
entity_desc.root_sep = "::";
this->m_desc.entity = ecs_entity_init(world, &entity_desc);
}
}
template <typename Func>
void each(Func&& func) {
this->build().each(FLECS_FWD(func));
}
};
}
namespace flecs
{
struct filter_base {
filter_base()
: m_world(nullptr)
, m_filter({})
, m_filter_ptr(nullptr) { }
filter_base(world_t *world, const ecs_filter_t *filter)
: m_world(world)
, m_filter({})
, m_filter_ptr(filter) { }
filter_base(world_t *world, ecs_filter_t *filter)
: m_world(world)
, m_filter_ptr(&m_filter) {
ecs_filter_move(&m_filter, filter);
}
filter_base(world_t *world, ecs_filter_desc_t *desc)
: m_world(world)
{
desc->storage = &m_filter;
if (ecs_filter_init(world, desc) == NULL) {
ecs_abort(ECS_INVALID_PARAMETER, NULL);
}
if (desc->terms_buffer) {
ecs_os_free(desc->terms_buffer);
}
m_filter_ptr = &m_filter;
}
filter_base(const filter_base& obj) {
this->m_world = obj.m_world;
if (obj.m_filter_ptr) {
this->m_filter_ptr = &this->m_filter;
} else {
this->m_filter_ptr = nullptr;
}
ecs_filter_copy(&m_filter, &obj.m_filter);
}
filter_base& operator=(const filter_base& obj) {
this->m_world = obj.m_world;
if (obj.m_filter_ptr) {
this->m_filter_ptr = &this->m_filter;
} else {
this->m_filter_ptr = nullptr;
}
ecs_filter_copy(&m_filter, &obj.m_filter);
return *this;
}
filter_base(filter_base&& obj) {
this->m_world = obj.m_world;
if (obj.m_filter_ptr) {
this->m_filter_ptr = &this->m_filter;
} else {
this->m_filter_ptr = nullptr;
}
ecs_filter_move(&m_filter, &obj.m_filter);
}
filter_base& operator=(filter_base&& obj) {
this->m_world = obj.m_world;
if (obj.m_filter_ptr) {
this->m_filter_ptr = &this->m_filter;
} else {
this->m_filter_ptr = nullptr;
}
ecs_filter_move(&m_filter, &obj.m_filter);
return *this;
}
flecs::entity entity() {
return flecs::entity(m_world, ecs_get_entity(m_filter_ptr));
}
operator const flecs::filter_t*() const {
return m_filter_ptr;
}
~filter_base() {
if ((&m_filter == m_filter_ptr) && m_filter_ptr) {
ecs_filter_fini(&m_filter);
}
}
template <typename Func>
void each_term(const Func& func) {
for (int i = 0; i < m_filter_ptr->term_count; i ++) {
flecs::term t(m_world, m_filter_ptr->terms[i]);
func(t);
t.reset(); }
}
flecs::term term(int32_t index) {
return flecs::term(m_world, m_filter_ptr->terms[index]);
}
int32_t field_count() {
return m_filter_ptr->term_count;
}
flecs::string str() {
char *result = ecs_filter_str(m_world, m_filter_ptr);
return flecs::string(result);
}
operator filter<>() const;
protected:
world_t *m_world = nullptr;
filter_t m_filter = ECS_FILTER_INIT;
const filter_t *m_filter_ptr;
};
template<typename ... Components>
struct filter : filter_base, iterable<Components...> {
private:
using Terms = typename _::term_ptrs<Components...>::array;
public:
using filter_base::filter_base;
filter() : filter_base() { }
filter(const filter& obj) : filter_base(obj) { }
filter& operator=(const filter& obj) {
filter_base::operator=(obj);
return *this;
}
filter(filter&& obj) : filter_base(FLECS_MOV(obj)) { }
filter& operator=(filter&& obj) {
filter_base::operator=(FLECS_FWD(obj));
return *this;
}
private:
ecs_iter_t get_iter(flecs::world_t *world) const override {
if (!world) {
world = m_world;
}
return ecs_filter_iter(world, m_filter_ptr);
}
ecs_iter_next_action_t next_action() const override {
return ecs_filter_next;
}
ecs_iter_next_action_t next_each_action() const override {
return ecs_filter_next_instanced;
}
};
template <typename... Comps, typename... Args>
inline flecs::filter<Comps...> world::filter(Args &&... args) const {
return flecs::filter_builder<Comps...>(m_world, FLECS_FWD(args)...)
.build();
}
template <typename... Comps, typename... Args>
inline flecs::filter_builder<Comps...> world::filter_builder(Args &&... args) const {
return flecs::filter_builder<Comps...>(m_world, FLECS_FWD(args)...);
}
namespace _ {
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) {
auto f = world.filter<Args ...>();
f.each(FLECS_MOV(func));
}
};
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) {
auto f = world.filter<Args ...>();
f.each(FLECS_MOV(func));
}
};
template<typename Func, typename T = int>
struct filter_invoker;
template <typename Func>
struct filter_invoker<Func, if_t<is_same<first_arg_t<Func>, flecs::entity>::value> > {
filter_invoker(const flecs::world& world, Func&& func) {
filter_invoker_w_ent<Func, arg_list_t<Func>>(world, FLECS_MOV(func));
}
};
template <typename Func>
struct filter_invoker<Func, if_not_t<is_same<first_arg_t<Func>, flecs::entity>::value> > {
filter_invoker(const flecs::world& world, Func&& func) {
filter_invoker_no_ent<Func, arg_list_t<Func>>(world, FLECS_MOV(func));
}
};
}
template <typename Func>
inline void world::each(Func&& func) const {
_::filter_invoker<Func> f_invoker(*this, FLECS_MOV(func));
}
template <typename T, typename Func>
inline void world::each(Func&& func) const {
ecs_term_t t = {};
t.id = _::cpp_type<T>::id();
ecs_iter_t it = ecs_term_iter(m_world, &t);
while (ecs_term_next(&it)) {
_::each_invoker<Func, T>(func).invoke(&it);
}
}
template <typename Func>
inline void world::each(flecs::id_t term_id, Func&& func) const {
ecs_term_t t = {};
t.id = term_id;
ecs_iter_t it = ecs_term_iter(m_world, &t);
while (ecs_term_next(&it)) {
_::each_invoker<Func>(func).invoke(&it);
}
}
inline filter_base::operator flecs::filter<> () const {
flecs::filter<> f;
ecs_filter_copy(&f.m_filter, &this->m_filter);
f.m_filter_ptr = &f.m_filter;
f.m_world = this->m_world;
return f;
}
}
#pragma once
namespace flecs
{
inline flecs::event_builder world::event(flecs::entity_t evt) const {
return flecs::event_builder(m_world, evt);
}
template <typename E>
inline flecs::event_builder_typed<E> world::event() const {
return flecs::event_builder_typed<E>(m_world, _::cpp_type<E>().id(m_world));
}
}
#pragma once
#pragma once
#pragma once
namespace flecs {
template<typename Base, typename ... Components>
struct query_builder_i : filter_builder_i<Base, Components ...> {
private:
using BaseClass = filter_builder_i<Base, Components ...>;
public:
query_builder_i()
: BaseClass(nullptr)
, m_desc(nullptr) { }
query_builder_i(ecs_query_desc_t *desc, int32_t term_index = 0)
: BaseClass(&desc->filter, term_index)
, m_desc(desc) { }
template <typename T>
Base& order_by(int(*compare)(flecs::entity_t, const T*, flecs::entity_t, const T*)) {
ecs_order_by_action_t cmp = reinterpret_cast<ecs_order_by_action_t>(compare);
return this->order_by(_::cpp_type<T>::id(this->world_v()), cmp);
}
Base& order_by(flecs::entity_t component, int(*compare)(flecs::entity_t, const void*, flecs::entity_t, const void*)) {
m_desc->order_by = reinterpret_cast<ecs_order_by_action_t>(compare);
m_desc->order_by_component = component;
return *this;
}
template <typename T>
Base& group_by(uint64_t(*group_by_action)(flecs::world_t*, flecs::table_t *table, flecs::id_t id, void* ctx)) {
ecs_group_by_action_t action = reinterpret_cast<ecs_group_by_action_t>(group_by_action);
return this->group_by(_::cpp_type<T>::id(this->world_v()), 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)) {
m_desc->group_by = reinterpret_cast<ecs_group_by_action_t>(group_by_action);
m_desc->group_by_id = component;
return *this;
}
template <typename T>
Base& group_by() {
return this->group_by(_::cpp_type<T>::id(this->world_v()), nullptr);
}
Base& group_by(flecs::entity_t component) {
return this->group_by(component, nullptr);
}
Base& group_by_ctx(void *ctx, ecs_ctx_free_t ctx_free = nullptr) {
m_desc->group_by_ctx = ctx;
m_desc->group_by_ctx_free = ctx_free;
return *this;
}
Base& on_group_create(ecs_group_create_action_t action) {
m_desc->on_group_create = action;
return *this;
}
Base& on_group_delete(ecs_group_delete_action_t action) {
m_desc->on_group_delete = action;
return *this;
}
Base& observable(const query_base& parent);
protected:
virtual flecs::world_t* world_v() = 0;
private:
operator Base&() {
return *static_cast<Base*>(this);
}
ecs_query_desc_t *m_desc;
};
}
namespace flecs {
namespace _ {
template <typename ... Components>
using query_builder_base = builder<
query, ecs_query_desc_t, query_builder<Components...>,
query_builder_i, Components ...>;
}
template <typename ... Components>
struct query_builder final : _::query_builder_base<Components...> {
query_builder(flecs::world_t* world, const char *name = nullptr)
: _::query_builder_base<Components...>(world)
{
_::sig<Components...>(world).populate(this);
if (name != nullptr) {
ecs_entity_desc_t entity_desc = {};
entity_desc.name = name;
entity_desc.sep = "::";
entity_desc.root_sep = "::";
this->m_desc.filter.entity = ecs_entity_init(world, &entity_desc);
}
}
};
}
namespace flecs {
struct query_base {
query_base()
: m_world(nullptr)
, m_query(nullptr) { }
query_base(world_t *world, query_t *query = nullptr)
: m_world(world)
, m_query(query) { }
query_base(world_t *world, ecs_query_desc_t *desc)
: m_world(world)
{
m_query = ecs_query_init(world, desc);
if (!m_query) {
ecs_abort(ECS_INVALID_PARAMETER, NULL);
}
if (desc->filter.terms_buffer) {
ecs_os_free(desc->filter.terms_buffer);
}
}
operator query_t*() const {
return m_query;
}
bool changed() const {
return ecs_query_changed(m_query, 0);
}
bool orphaned() const {
return ecs_query_orphaned(m_query);
}
const flecs::query_group_info_t* group_info(uint64_t group_id) const {
return ecs_query_get_group_info(m_query, group_id);
}
void* group_ctx(uint64_t group_id) const {
const flecs::query_group_info_t *gi = group_info(group_id);
if (gi) {
return gi->ctx;
} else {
return NULL;
}
}
void destruct() {
ecs_query_fini(m_query);
m_world = nullptr;
m_query = nullptr;
}
template <typename Func>
void each_term(const Func& func) const {
this->filter().each_term(func);
}
filter_base filter() const {
return filter_base(m_world, ecs_query_get_filter(m_query));
}
flecs::term term(int32_t index) const {
const ecs_filter_t *f = ecs_query_get_filter(m_query);
ecs_assert(f != NULL, ECS_INVALID_PARAMETER, NULL);
return flecs::term(m_world, f->terms[index]);
}
int32_t field_count() const {
const ecs_filter_t *f = ecs_query_get_filter(m_query);
return f->term_count;
}
flecs::string str() const {
const ecs_filter_t *f = ecs_query_get_filter(m_query);
char *result = ecs_filter_str(m_world, f);
return flecs::string(result);
}
flecs::entity entity() const {
return flecs::entity(m_world, ecs_get_entity(m_query));
}
operator query<>() const;
protected:
world_t *m_world;
query_t *m_query;
};
template<typename ... Components>
struct query final : query_base, iterable<Components...> {
public:
flecs::world world() const {
return flecs::world(m_world);
}
private:
using Terms = typename _::term_ptrs<Components...>::array;
ecs_iter_t get_iter(flecs::world_t *world) const override {
if (!world) {
world = m_world;
}
return ecs_query_iter(world, m_query);
}
ecs_iter_next_action_t next_action() const override {
return ecs_query_next;
}
ecs_iter_next_action_t next_each_action() const override {
return ecs_query_next_instanced;
}
public:
using query_base::query_base;
};
template <typename... Comps, typename... Args>
inline flecs::query<Comps...> world::query(Args &&... args) const {
return flecs::query_builder<Comps...>(m_world, FLECS_FWD(args)...)
.build();
}
template <typename... Comps, typename... Args>
inline flecs::query_builder<Comps...> world::query_builder(Args &&... args) const {
return flecs::query_builder<Comps...>(m_world, FLECS_FWD(args)...);
}
template <typename Base, typename ... Components>
inline Base& query_builder_i<Base, Components ...>::observable(const query_base& parent) {
m_desc->parent = parent;
return *static_cast<Base*>(this);
}
inline query_base::operator query<>() const {
return flecs::query<>(m_world, m_query);
}
}
#pragma once
#pragma once
#pragma once
namespace flecs {
namespace _ {
#define FLECS_IBUILDER template<typename IBase, typename ... Components> class
template<typename T, typename TDesc, typename Base, FLECS_IBUILDER IBuilder, typename ... Components>
struct node_builder : IBuilder<Base, Components ...>
{
using IBase = IBuilder<Base, Components ...>;
public:
explicit node_builder(flecs::world_t* world, const char *name = nullptr)
: IBase(&m_desc)
, m_desc{}
, m_world(world)
, m_instanced(false)
{
ecs_entity_desc_t entity_desc = {};
entity_desc.name = name;
entity_desc.sep = "::";
m_desc.entity = ecs_entity_init(m_world, &entity_desc);
}
template <typename Func>
T iter(Func&& func) {
using Invoker = typename _::iter_invoker<
typename std::decay<Func>::type, Components...>;
return build<Invoker>(FLECS_FWD(func));
}
template <typename Func>
T each(Func&& func) {
using Invoker = typename _::each_invoker<
typename std::decay<Func>::type, Components...>;
m_instanced = true;
return build<Invoker>(FLECS_FWD(func));
}
protected:
flecs::world_t* world_v() override { return m_world; }
TDesc m_desc;
flecs::world_t *m_world;
bool m_instanced;
private:
template <typename Invoker, typename Func>
T build(Func&& func) {
auto ctx = FLECS_NEW(Invoker)(FLECS_FWD(func));
m_desc.callback = Invoker::run;
m_desc.binding_ctx = ctx;
m_desc.binding_ctx_free = reinterpret_cast<
ecs_ctx_free_t>(_::free_obj<Invoker>);
return T(m_world, &m_desc, m_instanced);
}
};
#undef FLECS_IBUILDER
} }
#pragma once
namespace flecs {
template<typename Base, typename ... Components>
struct observer_builder_i : filter_builder_i<Base, Components ...> {
using BaseClass = filter_builder_i<Base, Components ...>;
observer_builder_i()
: BaseClass(nullptr)
, m_desc(nullptr)
, m_event_count(0) { }
observer_builder_i(ecs_observer_desc_t *desc)
: BaseClass(&desc->filter)
, m_desc(desc)
, m_event_count(0) { }
Base& event(entity_t evt) {
m_desc->events[m_event_count ++] = evt;
return *this;
}
template <typename E>
Base& event() {
m_desc->events[m_event_count ++] = _::cpp_type<E>().id(world_v());
return *this;
}
Base& yield_existing(bool value = true) {
m_desc->yield_existing = value;
return *this;
}
Base& ctx(void *ptr) {
m_desc->ctx = ptr;
return *this;
}
Base& run(ecs_iter_action_t action) {
m_desc->run = action;
return *this;
}
protected:
virtual flecs::world_t* world_v() = 0;
private:
operator Base&() {
return *static_cast<Base*>(this);
}
ecs_observer_desc_t *m_desc;
int32_t m_event_count;
};
}
namespace flecs {
namespace _ {
template <typename ... Components>
using observer_builder_base = node_builder<
observer, ecs_observer_desc_t, observer_builder<Components...>,
observer_builder_i, Components ...>;
}
template <typename ... Components>
struct observer_builder final : _::observer_builder_base<Components...> {
observer_builder(flecs::world_t* world, const char *name = nullptr)
: _::observer_builder_base<Components...>(world, name)
{
_::sig<Components...>(world).populate(this);
}
};
}
namespace flecs
{
struct observer final : entity
{
using entity::entity;
explicit observer() : entity() { }
observer(flecs::world_t *world, ecs_observer_desc_t *desc, bool instanced)
{
if (!desc->filter.instanced) {
desc->filter.instanced = instanced;
}
m_world = world;
m_id = ecs_observer_init(world, desc);
if (desc->filter.terms_buffer) {
ecs_os_free(desc->filter.terms_buffer);
}
}
void ctx(void *ctx) {
ecs_observer_desc_t desc = {};
desc.entity = m_id;
desc.ctx = ctx;
ecs_observer_init(m_world, &desc);
}
void* ctx() const {
return ecs_observer_get_ctx(m_world, m_id);
}
flecs::filter<> query() const {
const flecs::Poly *poly = this->get<flecs::Poly>(flecs::Observer);
const ecs_observer_t *ob = static_cast<const flecs::observer_t*>(poly->poly);
return flecs::filter<>(m_world, &ob->filter);
}
};
inline observer world::observer(flecs::entity e) const {
return flecs::observer(m_world, e);
}
template <typename... Comps, typename... Args>
inline observer_builder<Comps...> world::observer(Args &&... args) const {
return flecs::observer_builder<Comps...>(m_world, FLECS_FWD(args)...);
}
}
#pragma once
namespace flecs {
template <typename E>
inline E entity_view::to_constant() const {
const E* ptr = this->get<E>();
ecs_assert(ptr != NULL, ECS_INVALID_PARAMETER, "entity is not a constant");
return ptr[0];
}
template <typename E, if_t< is_enum<E>::value >>
inline flecs::entity world::to_entity(E constant) const {
const auto& et = enum_type<E>(m_world);
return flecs::entity(m_world, et.entity(constant));
}
}
#ifdef FLECS_MODULE
#pragma once
namespace flecs {
namespace _ {
template <typename T>
ecs_entity_t do_import(world& world, const char *symbol) {
ecs_trace("#[magenta]import#[reset] %s", _::type_name<T>());
ecs_log_push();
ecs_entity_t scope = ecs_set_scope(world, 0);
auto m_c = component<T>(world, nullptr, false);
ecs_add_id(world, m_c, EcsModule);
ecs_set_scope(world, m_c);
world.emplace<T>(world);
ecs_set_scope(world, scope);
ecs_entity_t m = ecs_lookup_symbol(world, symbol, true, false);
ecs_assert(m != 0, ECS_MODULE_UNDEFINED, symbol);
ecs_assert(m == m_c, ECS_INTERNAL_ERROR, NULL);
ecs_log_pop();
return m;
}
template <typename T>
flecs::entity import(world& world) {
const char *symbol = _::symbol_name<T>();
ecs_entity_t m = ecs_lookup_symbol(world, symbol, true, false);
if (!_::cpp_type<T>::registered(world)) {
if (m) {
_::cpp_type<T>::init(m, false);
} else {
m = _::do_import<T>(world, symbol);
}
} else if (!m) {
m = _::do_import<T>(world, symbol);
}
return flecs::entity(world, m);
}
}
template <typename Module>
inline flecs::entity world::module(const char *name) const {
flecs::id_t result = _::cpp_type<Module>::id(m_world, nullptr, false);
if (name) {
ecs_add_path_w_sep(m_world, result, 0, name, "::", "::");
}
ecs_set_scope(m_world, result);
return flecs::entity(m_world, result);
}
template <typename Module>
inline flecs::entity world::import() {
return flecs::_::import<Module>(*this);
}
}
#endif
#ifdef FLECS_SYSTEM
#pragma once
#pragma once
#pragma once
namespace flecs
{
template<typename Base, typename ... Components>
struct system_builder_i : query_builder_i<Base, Components ...> {
private:
using BaseClass = query_builder_i<Base, Components ...>;
public:
system_builder_i(ecs_system_desc_t *desc)
: BaseClass(&desc->query)
, m_desc(desc) { }
Base& kind(entity_t phase) {
flecs::entity_t cur_phase = ecs_get_target(
world_v(), m_desc->entity, EcsDependsOn, 0);
if (cur_phase) {
ecs_remove_id(world_v(), m_desc->entity, ecs_dependson(cur_phase));
ecs_remove_id(world_v(), m_desc->entity, cur_phase);
}
if (phase) {
ecs_add_id(world_v(), m_desc->entity, ecs_dependson(phase));
ecs_add_id(world_v(), m_desc->entity, phase);
}
return *this;
}
template <typename Phase>
Base& kind() {
return this->kind(_::cpp_type<Phase>::id(world_v()));
}
Base& multi_threaded(bool value = true) {
m_desc->multi_threaded = value;
return *this;
}
Base& no_readonly(bool value = true) {
m_desc->no_readonly = value;
return *this;
}
Base& interval(ecs_ftime_t interval) {
m_desc->interval = interval;
return *this;
}
Base& rate(const entity_t tick_source, int32_t rate) {
m_desc->rate = rate;
m_desc->tick_source = tick_source;
return *this;
}
Base& rate(int32_t rate) {
m_desc->rate = rate;
return *this;
}
Base& tick_source(flecs::entity_t tick_source) {
m_desc->tick_source = tick_source;
return *this;
}
Base& ctx(void *ptr) {
m_desc->ctx = ptr;
return *this;
}
Base& run(ecs_iter_action_t action) {
m_desc->run = action;
return *this;
}
protected:
virtual flecs::world_t* world_v() = 0;
private:
operator Base&() {
return *static_cast<Base*>(this);
}
ecs_system_desc_t *m_desc;
};
}
namespace flecs {
namespace _ {
template <typename ... Components>
using system_builder_base = node_builder<
system, ecs_system_desc_t, system_builder<Components...>,
system_builder_i, Components ...>;
}
template <typename ... Components>
struct system_builder final : _::system_builder_base<Components...> {
system_builder(flecs::world_t* world, const char *name = nullptr)
: _::system_builder_base<Components...>(world, name)
{
_::sig<Components...>(world).populate(this);
#ifdef FLECS_PIPELINE
ecs_add_id(world, this->m_desc.entity, ecs_dependson(flecs::OnUpdate));
ecs_add_id(world, this->m_desc.entity, flecs::OnUpdate);
#endif
}
};
}
namespace flecs
{
struct system_runner_fluent {
system_runner_fluent(
world_t *world,
entity_t id,
int32_t stage_current,
int32_t stage_count,
ecs_ftime_t delta_time,
void *param)
: m_stage(world)
, m_id(id)
, m_delta_time(delta_time)
, m_param(param)
, m_offset(0)
, m_limit(0)
, m_stage_current(stage_current)
, m_stage_count(stage_count) { }
system_runner_fluent& offset(int32_t offset) {
m_offset = offset;
return *this;
}
system_runner_fluent& limit(int32_t limit) {
m_limit = limit;
return *this;
}
system_runner_fluent& stage(flecs::world& stage) {
m_stage = stage.c_ptr();
return *this;
}
~system_runner_fluent() {
if (m_stage_count) {
ecs_run_worker(
m_stage, m_id, m_stage_current, m_stage_count, m_delta_time,
m_param);
} else {
ecs_run_w_filter(
m_stage, m_id, m_delta_time, m_offset, m_limit, m_param);
}
}
private:
world_t *m_stage;
entity_t m_id;
ecs_ftime_t m_delta_time;
void *m_param;
int32_t m_offset;
int32_t m_limit;
int32_t m_stage_current;
int32_t m_stage_count;
};
struct system final : entity
{
using entity::entity;
explicit system() {
m_id = 0;
m_world = nullptr;
}
explicit system(flecs::world_t *world, ecs_system_desc_t *desc, bool instanced)
{
if (!desc->query.filter.instanced) {
desc->query.filter.instanced = instanced;
}
m_world = world;
m_id = ecs_system_init(world, desc);
if (desc->query.filter.terms_buffer) {
ecs_os_free(desc->query.filter.terms_buffer);
}
}
void ctx(void *ctx) {
ecs_system_desc_t desc = {};
desc.entity = m_id;
desc.ctx = ctx;
ecs_system_init(m_world, &desc);
}
void* ctx() const {
return ecs_system_get_ctx(m_world, m_id);
}
flecs::query<> query() const {
return flecs::query<>(m_world, ecs_system_get_query(m_world, m_id));
}
system_runner_fluent run(ecs_ftime_t delta_time = 0.0f, void *param = nullptr) const {
return system_runner_fluent(m_world, m_id, 0, 0, delta_time, param);
}
system_runner_fluent run_worker(
int32_t stage_current,
int32_t stage_count,
ecs_ftime_t delta_time = 0.0f,
void *param = nullptr) const
{
return system_runner_fluent(
m_world, m_id, stage_current, stage_count, delta_time, param);
}
# ifdef FLECS_TIMER
void interval(ecs_ftime_t interval);
ecs_ftime_t interval();
void timeout(ecs_ftime_t timeout);
ecs_ftime_t timeout();
void rate(int32_t rate);
void start();
void stop();
void set_tick_source(flecs::entity e);
# endif
};
inline system world::system(flecs::entity e) const {
return flecs::system(m_world, e);
}
template <typename... Comps, typename... Args>
inline system_builder<Comps...> world::system(Args &&... args) const {
return flecs::system_builder<Comps...>(m_world, FLECS_FWD(args)...);
}
namespace _ {
inline void system_init(flecs::world& world) {
world.component<TickSource>("flecs::system::TickSource");
}
} }
#endif
#ifdef FLECS_PIPELINE
#pragma once
#pragma once
#pragma once
namespace flecs {
template<typename Base>
struct pipeline_builder_i : query_builder_i<Base> {
pipeline_builder_i(ecs_pipeline_desc_t *desc, int32_t term_index = 0)
: query_builder_i<Base>(&desc->query, term_index)
, m_desc(desc) { }
private:
ecs_pipeline_desc_t *m_desc;
};
}
namespace flecs {
namespace _ {
template <typename ... Components>
using pipeline_builder_base = builder<
pipeline, ecs_pipeline_desc_t, pipeline_builder<Components...>,
pipeline_builder_i, Components ...>;
}
template <typename ... Components>
struct pipeline_builder final : _::pipeline_builder_base<Components...> {
pipeline_builder(flecs::world_t* world, flecs::entity_t id = 0)
: _::pipeline_builder_base<Components...>(world)
{
_::sig<Components...>(world).populate(this);
this->m_desc.entity = id;
}
};
}
namespace flecs {
template <typename ... Components>
struct pipeline : entity {
pipeline(world_t *world, ecs_pipeline_desc_t *desc)
: entity(world)
{
m_id = ecs_pipeline_init(world, desc);
if (!m_id) {
ecs_abort(ECS_INVALID_PARAMETER, NULL);
}
if (desc->query.filter.terms_buffer) {
ecs_os_free(desc->query.filter.terms_buffer);
}
}
};
inline flecs::pipeline_builder<> world::pipeline() const {
return flecs::pipeline_builder<>(m_world);
}
template <typename Pipeline, if_not_t< is_enum<Pipeline>::value >>
inline flecs::pipeline_builder<> world::pipeline() const {
return flecs::pipeline_builder<>(m_world, _::cpp_type<Pipeline>::id(m_world));
}
inline void world::set_pipeline(const flecs::entity pip) const {
return ecs_set_pipeline(m_world, pip);
}
template <typename Pipeline>
inline void world::set_pipeline() const {
return ecs_set_pipeline(m_world, _::cpp_type<Pipeline>::id(m_world));
}
inline flecs::entity world::get_pipeline() const {
return flecs::entity(m_world, ecs_get_pipeline(m_world));
}
inline bool world::progress(ecs_ftime_t delta_time) const {
return ecs_progress(m_world, delta_time);
}
inline void world::run_pipeline(const flecs::entity_t pip, ecs_ftime_t delta_time) const {
return ecs_run_pipeline(m_world, pip, delta_time);
}
template <typename Pipeline, if_not_t< is_enum<Pipeline>::value >>
inline void world::run_pipeline(ecs_ftime_t delta_time) const {
return ecs_run_pipeline(m_world, _::cpp_type<Pipeline>::id(m_world), delta_time);
}
inline void world::set_time_scale(ecs_ftime_t mul) const {
ecs_set_time_scale(m_world, mul);
}
inline void world::set_target_fps(ecs_ftime_t target_fps) const {
ecs_set_target_fps(m_world, target_fps);
}
inline void world::reset_clock() const {
ecs_reset_clock(m_world);
}
inline void world::set_threads(int32_t threads) const {
ecs_set_threads(m_world, threads);
}
inline int32_t world::get_threads() const {
return ecs_get_stage_count(m_world);
}
inline void world::set_task_threads(int32_t task_threads) const {
ecs_set_task_threads(m_world, task_threads);
}
inline bool world::using_task_threads() const {
return ecs_using_task_threads(m_world);
}
}
#endif
#ifdef FLECS_TIMER
#pragma once
namespace flecs {
struct timer final : entity {
using entity::entity;
timer& interval(ecs_ftime_t interval) {
ecs_set_interval(m_world, m_id, interval);
return *this;
}
ecs_ftime_t interval() {
return ecs_get_interval(m_world, m_id);
}
timer& timeout(ecs_ftime_t timeout) {
ecs_set_timeout(m_world, m_id, timeout);
return *this;
}
ecs_ftime_t timeout() {
return ecs_get_timeout(m_world, m_id);
}
timer& rate(int32_t rate, flecs::entity_t tick_source = 0) {
ecs_set_rate(m_world, m_id, rate, tick_source);
return *this;
}
void start() {
ecs_start_timer(m_world, m_id);
}
void stop() {
ecs_stop_timer(m_world, m_id);
}
};
template <typename... Args>
inline flecs::timer world::timer(Args &&... args) const {
return flecs::timer(m_world, FLECS_FWD(args)...);
}
inline void world::randomize_timers() const {
ecs_randomize_timers(m_world);
}
inline void system::interval(ecs_ftime_t interval) {
ecs_set_interval(m_world, m_id, interval);
}
inline ecs_ftime_t system::interval() {
return ecs_get_interval(m_world, m_id);
}
inline void system::timeout(ecs_ftime_t timeout) {
ecs_set_timeout(m_world, m_id, timeout);
}
inline ecs_ftime_t system::timeout() {
return ecs_get_timeout(m_world, m_id);
}
inline void system::rate(int32_t rate) {
ecs_set_rate(m_world, m_id, rate, 0);
}
inline void system::start() {
ecs_start_timer(m_world, m_id);
}
inline void system::stop() {
ecs_stop_timer(m_world, m_id);
}
inline void system::set_tick_source(flecs::entity e) {
ecs_set_tick_source(m_world, m_id, e);
}
namespace _ {
inline void timer_init(flecs::world& world) {
world.component<RateFilter>("flecs::timer::RateFilter");
world.component<Timer>("flecs::timer::Timer");
}
}
}
#endif
#ifdef FLECS_SNAPSHOT
#pragma once
namespace flecs {
struct snapshot final {
explicit snapshot(const world& world)
: m_world( world )
, m_snapshot( nullptr ) { }
snapshot(const snapshot& obj)
: m_world( obj.m_world )
{
ecs_iter_t it = ecs_snapshot_iter(obj.m_snapshot);
m_snapshot = ecs_snapshot_take_w_iter(&it);
}
snapshot(snapshot&& obj)
: m_world(obj.m_world)
, m_snapshot(obj.m_snapshot)
{
obj.m_snapshot = nullptr;
}
snapshot& operator=(const snapshot& obj) {
ecs_assert(m_world.c_ptr() == obj.m_world.c_ptr(), ECS_INVALID_PARAMETER, NULL);
ecs_iter_t it = ecs_snapshot_iter(obj.m_snapshot);
m_snapshot = ecs_snapshot_take_w_iter(&it);
return *this;
}
snapshot& operator=(snapshot&& obj) {
ecs_assert(m_world.c_ptr() == obj.m_world.c_ptr(), ECS_INVALID_PARAMETER, NULL);
m_snapshot = obj.m_snapshot;
obj.m_snapshot = nullptr;
return *this;
}
void take() {
if (m_snapshot) {
ecs_snapshot_free(m_snapshot);
}
m_snapshot = ecs_snapshot_take(m_world.c_ptr());
}
template <typename F>
void take(const F& f) {
if (m_snapshot) {
ecs_snapshot_free(m_snapshot);
}
ecs_iter_t it = ecs_filter_iter(m_world, f.c_ptr());
m_snapshot = ecs_snapshot_take_w_iter(&it);
}
void restore() {
if (m_snapshot) {
ecs_snapshot_restore(m_world.c_ptr(), m_snapshot);
m_snapshot = nullptr;
}
}
~snapshot() {
if (m_snapshot) {
ecs_snapshot_free(m_snapshot);
}
}
snapshot_t* c_ptr() const {
return m_snapshot;
}
private:
const world& m_world;
snapshot_t *m_snapshot;
};
template <typename... Args>
inline flecs::snapshot world::snapshot(Args &&... args) const {
return flecs::snapshot(*this, FLECS_FWD(args)...);
}
}
#endif
#ifdef FLECS_DOC
#pragma once
namespace flecs {
namespace doc {
inline const char* get_name(const flecs::entity_view& e) {
return ecs_doc_get_name(e.world(), e);
}
inline const char* get_brief(const flecs::entity_view& e) {
return ecs_doc_get_brief(e.world(), e);
}
inline const char* get_detail(const flecs::entity_view& e) {
return ecs_doc_get_detail(e.world(), e);
}
inline const char* get_link(const flecs::entity_view& e) {
return ecs_doc_get_link(e.world(), e);
}
inline void set_name(flecs::entity& e, const char *name) {
ecs_doc_set_name(e.world(), e, name);
}
inline void set_brief(flecs::entity& e, const char *description) {
ecs_doc_set_brief(e.world(), e, description);
}
inline void set_detail(flecs::entity& e, const char *description) {
ecs_doc_set_detail(e.world(), e, description);
}
inline void set_link(flecs::entity& e, const char *description) {
ecs_doc_set_link(e.world(), e, description);
}
namespace _ {
inline void init(flecs::world& world) {
world.component<doc::Description>("flecs::doc::Description");
}
} } }
#endif
#ifdef FLECS_DOC
#endif
#ifdef FLECS_REST
#pragma once
namespace flecs {
namespace rest {
namespace _ {
inline void init(flecs::world& world) {
world.component<Rest>("flecs::rest::Rest");
}
} } }
#endif
#ifdef FLECS_RULES
#pragma once
#pragma once
namespace flecs {
namespace _ {
template <typename ... Components>
using rule_builder_base = builder<
rule, ecs_filter_desc_t, rule_builder<Components...>,
filter_builder_i, Components ...>;
}
template <typename ... Components>
struct rule_builder final : _::rule_builder_base<Components...> {
rule_builder(flecs::world_t* world, const char *name = nullptr)
: _::rule_builder_base<Components...>(world)
{
_::sig<Components...>(world).populate(this);
if (name != nullptr) {
ecs_entity_desc_t entity_desc = {};
entity_desc.name = name;
entity_desc.sep = "::";
entity_desc.root_sep = "::";
this->m_desc.entity = ecs_entity_init(world, &entity_desc);
}
}
};
}
namespace flecs {
struct rule_base {
rule_base()
: m_world(nullptr)
, m_rule(nullptr) { }
rule_base(world_t *world, rule_t *rule = nullptr)
: m_world(world)
, m_rule(rule) { }
rule_base(world_t *world, ecs_filter_desc_t *desc)
: m_world(world)
{
m_rule = ecs_rule_init(world, desc);
if (desc->terms_buffer) {
ecs_os_free(desc->terms_buffer);
}
}
bool is_valid() const {
return m_rule != nullptr;
}
operator rule_t*() const {
return m_rule;
}
flecs::entity entity() {
return flecs::entity(m_world, ecs_get_entity(m_rule));
}
void destruct() {
if (m_rule) {
ecs_rule_fini(m_rule);
m_world = nullptr;
m_rule = nullptr;
}
}
template <typename Func>
void each_term(const Func& func) const {
this->filter().each_term(func);
}
void move(flecs::rule_base&& obj) {
this->destruct();
this->m_world = obj.m_world;
this->m_rule = obj.m_rule;
obj.m_world = nullptr;
obj.m_rule = nullptr;
}
flecs::filter_base filter() const {
return filter_base(m_world, ecs_rule_get_filter(m_rule));
}
flecs::string str() const {
const ecs_filter_t *f = ecs_rule_get_filter(m_rule);
char *result = ecs_filter_str(m_world, f);
return flecs::string(result);
}
flecs::string rule_str() const {
char *result = ecs_rule_str(m_rule);
return flecs::string(result);
}
operator rule<>() const;
protected:
world_t *m_world;
rule_t *m_rule;
};
template<typename ... Components>
struct rule final : rule_base, iterable<Components...> {
private:
using Terms = typename _::term_ptrs<Components...>::array;
ecs_iter_t get_iter(flecs::world_t *world) const override {
if (!world) {
world = m_world;
}
return ecs_rule_iter(world, m_rule);
}
ecs_iter_next_action_t next_action() const override {
return ecs_rule_next;
}
ecs_iter_next_action_t next_each_action() const override {
return ecs_rule_next_instanced;
}
public:
using rule_base::rule_base;
int32_t find_var(const char *name) {
return ecs_rule_find_var(m_rule, name);
}
};
template <typename... Comps, typename... Args>
inline flecs::rule<Comps...> world::rule(Args &&... args) const {
return flecs::rule_builder<Comps...>(m_world, FLECS_FWD(args)...)
.build();
}
template <typename... Comps, typename... Args>
inline flecs::rule_builder<Comps...> world::rule_builder(Args &&... args) const {
return flecs::rule_builder<Comps...>(m_world, FLECS_FWD(args)...);
}
inline rule_base::operator rule<>() const {
return flecs::rule<>(m_world, m_rule);
}
}
#endif
#ifdef FLECS_META
#pragma once
FLECS_ENUM_LAST(flecs::meta::type_kind_t, flecs::meta::TypeKindLast)
FLECS_ENUM_LAST(flecs::meta::primitive_kind_t, flecs::meta::PrimitiveKindLast)
namespace flecs {
namespace meta {
namespace _ {
template <typename EntityType>
inline flecs::opaque<EntityType> flecs_entity_support(flecs::world&) {
return flecs::opaque<EntityType>()
.as_type(flecs::Entity)
.serialize([](const flecs::serializer *ser, const EntityType *data) {
flecs::entity_t id = data->id();
return ser->value(flecs::Entity, &id);
})
.assign_entity(
[](EntityType *dst, flecs::world_t *world, flecs::entity_t e) {
*dst = EntityType(world, e);
});
}
inline void init(flecs::world& world) {
world.component<bool_t>("flecs::meta::bool");
world.component<char_t>("flecs::meta::char");
world.component<u8_t>("flecs::meta::u8");
world.component<u16_t>("flecs::meta::u16");
world.component<u32_t>("flecs::meta::u32");
world.component<u64_t>("flecs::meta::u64");
world.component<i8_t>("flecs::meta::i8");
world.component<i16_t>("flecs::meta::i16");
world.component<i32_t>("flecs::meta::i32");
world.component<i64_t>("flecs::meta::i64");
world.component<f32_t>("flecs::meta::f32");
world.component<f64_t>("flecs::meta::f64");
world.component<type_kind_t>("flecs::meta::type_kind");
world.component<primitive_kind_t>("flecs::meta::primitive_kind");
world.component<member_t>("flecs::meta::member");
world.component<enum_constant_t>("flecs::meta::enum_constant");
world.component<bitmask_constant_t>("flecs::meta::bitmask_constant");
world.component<MetaType>("flecs::meta::MetaType");
world.component<MetaTypeSerialized>("flecs::meta::MetaTypeSerialized");
world.component<Primitive>("flecs::meta::Primitive");
world.component<Enum>("flecs::meta::Enum");
world.component<Bitmask>("flecs::meta::Bitmask");
world.component<Member>("flecs::meta::Member");
world.component<Struct>("flecs::meta::Struct");
world.component<Array>("flecs::meta::Array");
world.component<Vector>("flecs::meta::Vector");
world.component<Unit>("flecs::meta::Unit");
if (!flecs::is_same<i32_t, iptr_t>() && !flecs::is_same<i64_t, iptr_t>()) {
flecs::_::cpp_type<iptr_t>::init(flecs::Iptr, true);
ecs_assert(flecs::type_id<iptr_t>() == flecs::Iptr,
ECS_INTERNAL_ERROR, NULL);
ecs_remove_pair(world, flecs::Iptr, ecs_id(EcsIdentifier), EcsSymbol);
}
if (!flecs::is_same<u32_t, uptr_t>() && !flecs::is_same<u64_t, uptr_t>()) {
flecs::_::cpp_type<uptr_t>::init(flecs::Uptr, true);
ecs_assert(flecs::type_id<uptr_t>() == flecs::Uptr,
ECS_INTERNAL_ERROR, NULL);
ecs_remove_pair(world, flecs::Uptr, ecs_id(EcsIdentifier), EcsSymbol);
}
world.component<flecs::entity_view>()
.opaque(flecs_entity_support<flecs::entity_view>);
world.component<flecs::entity>()
.opaque(flecs_entity_support<flecs::entity>);
}
}
}
inline flecs::entity cursor::get_type() const {
return flecs::entity(m_cursor.world, ecs_meta_get_type(&m_cursor));
}
inline flecs::entity cursor::get_unit() const {
return flecs::entity(m_cursor.world, ecs_meta_get_unit(&m_cursor));
}
inline flecs::entity cursor::get_entity() const {
return flecs::entity(m_cursor.world, ecs_meta_get_entity(&m_cursor));
}
inline flecs::entity world::primitive(flecs::meta::primitive_kind_t kind) {
ecs_primitive_desc_t desc = {};
desc.kind = kind;
flecs::entity_t eid = ecs_primitive_init(m_world, &desc);
ecs_assert(eid != 0, ECS_INVALID_OPERATION, NULL);
return flecs::entity(m_world, eid);
}
inline flecs::entity world::array(flecs::entity_t elem_id, int32_t array_count) {
ecs_array_desc_t desc = {};
desc.type = elem_id;
desc.count = array_count;
flecs::entity_t eid = ecs_array_init(m_world, &desc);
ecs_assert(eid != 0, ECS_INVALID_OPERATION, NULL);
return flecs::entity(m_world, eid);
}
template <typename T>
inline flecs::entity world::array(int32_t array_count) {
return this->array(_::cpp_type<T>::id(m_world), array_count);
}
inline flecs::entity world::vector(flecs::entity_t elem_id) {
ecs_vector_desc_t desc = {};
desc.type = elem_id;
flecs::entity_t eid = ecs_vector_init(m_world, &desc);
ecs_assert(eid != 0, ECS_INVALID_OPERATION, NULL);
return flecs::entity(m_world, eid);
}
template <typename T>
inline flecs::entity world::vector() {
return this->vector(_::cpp_type<T>::id(m_world));
}
}
inline int ecs_serializer_t::value(ecs_entity_t type, const void *v) const {
return this->value_(this, type, v);
}
template <typename T>
inline int ecs_serializer_t::value(const T& v) const {
return this->value(flecs::_::cpp_type<T>::id(
const_cast<flecs::world_t*>(this->world)), &v);
}
inline int ecs_serializer_t::member(const char *name) const {
return this->member_(this, name);
}
#endif
#ifdef FLECS_UNITS
#pragma once
namespace flecs {
inline units::units(flecs::world& world) {
FlecsUnitsImport(world);
world.module<units>();
world.entity<Prefixes>("::flecs::units::prefixes");
world.entity<Yocto>("::flecs::units::prefixes::Yocto");
world.entity<Zepto>("::flecs::units::prefixes::Zepto");
world.entity<Atto>("::flecs::units::prefixes::Atto");
world.entity<Femto>("::flecs::units::prefixes::Femto");
world.entity<Pico>("::flecs::units::prefixes::Pico");
world.entity<Nano>("::flecs::units::prefixes::Nano");
world.entity<Micro>("::flecs::units::prefixes::Micro");
world.entity<Milli>("::flecs::units::prefixes::Milli");
world.entity<Centi>("::flecs::units::prefixes::Centi");
world.entity<Deci>("::flecs::units::prefixes::Deci");
world.entity<Deca>("::flecs::units::prefixes::Deca");
world.entity<Hecto>("::flecs::units::prefixes::Hecto");
world.entity<Kilo>("::flecs::units::prefixes::Kilo");
world.entity<Mega>("::flecs::units::prefixes::Mega");
world.entity<Giga>("::flecs::units::prefixes::Giga");
world.entity<Tera>("::flecs::units::prefixes::Tera");
world.entity<Peta>("::flecs::units::prefixes::Peta");
world.entity<Exa>("::flecs::units::prefixes::Exa");
world.entity<Zetta>("::flecs::units::prefixes::Zetta");
world.entity<Yotta>("::flecs::units::prefixes::Yotta");
world.entity<Kibi>("::flecs::units::prefixes::Kibi");
world.entity<Mebi>("::flecs::units::prefixes::Mebi");
world.entity<Gibi>("::flecs::units::prefixes::Gibi");
world.entity<Tebi>("::flecs::units::prefixes::Tebi");
world.entity<Pebi>("::flecs::units::prefixes::Pebi");
world.entity<Exbi>("::flecs::units::prefixes::Exbi");
world.entity<Zebi>("::flecs::units::prefixes::Zebi");
world.entity<Yobi>("::flecs::units::prefixes::Yobi");
world.entity<Duration>("::flecs::units::Duration");
world.entity<Time>("::flecs::units::Time");
world.entity<Mass>("::flecs::units::Mass");
world.entity<Force>("::flecs::units::Force");
world.entity<ElectricCurrent>("::flecs::units::ElectricCurrent");
world.entity<Amount>("::flecs::units::Amount");
world.entity<LuminousIntensity>("::flecs::units::LuminousIntensity");
world.entity<Length>("::flecs::units::Length");
world.entity<Pressure>("::flecs::units::Pressure");
world.entity<Speed>("::flecs::units::Speed");
world.entity<Temperature>("::flecs::units::Temperature");
world.entity<Data>("::flecs::units::Data");
world.entity<DataRate>("::flecs::units::DataRate");
world.entity<Angle>("::flecs::units::Angle");
world.entity<Frequency>("::flecs::units::Frequency");
world.entity<Uri>("::flecs::units::Uri");
world.entity<duration::PicoSeconds>(
"::flecs::units::Duration::PicoSeconds");
world.entity<duration::NanoSeconds>(
"::flecs::units::Duration::NanoSeconds");
world.entity<duration::MicroSeconds>(
"::flecs::units::Duration::MicroSeconds");
world.entity<duration::MilliSeconds>(
"::flecs::units::Duration::MilliSeconds");
world.entity<duration::Seconds>(
"::flecs::units::Duration::Seconds");
world.entity<duration::Minutes>(
"::flecs::units::Duration::Minutes");
world.entity<duration::Hours>(
"::flecs::units::Duration::Hours");
world.entity<duration::Days>(
"::flecs::units::Duration::Days");
world.entity<time::Date>("::flecs::units::Time::Date");
world.entity<mass::Grams>("::flecs::units::Mass::Grams");
world.entity<mass::KiloGrams>("::flecs::units::Mass::KiloGrams");
world.entity<electric_current::Ampere>
("::flecs::units::ElectricCurrent::Ampere");
world.entity<amount::Mole>("::flecs::units::Amount::Mole");
world.entity<luminous_intensity::Candela>(
"::flecs::units::LuminousIntensity::Candela");
world.entity<force::Newton>("::flecs::units::Force::Newton");
world.entity<length::Meters>("::flecs::units::Length::Meters");
world.entity<length::PicoMeters>("::flecs::units::Length::PicoMeters");
world.entity<length::NanoMeters>("::flecs::units::Length::NanoMeters");
world.entity<length::MicroMeters>("::flecs::units::Length::MicroMeters");
world.entity<length::MilliMeters>("::flecs::units::Length::MilliMeters");
world.entity<length::CentiMeters>("::flecs::units::Length::CentiMeters");
world.entity<length::KiloMeters>("::flecs::units::Length::KiloMeters");
world.entity<length::Miles>("::flecs::units::Length::Miles");
world.entity<length::Pixels>("::flecs::units::Length::Pixels");
world.entity<pressure::Pascal>("::flecs::units::Pressure::Pascal");
world.entity<pressure::Bar>("::flecs::units::Pressure::Bar");
world.entity<speed::MetersPerSecond>(
"::flecs::units::Speed::MetersPerSecond");
world.entity<speed::KiloMetersPerSecond>(
"::flecs::units::Speed::KiloMetersPerSecond");
world.entity<speed::KiloMetersPerHour>(
"::flecs::units::Speed::KiloMetersPerHour");
world.entity<speed::MilesPerHour>(
"::flecs::units::Speed::MilesPerHour");
world.entity<temperature::Kelvin>(
"::flecs::units::Temperature::Kelvin");
world.entity<temperature::Celsius>(
"::flecs::units::Temperature::Celsius");
world.entity<temperature::Fahrenheit>(
"::flecs::units::Temperature::Fahrenheit");
world.entity<data::Bits>(
"::flecs::units::Data::Bits");
world.entity<data::KiloBits>(
"::flecs::units::Data::KiloBits");
world.entity<data::MegaBits>(
"::flecs::units::Data::MegaBits");
world.entity<data::GigaBits>(
"::flecs::units::Data::GigaBits");
world.entity<data::Bytes>(
"::flecs::units::Data::Bytes");
world.entity<data::KiloBytes>(
"::flecs::units::Data::KiloBytes");
world.entity<data::MegaBytes>(
"::flecs::units::Data::MegaBytes");
world.entity<data::GigaBytes>(
"::flecs::units::Data::GigaBytes");
world.entity<data::KibiBytes>(
"::flecs::units::Data::KibiBytes");
world.entity<data::MebiBytes>(
"::flecs::units::Data::MebiBytes");
world.entity<data::GibiBytes>(
"::flecs::units::Data::GibiBytes");
world.entity<datarate::BitsPerSecond>(
"::flecs::units::DataRate::BitsPerSecond");
world.entity<datarate::KiloBitsPerSecond>(
"::flecs::units::DataRate::KiloBitsPerSecond");
world.entity<datarate::MegaBitsPerSecond>(
"::flecs::units::DataRate::MegaBitsPerSecond");
world.entity<datarate::GigaBitsPerSecond>(
"::flecs::units::DataRate::GigaBitsPerSecond");
world.entity<datarate::BytesPerSecond>(
"::flecs::units::DataRate::BytesPerSecond");
world.entity<datarate::KiloBytesPerSecond>(
"::flecs::units::DataRate::KiloBytesPerSecond");
world.entity<datarate::MegaBytesPerSecond>(
"::flecs::units::DataRate::MegaBytesPerSecond");
world.entity<datarate::GigaBytesPerSecond>(
"::flecs::units::DataRate::GigaBytesPerSecond");
world.entity<frequency::Hertz>(
"::flecs::units::Frequency::Hertz");
world.entity<frequency::KiloHertz>(
"::flecs::units::Frequency::KiloHertz");
world.entity<frequency::MegaHertz>(
"::flecs::units::Frequency::MegaHertz");
world.entity<frequency::GigaHertz>(
"::flecs::units::Frequency::GigaHertz");
world.entity<uri::Hyperlink>(
"::flecs::units::Uri::Hyperlink");
world.entity<uri::Image>(
"::flecs::units::Uri::Image");
world.entity<uri::File>(
"::flecs::units::Uri::File");
world.entity<angle::Radians>(
"::flecs::units::Angle::Radians");
world.entity<angle::Degrees>(
"::flecs::units::Angle::Degrees");
world.entity<Percentage>("::flecs::units::Percentage");
world.entity<Bel>("::flecs::units::Bel");
world.entity<DeciBel>("::flecs::units::DeciBel");
}
}
#endif
#ifdef FLECS_MONITOR
#pragma once
namespace flecs {
inline monitor::monitor(flecs::world& world) {
FlecsMonitorImport(world);
}
}
#endif
#ifdef FLECS_METRICS
#pragma once
namespace flecs {
inline metrics::metrics(flecs::world& world) {
world.import<flecs::units>();
FlecsMetricsImport(world);
world.entity<metrics::Instance>("::flecs::metrics::Instance");
world.entity<metrics::Metric>("::flecs::metrics::Metric");
world.entity<metrics::Counter>("::flecs::metrics::Metric::Counter");
world.entity<metrics::CounterId>("::flecs::metrics::Metric::CounterId");
world.entity<metrics::CounterIncrement>("::flecs::metrics::Metric::CounterIncrement");
world.entity<metrics::Gauge>("::flecs::metrics::Metric::Gauge");
}
inline metric_builder::~metric_builder() {
if (!m_created) {
ecs_metric_init(m_world, &m_desc);
}
}
inline metric_builder& metric_builder::member(const char *name) {
return member(flecs::world(m_world).lookup(name));
}
template <typename T>
inline metric_builder& metric_builder::member(const char *name) {
flecs::entity e (m_world, _::cpp_type<T>::id(m_world));
flecs::entity_t m = e.lookup(name);
if (!m) {
flecs::log::err("member '%s' not found in type '%s'",
name, e.path().c_str());
return *this;
}
return member(m);
}
inline metric_builder& metric_builder::dotmember(const char *expr) {
m_desc.dotmember = expr;
return *this;
}
template <typename T>
inline metric_builder& metric_builder::dotmember(const char *expr) {
m_desc.dotmember = expr;
m_desc.id = _::cpp_type<T>::id(m_world);
return *this;
}
inline metric_builder::operator flecs::entity() {
if (!m_created) {
m_created = true;
flecs::entity result(m_world, ecs_metric_init(m_world, &m_desc));
m_desc.entity = result;
return result;
} else {
return flecs::entity(m_world, m_desc.entity);
}
}
template <typename... Args>
inline flecs::metric_builder world::metric(Args &&... args) const {
flecs::entity result(m_world, FLECS_FWD(args)...);
return flecs::metric_builder(m_world, result);
}
template <typename Kind>
inline untyped_component& untyped_component::metric(
flecs::entity_t parent,
const char *brief,
const char *metric_name)
{
flecs::world w(m_world);
flecs::entity e(m_world, m_id);
const flecs::member_t *m = ecs_cpp_last_member(w, e);
if (!m) {
return *this;
}
flecs::entity me = w.entity(m->member);
flecs::entity metric_entity = me;
if (parent) {
const char *component_name = e.name();
if (!metric_name) {
if (ecs_os_strcmp(m->name, "value") || !component_name) {
metric_entity = w.scope(parent).entity(m->name);
} else {
char *snake_name = flecs_to_snake_case(component_name);
metric_entity = w.scope(parent).entity(snake_name);
ecs_os_free(snake_name);
}
} else {
metric_entity = w.scope(parent).entity(metric_name);
}
}
w.metric(metric_entity).member(me).kind<Kind>().brief(brief);
return *this;
}
}
#endif
#ifdef FLECS_ALERTS
#pragma once
#pragma once
#pragma once
namespace flecs {
template<typename Base, typename ... Components>
struct alert_builder_i : filter_builder_i<Base, Components ...> {
private:
using BaseClass = filter_builder_i<Base, Components ...>;
public:
alert_builder_i()
: BaseClass(nullptr)
, m_desc(nullptr) { }
alert_builder_i(ecs_alert_desc_t *desc, int32_t term_index = 0)
: BaseClass(&desc->filter, term_index)
, m_desc(desc) { }
Base& message(const char *message) {
m_desc->message = message;
return *this;
}
Base& brief(const char *brief) {
m_desc->brief = brief;
return *this;
}
Base& doc_name(const char *doc_name) {
m_desc->doc_name = doc_name;
return *this;
}
Base& severity(flecs::entity_t kind) {
m_desc->severity = kind;
return *this;
}
Base& retain_period(ecs_ftime_t period) {
m_desc->retain_period = period;
return *this;
}
template <typename Severity>
Base& severity() {
return severity(_::cpp_type<Severity>::id(world_v()));
}
Base& severity_filter(flecs::entity_t kind, flecs::id_t with, const char *var = nullptr) {
ecs_assert(severity_filter_count < ECS_ALERT_MAX_SEVERITY_FILTERS,
ECS_INVALID_PARAMETER, "Maxium number of severity filters reached");
ecs_alert_severity_filter_t *filter =
&m_desc->severity_filters[severity_filter_count ++];
filter->severity = kind;
filter->with = with;
filter->var = var;
return *this;
}
template <typename Severity>
Base& severity_filter(flecs::id_t with, const char *var = nullptr) {
return severity_filter(_::cpp_type<Severity>::id(world_v()), with, var);
}
template <typename Severity, typename T, if_not_t< is_enum<T>::value > = 0>
Base& severity_filter(const char *var = nullptr) {
return severity_filter(_::cpp_type<Severity>::id(world_v()),
_::cpp_type<T>::id(world_v()), var);
}
template <typename Severity, typename T, if_t< is_enum<T>::value > = 0 >
Base& severity_filter(T with, const char *var = nullptr) {
flecs::world w(world_v());
flecs::entity constant = w.to_entity<T>(with);
return severity_filter(_::cpp_type<Severity>::id(world_v()),
w.pair<T>(constant), var);
}
Base& member(flecs::entity_t m) {
m_desc->member = m;
return *this;
}
Base& id(flecs::id_t id) {
m_desc->id = id;
return *this;
}
template <typename T>
Base& member(const char *m, const char *v = nullptr) {
flecs::entity_t id = _::cpp_type<T>::id(world_v());
flecs::entity_t mid = ecs_lookup_path_w_sep(
world_v(), id, m, "::", "::", false);
ecs_assert(m != 0, ECS_INVALID_PARAMETER, NULL);
m_desc->var = v;
return this->member(mid);
}
Base& var(const char *v) {
m_desc->var = v;
return *this;
}
protected:
virtual flecs::world_t* world_v() = 0;
private:
operator Base&() {
return *static_cast<Base*>(this);
}
ecs_alert_desc_t *m_desc;
int32_t severity_filter_count = 0;
};
}
namespace flecs {
namespace _ {
template <typename ... Components>
using alert_builder_base = builder<
alert, ecs_alert_desc_t, alert_builder<Components...>,
alert_builder_i, Components ...>;
}
template <typename ... Components>
struct alert_builder final : _::alert_builder_base<Components...> {
alert_builder(flecs::world_t* world, const char *name = nullptr)
: _::alert_builder_base<Components...>(world)
{
_::sig<Components...>(world).populate(this);
if (name != nullptr) {
ecs_entity_desc_t entity_desc = {};
entity_desc.name = name;
entity_desc.sep = "::";
entity_desc.root_sep = "::";
this->m_desc.entity = ecs_entity_init(world, &entity_desc);
}
}
};
}
namespace flecs {
template <typename ... Components>
struct alert final : entity
{
using entity::entity;
explicit alert() {
m_id = 0;
m_world = nullptr;
}
explicit alert(flecs::world_t *world, ecs_alert_desc_t *desc)
{
m_world = world;
m_id = ecs_alert_init(world, desc);
if (desc->filter.terms_buffer) {
ecs_os_free(desc->filter.terms_buffer);
}
}
};
inline alerts::alerts(flecs::world& world) {
FlecsAlertsImport(world);
world.entity<alerts::Alert>("::flecs::alerts::Alert");
world.entity<alerts::Info>("::flecs::alerts::Info");
world.entity<alerts::Warning>("::flecs::alerts::Warning");
world.entity<alerts::Error>("::flecs::alerts::Error");
}
template <typename... Comps, typename... Args>
inline flecs::alert_builder<Comps...> world::alert(Args &&... args) const {
return flecs::alert_builder<Comps...>(m_world, FLECS_FWD(args)...);
}
}
#endif
#pragma once
namespace flecs
{
inline flecs::entity iter::system() const {
return flecs::entity(m_iter->world, m_iter->system);
}
inline flecs::entity iter::event() const {
return flecs::entity(m_iter->world, m_iter->event);
}
inline flecs::id iter::event_id() const {
return flecs::id(m_iter->world, m_iter->event_id);
}
inline flecs::world iter::world() const {
return flecs::world(m_iter->world);
}
inline flecs::entity iter::entity(size_t row) const {
ecs_assert(row < static_cast<size_t>(m_iter->count),
ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
return flecs::entity(m_iter->world, m_iter->entities[row]);
}
template <typename T>
inline column<T>::column(iter &iter, int32_t index) {
*this = iter.field<T>(index);
}
inline flecs::entity iter::src(int32_t index) const {
return flecs::entity(m_iter->world, ecs_field_src(m_iter, index));
}
inline flecs::id iter::id(int32_t index) const {
return flecs::id(m_iter->world, ecs_field_id(m_iter, index));
}
inline flecs::id iter::pair(int32_t index) const {
flecs::id_t id = ecs_field_id(m_iter, index);
ecs_check(ECS_HAS_ID_FLAG(id, PAIR), ECS_INVALID_PARAMETER, NULL);
return flecs::id(m_iter->world, id);
error:
return flecs::id();
}
inline flecs::type iter::type() const {
return flecs::type(m_iter->world, ecs_table_get_type(m_iter->table));
}
inline flecs::table iter::table() const {
return flecs::table(m_iter->real_world, m_iter->table);
}
inline flecs::table_range iter::range() const {
return flecs::table_range(m_iter->real_world, m_iter->table,
m_iter->offset, m_iter->count);
}
#ifdef FLECS_RULES
inline flecs::entity iter::get_var(int var_id) const {
ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, 0);
return flecs::entity(m_iter->world, ecs_iter_get_var(m_iter, var_id));
}
inline flecs::entity iter::get_var(const char *name) const {
ecs_rule_iter_t *rit = &m_iter->priv.iter.rule;
const flecs::rule_t *r = rit->rule;
int var_id = ecs_rule_find_var(r, name);
ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, name);
return flecs::entity(m_iter->world, ecs_iter_get_var(m_iter, var_id));
}
#endif
}
#pragma once
namespace flecs
{
inline void world::init_builtin_components() {
# ifdef FLECS_SYSTEM
_::system_init(*this);
# endif
# ifdef FLECS_TIMER
_::timer_init(*this);
# endif
# ifdef FLECS_DOC
doc::_::init(*this);
# endif
# ifdef FLECS_REST
rest::_::init(*this);
# endif
# ifdef FLECS_META
meta::_::init(*this);
# endif
}
template <typename T>
inline flecs::entity world::use(const char *alias) const {
entity_t e = _::cpp_type<T>::id(m_world);
const char *name = alias;
if (!name) {
name = ecs_get_name(m_world, e);
}
ecs_set_alias(m_world, e, name);
return flecs::entity(m_world, e);
}
inline flecs::entity world::use(const char *name, const char *alias) const {
entity_t e = ecs_lookup_path_w_sep(m_world, 0, name, "::", "::", true);
ecs_assert(e != 0, ECS_INVALID_PARAMETER, NULL);
ecs_set_alias(m_world, e, alias);
return flecs::entity(m_world, e);
}
inline void world::use(flecs::entity e, const char *alias) const {
entity_t eid = e.id();
const char *name = alias;
if (!name) {
name = ecs_get_name(m_world, eid);
}
ecs_set_alias(m_world, eid, name);
}
inline flecs::entity world::set_scope(const flecs::entity_t s) const {
return flecs::entity(ecs_set_scope(m_world, s));
}
inline flecs::entity world::get_scope() const {
return flecs::entity(m_world, ecs_get_scope(m_world));
}
template <typename T>
inline flecs::entity world::set_scope() const {
return set_scope( _::cpp_type<T>::id(m_world) );
}
inline entity world::lookup(const char *name, bool search_path) const {
auto e = ecs_lookup_path_w_sep(m_world, 0, name, "::", "::", search_path);
return flecs::entity(*this, e);
}
template <typename T>
inline T* world::get_mut() const {
flecs::entity e(m_world, _::cpp_type<T>::id(m_world));
return e.get_mut<T>();
}
template <typename T>
inline void world::modified() const {
flecs::entity e(m_world, _::cpp_type<T>::id(m_world));
e.modified<T>();
}
template <typename First, typename Second>
inline void world::set(Second second, const First& value) const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
e.set<First>(second, value);
}
template <typename First, typename Second>
inline void world::set(Second second, First&& value) const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
e.set<First>(second, value);
}
template <typename T>
inline ref<T> world::get_ref() const {
flecs::entity e(m_world, _::cpp_type<T>::id(m_world));
return e.get_ref<T>();
}
template <typename T>
inline const T* world::get() const {
flecs::entity e(m_world, _::cpp_type<T>::id(m_world));
return e.get<T>();
}
template <typename First, typename Second, typename P, typename A>
const A* world::get() const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
return e.get<First, Second>();
}
template <typename First, typename Second>
const First* world::get(Second second) const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
return e.get<First>(second);
}
template <typename T>
inline bool world::has() const {
flecs::entity e(m_world, _::cpp_type<T>::id(m_world));
return e.has<T>();
}
template <typename First, typename Second>
inline bool world::has() const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
return e.has<First, Second>();
}
template <typename First>
inline bool world::has(flecs::id_t second) const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
return e.has<First>(second);
}
inline bool world::has(flecs::id_t first, flecs::id_t second) const {
flecs::entity e(m_world, first);
return e.has(first, second);
}
template <typename T>
inline void world::add() const {
flecs::entity e(m_world, _::cpp_type<T>::id(m_world));
e.add<T>();
}
template <typename First, typename Second>
inline void world::add() const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
e.add<First, Second>();
}
template <typename First>
inline void world::add(flecs::entity_t second) const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
e.add<First>(second);
}
inline void world::add(flecs::entity_t first, flecs::entity_t second) const {
flecs::entity e(m_world, first);
e.add(first, second);
}
template <typename T>
inline void world::remove() const {
flecs::entity e(m_world, _::cpp_type<T>::id(m_world));
e.remove<T>();
}
template <typename First, typename Second>
inline void world::remove() const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
e.remove<First, Second>();
}
template <typename First>
inline void world::remove(flecs::entity_t second) const {
flecs::entity e(m_world, _::cpp_type<First>::id(m_world));
e.remove<First>(second);
}
inline void world::remove(flecs::entity_t first, flecs::entity_t second) const {
flecs::entity e(m_world, first);
e.remove(first, second);
}
template <typename Func>
inline void world::children(Func&& f) const {
this->entity(0).children(FLECS_FWD(f));
}
template <typename T>
inline flecs::entity world::singleton() const {
return flecs::entity(m_world, _::cpp_type<T>::id(m_world));
}
template <typename First>
inline flecs::entity world::target(int32_t index) const
{
return flecs::entity(m_world,
ecs_get_target(m_world, _::cpp_type<First>::id(m_world), _::cpp_type<First>::id(m_world), index));
}
template <typename T>
inline flecs::entity world::target(
flecs::entity_t relationship,
int32_t index) const
{
return flecs::entity(m_world,
ecs_get_target(m_world, _::cpp_type<T>::id(m_world), relationship, index));
}
inline flecs::entity world::target(
flecs::entity_t relationship,
int32_t index) const
{
return flecs::entity(m_world,
ecs_get_target(m_world, relationship, relationship, index));
}
template <typename Func, if_t< is_callable<Func>::value > >
inline void world::get(const Func& func) const {
static_assert(arity<Func>::value == 1, "singleton component must be the only argument");
_::entity_with_invoker<Func>::invoke_get(
this->m_world, this->singleton<first_arg_t<Func>>(), func);
}
template <typename Func, if_t< is_callable<Func>::value > >
inline void world::set(const Func& func) const {
static_assert(arity<Func>::value == 1, "singleton component must be the only argument");
_::entity_with_invoker<Func>::invoke_get_mut(
this->m_world, this->singleton<first_arg_t<Func>>(), func);
}
inline flecs::entity world::get_alive(flecs::entity_t e) const {
e = ecs_get_alive(m_world, e);
return flecs::entity(m_world, e);
}
#ifndef ensure
inline flecs::entity world::ensure(flecs::entity_t e) const {
ecs_ensure(m_world, e);
return flecs::entity(m_world, e);
}
#endif
template <typename E>
inline flecs::entity enum_data<E>::entity() const {
return flecs::entity(world_, impl_.id);
}
template <typename E>
inline flecs::entity enum_data<E>::entity(int value) const {
return flecs::entity(world_, impl_.constants[value].id);
}
template <typename E>
inline flecs::entity enum_data<E>::entity(E value) const {
return flecs::entity(world_, impl_.constants[static_cast<int>(value)].id);
}
inline flecs::scoped_world world::scope(id_t parent) const {
return scoped_world(m_world, parent);
}
template <typename T>
inline flecs::scoped_world world::scope() const {
flecs::id_t parent = _::cpp_type<T>::id(m_world);
return scoped_world(m_world, parent);
}
inline flecs::scoped_world world::scope(const char* name) const {
return scope(entity(name));
}
}
#endif
#endif
#endif
#endif