Skip to content

Commit

Permalink
Refactor illegal checks to flags
Browse files Browse the repository at this point in the history
  • Loading branch information
jpeletier committed Nov 18, 2024
1 parent 1b5a685 commit 4339065
Show file tree
Hide file tree
Showing 9 changed files with 625 additions and 727 deletions.
467 changes: 222 additions & 245 deletions distr/flecs.c

Large diffs are not rendered by default.

153 changes: 70 additions & 83 deletions distr/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3522,6 +3522,19 @@ struct ecs_observer_t {
*
* @ingroup components
*/

/* Hook flags */
#define ECS_CTOR_ILLEGAL (1 << 0)
#define ECS_DTOR_ILLEGAL (1 << 1)
#define ECS_COPY_ILLEGAL (1 << 2)
#define ECS_MOVE_ILLEGAL (1 << 3)
#define ECS_COPY_CTOR_ILLEGAL (1 << 4)
#define ECS_MOVE_CTOR_ILLEGAL (1 << 5)
#define ECS_CTOR_MOVE_DTOR_ILLEGAL (1 << 6)
#define ECS_MOVE_DTOR_ILLEGAL (1 << 7)

typedef uint8_t ecs_type_hooks_flags_t;

struct ecs_type_hooks_t {
ecs_xtor_t ctor; /**< ctor */
ecs_xtor_t dtor; /**< dtor */
Expand All @@ -3546,6 +3559,12 @@ struct ecs_type_hooks_t {
* not set explicitly it will be derived from other callbacks. */
ecs_move_t move_dtor;

/** Hook flags
* Indicates if any hook is illegal.
* Setting any flag will configure an aborting hook
*/
ecs_type_hooks_flags_t flags;

/** 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;
Expand Down Expand Up @@ -7384,47 +7403,6 @@ const ecs_type_info_t* ecs_get_type_info(
const ecs_world_t *world,
ecs_id_t id);


/**
* @defgroup illegal_hooks Illegal lifecycle hooks
* Functions to mark specific lifecycle hooks as illegal
*
* @{
*/

/* Illegal constructor handler and constant */
FLECS_API
ecs_xtor_t ecs_ctor_illegal_(void);
#define ECS_CTOR_ILLEGAL (ecs_ctor_illegal_())

/* Illegal destructor handler and constant */
FLECS_API
ecs_xtor_t ecs_dtor_illegal_(void);
#define ECS_DTOR_ILLEGAL (ecs_dtor_illegal_())

/* Illegal copy-assign handler and constant */
FLECS_API
ecs_copy_t ecs_copy_illegal_(void);
#define ECS_COPY_ILLEGAL (ecs_copy_illegal_())

/* Illegal move-assign handler and constant */
FLECS_API
ecs_move_t ecs_move_illegal_(void);
#define ECS_MOVE_ILLEGAL (ecs_move_illegal_())

/* Illegal copy constructor handler and constant */
FLECS_API
ecs_copy_t ecs_copy_ctor_illegal_(void);
#define ECS_COPY_CTOR_ILLEGAL (ecs_copy_ctor_illegal_())

/* Illegal move constructor handler and constant */
FLECS_API
ecs_move_t ecs_move_ctor_illegal_(void);
#define ECS_MOVE_CTOR_ILLEGAL (ecs_move_ctor_illegal_())

/** @} */


/** Register hooks for component.
* Hooks allow for the execution of user code when components are constructed,
* copied, moved, destructed, added, removed or set. Hooks can be assigned as
Expand Down Expand Up @@ -20301,145 +20279,153 @@ namespace _

// Trivially constructible
template <typename T, if_t< std::is_trivially_constructible<T>::value > = 0>
ecs_xtor_t ctor() {
ecs_xtor_t ctor(ecs_type_hooks_flags_t&) {
return nullptr;
}

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

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

// No dtor
template <typename T, if_t< std::is_trivially_destructible<T>::value > = 0>
ecs_xtor_t dtor() {
ecs_xtor_t dtor(ecs_type_hooks_flags_t&) {
return nullptr;
}

// Dtor
template <typename T, if_t<
std::is_destructible<T>::value &&
! std::is_trivially_destructible<T>::value > = 0>
ecs_xtor_t dtor() {
ecs_xtor_t dtor(ecs_type_hooks_flags_t&) {
return dtor_impl<T>;
}

// Assert when the type cannot be destructed
template <typename T, if_not_t< std::is_destructible<T>::value > = 0>
ecs_xtor_t dtor() {
ecs_xtor_t dtor(ecs_type_hooks_flags_t& flags) {
flecs_static_assert(always_false<T>::value,
"component type must be destructible");
return ECS_DTOR_ILLEGAL;
flags |= ECS_DTOR_ILLEGAL;
return nullptr;
}

// Trivially copyable
template <typename T, if_t< std::is_trivially_copyable<T>::value > = 0>
ecs_copy_t copy() {
ecs_copy_t copy(ecs_type_hooks_flags_t&) {
return nullptr;
}

// Not copyable
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;
ecs_copy_t copy(ecs_type_hooks_flags_t& flags) {
flags |= ECS_COPY_ILLEGAL;
return nullptr;
}

// Copy assignment
template <typename T, if_t<
std::is_copy_assignable<T>::value &&
! std::is_trivially_copyable<T>::value > = 0>
ecs_copy_t copy() {
ecs_copy_t copy(ecs_type_hooks_flags_t&) {
return copy_impl<T>;
}

// Trivially move assignable
template <typename T, if_t< std::is_trivially_move_assignable<T>::value > = 0>
ecs_move_t move() {
ecs_move_t move(ecs_type_hooks_flags_t&) {
return nullptr;
}

// Component types must be move assignable
template <typename T, if_not_t< std::is_move_assignable<T>::value > = 0>
ecs_move_t move() {
return ECS_MOVE_ILLEGAL;
ecs_move_t move(ecs_type_hooks_flags_t& flags) {
flags |= ECS_MOVE_ILLEGAL;
return nullptr;
}

// Move assignment
template <typename T, if_t<
std::is_move_assignable<T>::value &&
! std::is_trivially_move_assignable<T>::value > = 0>
ecs_move_t move() {
ecs_move_t move(ecs_type_hooks_flags_t&) {
return move_impl<T>;
}

// Trivially copy constructible
template <typename T, if_t<
std::is_trivially_copy_constructible<T>::value > = 0>
ecs_copy_t copy_ctor() {
ecs_copy_t copy_ctor(ecs_type_hooks_flags_t&) {
return nullptr;
}

// No copy ctor
template <typename T, if_t< ! std::is_copy_constructible<T>::value > = 0>
ecs_copy_t copy_ctor() {
return ECS_COPY_CTOR_ILLEGAL;
ecs_copy_t copy_ctor(ecs_type_hooks_flags_t& flags) {
flags |= ECS_COPY_CTOR_ILLEGAL;
return nullptr;

}

// Copy ctor
template <typename T, if_t<
std::is_copy_constructible<T>::value &&
! std::is_trivially_copy_constructible<T>::value > = 0>
ecs_copy_t copy_ctor() {
ecs_copy_t copy_ctor(ecs_type_hooks_flags_t&) {
return copy_ctor_impl<T>;
}

// Trivially move constructible
template <typename T, if_t<
std::is_trivially_move_constructible<T>::value > = 0>
ecs_move_t move_ctor() {
ecs_move_t move_ctor(ecs_type_hooks_flags_t&) {
return nullptr;
}

// Component types must be move constructible
template <typename T, if_not_t< std::is_move_constructible<T>::value > = 0>
ecs_move_t move_ctor() {
return ECS_MOVE_CTOR_ILLEGAL;
ecs_move_t move_ctor(ecs_type_hooks_flags_t& flags) {
flags |= ECS_MOVE_CTOR_ILLEGAL;
return nullptr;
}

// Move ctor
template <typename T, if_t<
std::is_move_constructible<T>::value &&
! std::is_trivially_move_constructible<T>::value > = 0>
ecs_move_t move_ctor() {
ecs_move_t move_ctor(ecs_type_hooks_flags_t&) {
return move_ctor_impl<T>;
}

// Trivial merge (move assign + dtor)
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() {
ecs_move_t ctor_move_dtor(ecs_type_hooks_flags_t&) {
return nullptr;
}

// Component types must be move constructible and destructible
template <typename T, if_t<
! std::is_move_constructible<T>::value ||
! std::is_destructible<T>::value > = 0>
ecs_move_t ctor_move_dtor() {
return ECS_MOVE_CTOR_ILLEGAL;
ecs_move_t ctor_move_dtor(ecs_type_hooks_flags_t& flags) {
flags |= ECS_CTOR_MOVE_DTOR_ILLEGAL;
return nullptr;
}

// Merge ctor + dtor
Expand All @@ -20448,24 +20434,25 @@ template <typename T, if_t<
std::is_trivially_destructible<T>::value) &&
std::is_move_constructible<T>::value &&
std::is_destructible<T>::value > = 0>
ecs_move_t ctor_move_dtor() {
ecs_move_t ctor_move_dtor(ecs_type_hooks_flags_t&) {
return ctor_move_dtor_impl<T>;
}

// Trivial merge (move assign + dtor)
template <typename T, if_t<
std::is_trivially_move_assignable<T>::value &&
std::is_trivially_destructible<T>::value > = 0>
ecs_move_t move_dtor() {
ecs_move_t move_dtor(ecs_type_hooks_flags_t&) {
return nullptr;
}

// Component types must be move constructible and destructible
template <typename T, if_t<
! std::is_move_assignable<T>::value ||
! std::is_destructible<T>::value > = 0>
ecs_move_t move_dtor() {
return ECS_MOVE_CTOR_ILLEGAL;
ecs_move_t move_dtor(ecs_type_hooks_flags_t& flags) {
flags |= ECS_MOVE_DTOR_ILLEGAL;
return nullptr;
}

// Merge assign + dtor
Expand All @@ -20474,7 +20461,7 @@ template <typename T, if_t<
std::is_trivially_destructible<T>::value) &&
std::is_move_assignable<T>::value &&
std::is_destructible<T>::value > = 0>
ecs_move_t move_dtor() {
ecs_move_t move_dtor(ecs_type_hooks_flags_t&) {
return move_dtor_impl<T>;
}

Expand Down Expand Up @@ -26824,20 +26811,20 @@ void register_lifecycle_actions(
ecs_entity_t component)
{
ecs_type_hooks_t cl{};
cl.ctor = ctor<T>();
cl.dtor = dtor<T>();
cl.ctor = ctor<T>(cl.flags);
cl.dtor = dtor<T>(cl.flags);

cl.copy = copy<T>();
cl.copy_ctor = copy_ctor<T>();
cl.move = move<T>();
cl.move_ctor = move_ctor<T>();
cl.copy = copy<T>(cl.flags);
cl.copy_ctor = copy_ctor<T>(cl.flags);
cl.move = move<T>(cl.flags);
cl.move_ctor = move_ctor<T>(cl.flags);

cl.ctor_move_dtor = ctor_move_dtor<T>();
cl.move_dtor = move_dtor<T>();
cl.ctor_move_dtor = ctor_move_dtor<T>(cl.flags);
cl.move_dtor = move_dtor<T>(cl.flags);

ecs_set_hooks_id( world, component, &cl);
ecs_set_hooks_id(world, component, &cl);

if (cl.move == ECS_MOVE_ILLEGAL || cl.move_ctor == ECS_MOVE_CTOR_ILLEGAL) {
if (cl.flags & ECS_MOVE_ILLEGAL || cl.flags & ECS_MOVE_CTOR_ILLEGAL) {
ecs_add_id(world, component, flecs::Sparse);
}
}
Expand Down
Loading

0 comments on commit 4339065

Please sign in to comment.