-
-
Notifications
You must be signed in to change notification settings - Fork 463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[core] operator== hook #1455
base: master
Are you sure you want to change the base?
[core] operator== hook #1455
Conversation
fa1a619
to
2c416ea
Compare
b4af2c5
to
9fb4d95
Compare
@@ -397,14 +442,14 @@ struct component : untyped_component { | |||
template <typename Func> | |||
component<T>& on_add(Func&& func) { | |||
using Delegate = typename _::each_delegate<typename std::decay<Func>::type, T>; | |||
flecs::type_hooks_t h = get_hooks(); | |||
flecs::type_hooks_t h = this->get_hooks(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: remove this->
so it's consistent with set_hooks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -429,14 +474,48 @@ struct component : untyped_component { | |||
component<T>& on_set(Func&& func) { | |||
using Delegate = typename _::each_delegate< | |||
typename std::decay<Func>::type, T>; | |||
flecs::type_hooks_t h = get_hooks(); | |||
flecs::type_hooks_t h = this->get_hooks(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: see above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
|
||
/** Register operator compare hook. */ | ||
using untyped_component::op_compare; | ||
component<T>& op_compare() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I made up my mind about using on_X
naming. It makes more sense to me, since it's still a hook that will be invoked when the core needs to do a comparison, so it is "on compare", "on equals".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
src/addons/meta/rtt_lifecycle.c
Outdated
dtor_hook_required, | ||
move_hook_required, | ||
copy_hook_required); | ||
ctor_hook_required ? flecs_rtt_struct_ctor : NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we keep the existing design where we just pass in booleans to flecs_rtt_init_default_hooks_struct
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
This change made sense in some internal refactor. Not anymore.
|
||
ecs_type_hooks_t hooks = *ecs_get_hooks_id(world, component); | ||
|
||
hooks.ctor = ctor_hook_required && !(flags & ECS_TYPE_HOOK_CTOR_ILLEGAL) ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this code added? It doesn't seem related to equals/compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is due to the new flags checks in ecs_set_hooks_id()
. It now requires that hooks are set to NULL
if they are to be illegal: The PR enables the commented-out asserts in there:
/* TODO: enable asserts once RTT API is updated */
... and also unquarantines several tests in ComponentLifecycle.c
.
|
||
if (hooks.lifecycle_ctx_free) { | ||
hooks.lifecycle_ctx_free(hooks.lifecycle_ctx); | ||
hooks.lifecycle_ctx_free = NULL; | ||
hooks.lifecycle_ctx_free = flecs_rtt_free_lifecycle_nop; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need a nop
? Can we keep the existing approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing approach didn't actually work as intended. Specifically, ecs_set_hooks_id
does not allow you to unset lifecycle_ctx_free
once it's been set.
This issue went unnoticed in other cases (e.g., for ctor
, dtor
, etc.) because if any field in a struct required a runtime-generated hook, the struct would always continue requiring hooks as new fields were added. In those cases, the lifecycle context wouldn't need to be removed.
However, handling cmp
and equals
hooks is different. Initially, a struct might be comparable because its first field is comparable, and so an autogenerated compare hook is added. But if a later field is not comparable, the entire struct becomes uncomparable, even if further comparable fields are added later. This means the lifecycle context must be removed, unless the struct coincidentally still requires other hooks (e.g., ctor
or dtor
).
Since ecs_set_hooks_id
doesn't support unsetting lifecycle_ctx_free
, I opted to replace it with a no-op function.
I could change ecs_set_hooks_id
to do what I want and avoid the nop, but that would break a pattern in there, so it is better to have this conversation and decide.
So that's why 😉
} | ||
|
||
if (ctor_hook_required || dtor_hook_required || move_hook_required || | ||
copy_hook_required) { | ||
if (hooks.ctor || hooks.dtor || hooks.move || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did the existing approach change here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, due to the refactor required to comply with ecs_set_hooks_id()
strict flags check.
@@ -1464,9 +1539,10 @@ void ecs_set_hooks_id( | |||
} | |||
|
|||
if(ti->hooks.flags & ECS_TYPE_HOOK_MOVE_DTOR_ILLEGAL) { | |||
ti->hooks.ctor_move_dtor = flecs_move_ctor_illegal; | |||
ti->hooks.move_dtor = flecs_move_ctor_illegal; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unrelated to this PR, I just spotted this bug and fixed it along the way before I forgot: The wrong hook was being set to the flecs_move_ctor_illegal
illegal handler.
int16_t value; | ||
}; | ||
|
||
int compare(flecs::world& ecs, flecs::entity_t id, const void *a, const void *b) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make these functions static
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
Allow in cpp to generate equals hook from compare hook
Note, requires #1454 to be merged first.
Building on the previous PR, this one adds a hook for
operator==
. It will detect this operator in a component definition and bind a hook to it that can be used to test components for equality.If this operator is not defined but the compare operator is, Flecs will automatically derive this operator.