Skip to content

Commit

Permalink
#680 simplify component lifecycle signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Mar 23, 2022
1 parent 98e722f commit d49c3f1
Show file tree
Hide file tree
Showing 23 changed files with 834 additions and 1,158 deletions.
494 changes: 222 additions & 272 deletions flecs.c

Large diffs are not rendered by default.

214 changes: 41 additions & 173 deletions flecs.h

Large diffs are not rendered by default.

12 changes: 4 additions & 8 deletions include/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,27 +321,19 @@ typedef uint64_t (*ecs_hash_value_action_t)(

/** Constructor/destructor callback */
typedef void (*ecs_xtor_t)(
ecs_world_t *world,
const ecs_entity_t *entities,
void *ptr,
int32_t count,
const ecs_type_info_t *type_info);

/** Copy is invoked when a component is copied into another component. */
typedef void (*ecs_copy_t)(
ecs_world_t *world,
const ecs_entity_t *dst_entities,
const ecs_entity_t *src_entities,
void *dst_ptr,
const void *src_ptr,
int32_t count,
const ecs_type_info_t *type_info);

/** Move is invoked when a component is moved to another component. */
typedef void (*ecs_move_t)(
ecs_world_t *world,
const ecs_entity_t *dst_entities,
const ecs_entity_t *src_entities,
void *dst_ptr,
void *src_ptr,
int32_t count,
Expand Down Expand Up @@ -881,6 +873,10 @@ typedef struct EcsComponentLifecycle {
* not set explicitly it will be derived from other callbacks. */
ecs_move_t move_dtor;

/* Callback that is invoked when an instance of a component is added. This
* callback is invoked before triggers are invoked. */
ecs_iter_action_t on_add;

/* Callback that is invoked when an instance of the component is set. This
* callback is invoked before triggers are invoked, and enable the component
* to respond to changes on itself before others can. */
Expand Down
1 change: 0 additions & 1 deletion include/flecs/addons/cpp/impl.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#include "impl/lifecycle_traits.hpp"
#include "impl/iter.hpp"
#include "impl/world.hpp"
25 changes: 0 additions & 25 deletions include/flecs/addons/cpp/impl/lifecycle_traits.hpp

This file was deleted.

144 changes: 34 additions & 110 deletions include/flecs/addons/cpp/lifecycle_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,41 @@ namespace flecs
namespace _
{

inline void ecs_ctor_illegal(ecs_world_t* w, const ecs_entity_t*,
void *, int32_t, const ecs_type_info_t* info)
{
char *path = ecs_get_path_w_sep(w, 0, info->component, "::", "::");
ecs_abort(ECS_INVALID_OPERATION,
"cannnot default construct %s, add %s::%s() or use emplace<T>",
path, path, ecs_get_name(w, info->component));
ecs_os_free(path);
inline void ecs_ctor_illegal(void *, int32_t, const ecs_type_info_t*) {
ecs_abort(ECS_INVALID_OPERATION, "invalid constructor");
}

inline void ecs_dtor_illegal(ecs_world_t* w, const ecs_entity_t*,
void *, int32_t, const ecs_type_info_t *info)
{
char *path = ecs_get_path_w_sep(w, 0, info->component, "::", "::");
ecs_abort(ECS_INVALID_OPERATION, "cannnot destruct %s, add ~%s::%s()",
path, path, ecs_get_name(w, info->component));
ecs_os_free(path);
inline void ecs_dtor_illegal(void *, int32_t, const ecs_type_info_t*) {
ecs_abort(ECS_INVALID_OPERATION, "invalid destructor");
}

inline void ecs_copy_illegal(ecs_world_t* w, const ecs_entity_t*,
const ecs_entity_t*, void *, const void *, int32_t, const ecs_type_info_t *info)
inline void ecs_copy_illegal(
void *, const void *, int32_t, const ecs_type_info_t *)
{
char *path = ecs_get_path_w_sep(w, 0, info->component, "::", "::");
ecs_abort(ECS_INVALID_OPERATION,
"cannnot copy assign %s, add %s& %s::operator =(const %s&)", path,
ecs_get_name(w, info->component), path, ecs_get_name(w, info->component), ecs_get_name(w, info->component));
ecs_os_free(path);
ecs_abort(ECS_INVALID_OPERATION, "invalid copy assignment");
}

inline void ecs_move_illegal(ecs_world_t* w, const ecs_entity_t*,
const ecs_entity_t*, void *, void *, int32_t, const ecs_type_info_t *info)
{
char *path = ecs_get_path_w_sep(w, 0, info->component, "::", "::");
ecs_abort(ECS_INVALID_OPERATION,
"cannnot move assign %s, add %s& %s::operator =(%s&&)", path,
ecs_get_name(w, info->component), path, ecs_get_name(w, info->component), ecs_get_name(w, info->component));
ecs_os_free(path);
inline void ecs_move_illegal(void *, void *, int32_t, const ecs_type_info_t *) {
ecs_abort(ECS_INVALID_OPERATION, "invalid move assignment");
}

inline void ecs_copy_ctor_illegal(ecs_world_t* w,
const ecs_entity_t*, const ecs_entity_t*,
void *, const void *, int32_t, const ecs_type_info_t *info)
inline void ecs_copy_ctor_illegal(
void *, const void *, int32_t, const ecs_type_info_t *)
{
char *path = ecs_get_path_w_sep(w, 0, info->component, "::", "::");
ecs_abort(ECS_INVALID_OPERATION,
"cannnot copy construct %s, add %s::%s(const %s&)",
path, path, ecs_get_name(w, info->component), ecs_get_name(w, info->component));
ecs_os_free(path);
ecs_abort(ECS_INVALID_OPERATION, "invalid copy construct");
}

inline void ecs_move_ctor_illegal(ecs_world_t* w,
const ecs_entity_t*, const ecs_entity_t*,
void *, void *, int32_t, const ecs_type_info_t *info)
inline void ecs_move_ctor_illegal(
void *, void *, int32_t, const ecs_type_info_t *)
{
char *path = ecs_get_path_w_sep(w, 0, info->component, "::", "::");
ecs_abort(ECS_INVALID_OPERATION,
"cannnot move construct %s, add %s::%s(%s&&)",
path, path, ecs_get_name(w, info->component), ecs_get_name(w, info->component));
ecs_os_free(path);
ecs_abort(ECS_INVALID_OPERATION, "invalid move construct");
}


// T()
// Can't coexist with T(flecs::entity) or T(flecs::world, flecs::entity)
template <typename T>
void ctor_impl(
ecs_world_t*, const ecs_entity_t*, void *ptr, int32_t count,
const ecs_type_info_t *info)
{
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);
Expand All @@ -81,18 +47,9 @@ void ctor_impl(
}
}

// T(flecs::world, flecs::entity)
template <typename T>
void ctor_world_entity_impl(
ecs_world_t* world, const ecs_entity_t* ids, void *ptr, int32_t count,
const ecs_type_info_t *info);

// ~T()
template <typename T>
void dtor_impl(
ecs_world_t*, const ecs_entity_t*, void *ptr, int32_t count,
const ecs_type_info_t *info)
{
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);
Expand All @@ -103,9 +60,8 @@ void dtor_impl(

// T& operator=(const T&)
template <typename T>
void copy_impl(
ecs_world_t*, const ecs_entity_t*, const ecs_entity_t*, void *dst_ptr,
const void *src_ptr, int32_t count, const ecs_type_info_t *info)
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);
Expand All @@ -118,9 +74,8 @@ void copy_impl(

// T& operator=(T&&)
template <typename T>
void move_impl(
ecs_world_t*, const ecs_entity_t*, const ecs_entity_t*, void *dst_ptr,
void *src_ptr, int32_t count, const ecs_type_info_t *info)
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);
Expand All @@ -133,9 +88,8 @@ void move_impl(

// T(T&)
template <typename T>
void copy_ctor_impl(
ecs_world_t*, const ecs_entity_t*, const ecs_entity_t*, void *dst_ptr,
const void *src_ptr, int32_t count, const ecs_type_info_t *info)
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);
Expand All @@ -148,9 +102,8 @@ void copy_ctor_impl(

// T(T&&)
template <typename T>
void move_ctor_impl(
ecs_world_t*, const ecs_entity_t*, const ecs_entity_t*, void *dst_ptr,
void *src_ptr, int32_t count, const ecs_type_info_t *info)
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);
Expand All @@ -164,9 +117,8 @@ void move_ctor_impl(
// T(T&&), ~T()
// Typically used when moving to a new table, and removing from the old table
template <typename T>
void ctor_move_dtor_impl(
ecs_world_t*, const ecs_entity_t*, const ecs_entity_t*, void *dst_ptr,
void *src_ptr, int32_t count, const ecs_type_info_t *info)
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);
Expand All @@ -182,9 +134,8 @@ void ctor_move_dtor_impl(
// Typically used when moving a component to a deleted component
template <typename T, if_not_t<
std::is_trivially_move_assignable<T>::value > = 0>
void move_dtor_impl(
ecs_world_t*, const ecs_entity_t*, const ecs_entity_t*, void *dst_ptr,
void *src_ptr, int32_t count, const ecs_type_info_t *info)
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);
Expand All @@ -203,9 +154,8 @@ void move_dtor_impl(
// Typically used when moving a component to a deleted component
template <typename T, if_t<
std::is_trivially_move_assignable<T>::value > = 0>
void move_dtor_impl(
ecs_world_t*, const ecs_entity_t*, const ecs_entity_t*, void *dst_ptr,
void *src_ptr, int32_t count, const ecs_type_info_t *info)
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);
Expand All @@ -224,29 +174,11 @@ void move_dtor_impl(

} // _

// Trait to test if type has flecs constructor
template <typename T>
struct has_flecs_ctor {
static constexpr bool value =
std::is_constructible<actual_type_t<T>,
flecs::world&, flecs::entity>::value;
};

// Trait to test if type is constructible by flecs
template <typename T>
struct is_flecs_constructible {
static constexpr bool value =
std::is_default_constructible<actual_type_t<T>>::value ||
std::is_constructible<actual_type_t<T>,
flecs::world&, flecs::entity>::value;
};

// Trait to test if type has a self constructor (flecs::entity, Args...)
template <typename T, typename ... Args>
struct is_self_constructible {
static constexpr bool value =
std::is_constructible<actual_type_t<T>,
flecs::entity, Args...>::value;
std::is_default_constructible<actual_type_t<T>>::value;
};

namespace _
Expand All @@ -260,27 +192,19 @@ ecs_xtor_t ctor() {

// Not constructible by flecs
template <typename T, if_t<
! std::is_default_constructible<T>::value &&
! has_flecs_ctor<T>::value > = 0>
! std::is_default_constructible<T>::value > = 0>
ecs_xtor_t ctor() {
return ecs_ctor_illegal;
}

// Default constructible
template <typename T, if_t<
! std::is_trivially_constructible<T>::value &&
std::is_default_constructible<T>::value &&
! has_flecs_ctor<T>::value > = 0>
std::is_default_constructible<T>::value > = 0>
ecs_xtor_t ctor() {
return ctor_impl<T>;
}

// Flecs constructible: T(flecs::world, flecs::entity)
template <typename T, if_t< has_flecs_ctor<T>::value > = 0>
ecs_xtor_t ctor() {
return ctor_world_entity_impl<T>;
}

// No dtor
template <typename T, if_t< std::is_trivially_destructible<T>::value > = 0>
ecs_xtor_t dtor() {
Expand Down
2 changes: 2 additions & 0 deletions include/flecs/addons/flecs_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,8 @@
#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_query_new(world, q_expr)\
ecs_query_init(world, &(ecs_query_desc_t){\
Expand Down
Loading

0 comments on commit d49c3f1

Please sign in to comment.