Properly link flecs library

This commit is contained in:
2023-11-09 11:38:29 +01:00
parent dc585396c3
commit 8edcf9305c
1392 changed files with 390081 additions and 164 deletions

View File

@@ -579,6 +579,13 @@ extern "C" {
#endif
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#pragma GCC diagnostic ignored "-Wunused-macros"
/* This warning gets thrown *sometimes* when not all members for a struct are
* provided in an initializer. Flecs heavily relies on descriptor structs that
* only require partly initialization, so this warning isn't useful.
* It doesn't introduce any safety issues (fields are guaranteed to be 0
* initialized), and later versions of gcc (>=11) seem to no longer throw this
* warning. */
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
/* Standard library dependencies */
@@ -16768,7 +16775,7 @@ using return_type_t = typename _::function_traits<T>::return_type;
template <typename T>
using arg_list_t = typename _::function_traits<T>::args;
// First arg
template<typename Func, typename ... Args>
struct first_arg_impl;
@@ -16785,6 +16792,23 @@ struct first_arg {
template <typename Func>
using first_arg_t = typename first_arg<Func>::type;
// Last arg
template<typename Func, typename ... Args>
struct second_arg_impl;
template<typename Func, typename First, typename T, typename ... Args>
struct second_arg_impl<Func, _::arg_list<First, T, Args ...> > {
using type = T;
};
template<typename Func>
struct second_arg {
using type = typename second_arg_impl<Func, arg_list_t<Func>>::type;
};
template <typename Func>
using second_arg_t = typename second_arg<Func>::type;
} // flecs
@@ -17073,15 +17097,7 @@ struct event_builder_base {
/** Set entity for which to emit event */
Base& entity(flecs::entity_t e) {
ecs_record_t *r = ecs_record_find(m_world, e);
/* Can't emit for empty entity */
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;
m_desc.entity = e;
return *this;
}
@@ -17100,8 +17116,6 @@ struct event_builder_base {
}
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));
@@ -17144,6 +17158,31 @@ public:
}
namespace flecs {
namespace _ {
// Utility to derive event type from function
template <typename Func, typename U = int>
struct event_from_func;
// Specialization for observer callbacks with a single argument
template <typename Func>
struct event_from_func<Func, if_t< arity<Func>::value == 1>> {
using type = decay_t<first_arg_t<Func>>;
};
// Specialization for observer callbacks with an initial entity src argument
template <typename Func>
struct event_from_func<Func, if_t< arity<Func>::value == 2>> {
using type = decay_t<second_arg_t<Func>>;
};
template <typename Func>
using event_from_func_t = typename event_from_func<Func>::type;
}
}
/**
* @file addons/cpp/mixins/query/decl.hpp
* @brief Query declarations.
@@ -19250,6 +19289,8 @@ namespace flecs
*/
template <typename T>
struct ref {
ref() : m_world(nullptr), m_ref{} { }
ref(world_t *world, entity_t entity, flecs::id_t id = 0)
: m_ref()
{
@@ -19280,6 +19321,14 @@ struct ref {
m_world, &m_ref, this->m_ref.id));
}
T* try_get() {
if (!m_world || !m_ref.entity) {
return nullptr;
}
return get();
}
flecs::entity entity() const;
private:
@@ -22400,6 +22449,59 @@ template <typename E>
E to_constant() const;
/**
* @file addons/cpp/mixins/event/entity_builder.hpp
* @brief Event entity mixin.
*/
/** Emit event for entity.
*
* \memberof flecs::entity_view
*
* @param evt The event to emit.
*/
void emit(flecs::entity_t evt) {
flecs::world(m_world)
.event(evt)
.entity(m_id)
.emit();
}
/** Emit event for entity.
*
* \memberof flecs::entity_view
*
* @param evt The event to emit.
*/
void emit(flecs::entity evt);
/** Emit event for entity.
*
* \memberof flecs::entity_view
*
* @tparam Evt The event to emit.
*/
template <typename Evt, if_t<is_empty<Evt>::value> = 0>
void emit() {
this->emit(_::cpp_type<Evt>::id(m_world));
}
/** Emit event with payload for entity.
*
* \memberof flecs::entity_view
*
* @tparam Evt The event to emit.
*/
template <typename Evt, if_not_t<is_empty<Evt>::value> = 0>
void emit(const Evt& payload) {
flecs::world(m_world)
.event(_::cpp_type<Evt>::id(m_world))
.entity(m_id)
.ctx(&payload)
.emit();
}
private:
flecs::entity set_stage(world_t *stage);
@@ -23622,6 +23724,45 @@ Self& set_json_second(
# endif
/**
* @file addons/cpp/mixins/event/entity_builder.hpp
* @brief Event entity mixin.
*/
/** Observe event on entity
*
* \memberof flecs::entity_builder
*
* @param evt The event id.
* @param callback The observer callback.
* @return Event builder.
*/
template <typename Func>
Self& observe(flecs::entity_t evt, Func&& callback);
/** Observe event on entity
*
* \memberof flecs::entity_builder
*
* @tparam Evt The event type.
* @param callback The observer callback.
* @return Event builder.
*/
template <typename Evt, typename Func>
Self& observe(Func&& callback);
/** Observe event on entity
*
* \memberof flecs::entity_builder
*
* @param callback The observer callback.
* @return Event builder.
*/
template <typename Func>
Self& observe(Func&& callback);
protected:
Self& to_base() {
@@ -24514,6 +24655,76 @@ private:
};
////////////////////////////////////////////////////////////////////////////////
//// Utility class to invoke an entity observer delegate
////////////////////////////////////////////////////////////////////////////////
template <typename Func>
struct entity_observer_delegate : delegate {
explicit entity_observer_delegate(Func&& func) noexcept
: m_func(FLECS_MOV(func)) { }
// Static function that can be used as callback for systems/triggers
static void run(ecs_iter_t *iter) {
invoke<Func>(iter);
}
private:
template <typename F, if_t<arity<F>::value == 1> = 0>
static void invoke(ecs_iter_t *iter) {
auto self = static_cast<const entity_observer_delegate*>(iter->binding_ctx);
ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL);
self->m_func(flecs::entity(iter->world, ecs_field_src(iter, 1)));
}
template <typename F, if_t<arity<F>::value == 0> = 0>
static void invoke(ecs_iter_t *iter) {
auto self = static_cast<const entity_observer_delegate*>(iter->binding_ctx);
ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL);
self->m_func();
}
Func m_func;
};
template <typename Func, typename Event>
struct entity_payload_observer_delegate : delegate {
explicit entity_payload_observer_delegate(Func&& func) noexcept
: m_func(FLECS_MOV(func)) { }
// Static function that can be used as callback for systems/triggers
static void run(ecs_iter_t *iter) {
invoke<Func>(iter);
}
private:
template <typename F, if_t<arity<F>::value == 1> = 0>
static void invoke(ecs_iter_t *iter) {
auto self = static_cast<const entity_payload_observer_delegate*>(
iter->binding_ctx);
ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL);
ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION,
"entity observer invoked without payload");
Event *data = static_cast<Event*>(iter->param);
self->m_func(*data);
}
template <typename F, if_t<arity<F>::value == 2> = 0>
static void invoke(ecs_iter_t *iter) {
auto self = static_cast<const entity_payload_observer_delegate*>(
iter->binding_ctx);
ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL);
ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION,
"entity observer invoked without payload");
Event *data = static_cast<Event*>(iter->param);
self->m_func(flecs::entity(iter->world, ecs_field_src(iter, 1)), *data);
}
Func m_func;
};
////////////////////////////////////////////////////////////////////////////////
//// Utility to invoke callback on entity if it has components in signature
////////////////////////////////////////////////////////////////////////////////
@@ -24898,28 +25109,28 @@ protected:
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>
template < template<typename Func, typename ... Comps> class Delegate, 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()) {
if (Delegate<Func, Components...>::instanced()) {
ECS_BIT_SET(it.flags, EcsIterIsInstanced);
}
while (next(&it, FLECS_FWD(args)...)) {
Invoker<Func, Components...>(func).invoke(&it);
Delegate<Func, Components...>(func).invoke(&it);
}
}
template < template<typename Func, typename ... Comps> class Invoker, typename Func, typename NextFunc, typename ... Args>
template < template<typename Func, typename ... Comps> class Delegate, 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()) {
if (Delegate<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);
result = Delegate<Func, Components...>(func).invoke(&it);
}
if (result) {
ecs_iter_fini(&it);
@@ -25582,6 +25793,17 @@ untyped_component& bit(const char *name, uint32_t value) {
return *this;
}
/** Register array metadata for component */
template <typename Elem>
untyped_component& array(int32_t elem_count) {
ecs_array_desc_t desc = {};
desc.entity = m_id;
desc.type = _::cpp_type<Elem>::id(m_world);
desc.count = elem_count;
ecs_array_init(m_world, &desc);
return *this;
}
/** Add member value range */
untyped_component& range(double min, double max) {
const flecs::member_t *m = ecs_cpp_last_member(m_world, m_id);
@@ -25764,16 +25986,16 @@ struct component : untyped_component {
/** Register on_add hook. */
template <typename Func>
component<T>& on_add(Func&& func) {
using Invoker = typename _::each_delegate<
using Delegate = typename _::each_delegate<
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));
h.on_add = Delegate::run_add;
ctx->on_add = FLECS_NEW(Delegate)(FLECS_FWD(func));
ctx->free_on_add = reinterpret_cast<ecs_ctx_free_t>(
_::free_obj<Invoker>);
_::free_obj<Delegate>);
ecs_set_hooks_id(m_world, m_id, &h);
return *this;
}
@@ -25781,16 +26003,16 @@ struct component : untyped_component {
/** Register on_remove hook. */
template <typename Func>
component<T>& on_remove(Func&& func) {
using Invoker = typename _::each_delegate<
using Delegate = typename _::each_delegate<
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));
h.on_remove = Delegate::run_remove;
ctx->on_remove = FLECS_NEW(Delegate)(FLECS_FWD(func));
ctx->free_on_remove = reinterpret_cast<ecs_ctx_free_t>(
_::free_obj<Invoker>);
_::free_obj<Delegate>);
ecs_set_hooks_id(m_world, m_id, &h);
return *this;
}
@@ -25798,16 +26020,16 @@ struct component : untyped_component {
/** Register on_set hook. */
template <typename Func>
component<T>& on_set(Func&& func) {
using Invoker = typename _::each_delegate<
using Delegate = typename _::each_delegate<
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));
h.on_set = Delegate::run_set;
ctx->on_set = FLECS_NEW(Delegate)(FLECS_FWD(func));
ctx->free_on_set = reinterpret_cast<ecs_ctx_free_t>(
_::free_obj<Invoker>);
_::free_obj<Delegate>);
ecs_set_hooks_id(m_world, m_id, &h);
return *this;
}
@@ -28045,30 +28267,6 @@ inline filter_base::operator flecs::filter<> () const {
}
/**
* @file addons/cpp/mixins/event/impl.hpp
* @brief Event implementation.
*/
#pragma once
namespace flecs
{
// Mixin implementation
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));
}
} // namespace flecs
/**
* @file addons/cpp/mixins/query/impl.hpp
* @brief Query implementation.
@@ -28505,19 +28703,19 @@ public:
* template parameters and anything provided by the signature method. */
template <typename Func>
T iter(Func&& func) {
using Invoker = typename _::iter_delegate<
using Delegate = typename _::iter_delegate<
typename std::decay<Func>::type, Components...>;
return build<Invoker>(FLECS_FWD(func));
return build<Delegate>(FLECS_FWD(func));
}
/* Each is similar to action, but accepts a function that operates on a
* single entity */
template <typename Func>
T each(Func&& func) {
using Invoker = typename _::each_delegate<
using Delegate = typename _::each_delegate<
typename std::decay<Func>::type, Components...>;
m_instanced = true;
return build<Invoker>(FLECS_FWD(func));
return build<Delegate>(FLECS_FWD(func));
}
protected:
@@ -28527,13 +28725,13 @@ protected:
bool m_instanced;
private:
template <typename Invoker, typename Func>
template <typename Delegate, typename Func>
T build(Func&& func) {
auto ctx = FLECS_NEW(Invoker)(FLECS_FWD(func));
m_desc.callback = Invoker::run;
auto ctx = FLECS_NEW(Delegate)(FLECS_FWD(func));
m_desc.callback = Delegate::run;
m_desc.binding_ctx = ctx;
m_desc.binding_ctx_free = reinterpret_cast<
ecs_ctx_free_t>(_::free_obj<Invoker>);
ecs_ctx_free_t>(_::free_obj<Delegate>);
return T(m_world, &m_desc, m_instanced);
}
@@ -28698,6 +28896,109 @@ inline observer_builder<Comps...> world::observer(Args &&... args) const {
} // namespace flecs
/**
* @file addons/cpp/mixins/event/impl.hpp
* @brief Event implementation.
*/
#pragma once
namespace flecs
{
// Mixin implementation
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));
}
namespace _ {
inline void entity_observer_create(
flecs::world_t *world,
flecs::entity_t event,
flecs::entity_t entity,
ecs_iter_action_t callback,
void *binding_ctx,
ecs_ctx_free_t binding_ctx_free)
{
ecs_observer_desc_t desc = {};
desc.events[0] = event;
desc.filter.terms[0].id = EcsAny;
desc.filter.terms[0].src.id = entity;
desc.callback = callback;
desc.binding_ctx = binding_ctx;
desc.binding_ctx_free = binding_ctx_free;
flecs::entity_t o = ecs_observer_init(world, &desc);
ecs_add_pair(world, o, EcsChildOf, entity);
}
template <typename Func>
struct entity_observer_factory {
template <typename Evt, if_t<is_empty<Evt>::value> = 0>
static void create(
flecs::world_t *world,
flecs::entity_t entity,
Func&& f)
{
using Delegate = _::entity_observer_delegate<Func>;
auto ctx = FLECS_NEW(Delegate)(FLECS_FWD(f));
entity_observer_create(world, _::cpp_type<Evt>::id(world), entity, Delegate::run, ctx,
reinterpret_cast<ecs_ctx_free_t>(_::free_obj<Delegate>));
}
template <typename Evt, if_not_t<is_empty<Evt>::value> = 0>
static void create(
flecs::world_t *world,
flecs::entity_t entity,
Func&& f)
{
using Delegate = _::entity_payload_observer_delegate<Func, Evt>;
auto ctx = FLECS_NEW(Delegate)(FLECS_FWD(f));
entity_observer_create(world, _::cpp_type<Evt>::id(world), entity, Delegate::run, ctx,
reinterpret_cast<ecs_ctx_free_t>(_::free_obj<Delegate>));
}
};
}
template <typename Self>
template <typename Func>
inline Self& entity_builder<Self>::observe(flecs::entity_t evt, Func&& f) {
using Delegate = _::entity_observer_delegate<Func>;
auto ctx = FLECS_NEW(Delegate)(FLECS_FWD(f));
_::entity_observer_create(m_world, evt, m_id, Delegate::run, ctx,
reinterpret_cast<ecs_ctx_free_t>(_::free_obj<Delegate>));
return to_base();
}
template <typename Self>
template <typename Evt, typename Func>
inline Self& entity_builder<Self>::observe(Func&& f) {
_::entity_observer_factory<Func>::template create<Evt>(
m_world, m_id, FLECS_FWD(f));
return to_base();
}
template <typename Self>
template <typename Func>
inline Self& entity_builder<Self>::observe(Func&& f) {
return this->observe<_::event_from_func_t<Func>>(FLECS_FWD(f));
}
inline void entity_view::emit(flecs::entity evt) {
this->emit(evt.id());
}
} // namespace flecs
/**
* @file addons/cpp/mixins/enum/impl.hpp
* @brief Enum implementation.