Skip to content

Commit 234875d

Browse files
authored
Fix Component macro hook composition codegen (#24039)
# Objective #24000 introduced the ability to use both relationships and user-provided hooks with `#[derive(Component)]`, but the hook function that is generated when there's a conflict does not compile. ## Solution Remove an errant nested `quote!`, and change the inline function definition to a closure so that `Self` type references work. ## Testing Updated the test to check the rest of the hooks, and it passes with this fix.
1 parent 0a056c7 commit 234875d

2 files changed

Lines changed: 46 additions & 13 deletions

File tree

crates/bevy_ecs/macros/src/component.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -762,11 +762,8 @@ fn hook_register_function_call(
762762
[single] => single.clone(),
763763
multiple => {
764764
quote! {
765-
{
766-
fn hook(world: #bevy_ecs_path::world::DeferredWorld, context: #bevy_ecs_path::lifecycle::HookContext) {
767-
quote! {#(#multiple(world.reborrow(), context.clone());)*}
768-
}
769-
hook
765+
|mut world: #bevy_ecs_path::world::DeferredWorld, context: #bevy_ecs_path::lifecycle::HookContext| {
766+
#(#multiple(world.reborrow(), context.clone());)*
770767
}
771768
}
772769
}

crates/bevy_ecs/src/relationship/mod.rs

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,27 +1190,63 @@ mod tests {
11901190
}
11911191

11921192
#[test]
1193-
fn component_hooks_compatibility() {
1194-
static CALLED: AtomicBool = AtomicBool::new(false);
1193+
pub fn component_hooks_compatibility() {
1194+
static ADD_CALLED: AtomicBool = AtomicBool::new(false);
1195+
static INSERT_CALLED: AtomicBool = AtomicBool::new(false);
1196+
static DISCARD_CALLED: AtomicBool = AtomicBool::new(false);
1197+
static REMOVE_CALLED: AtomicBool = AtomicBool::new(false);
1198+
static DESPAWN_CALLED: AtomicBool = AtomicBool::new(false);
11951199

11961200
#[derive(Component)]
11971201
#[relationship(relationship_target = RelTarget)]
1198-
#[component(on_add = on_add)]
1202+
#[component(on_add, on_insert, on_discard, on_remove, on_despawn)]
11991203
struct Rel(Entity);
12001204

12011205
#[derive(Component)]
12021206
#[relationship_target(relationship = Rel)]
12031207
struct RelTarget(Entity);
12041208

1205-
fn on_add(world: DeferredWorld, context: HookContext) {
1206-
assert!(!world.entity(context.entity).contains::<RelTarget>());
1207-
CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1209+
impl Rel {
1210+
fn on_add(world: DeferredWorld, context: HookContext) {
1211+
let &Rel(target) = world.get(context.entity).unwrap();
1212+
assert!(!world.entity(target).contains::<RelTarget>());
1213+
ADD_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1214+
}
1215+
1216+
fn on_insert(world: DeferredWorld, context: HookContext) {
1217+
let &Rel(target) = world.get(context.entity).unwrap();
1218+
assert!(!world.entity(target).contains::<RelTarget>());
1219+
INSERT_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1220+
}
1221+
1222+
fn on_discard(world: DeferredWorld, context: HookContext) {
1223+
let &Rel(target) = world.get(context.entity).unwrap();
1224+
assert!(world.entity(target).contains::<RelTarget>());
1225+
DISCARD_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1226+
}
1227+
1228+
fn on_remove(world: DeferredWorld, context: HookContext) {
1229+
let &Rel(target) = world.get(context.entity).unwrap();
1230+
assert!(world.entity(target).contains::<RelTarget>());
1231+
REMOVE_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1232+
}
1233+
1234+
fn on_despawn(world: DeferredWorld, context: HookContext) {
1235+
let &Rel(target) = world.get(context.entity).unwrap();
1236+
assert!(world.entity(target).contains::<RelTarget>());
1237+
DESPAWN_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1238+
}
12081239
}
12091240

12101241
let mut world = World::new();
12111242
let target = world.spawn_empty().id();
1212-
world.spawn(Rel(target));
1243+
let source = world.spawn(Rel(target)).id();
12131244
assert!(world.entity(target).contains::<RelTarget>());
1214-
assert!(CALLED.load(core::sync::atomic::Ordering::Relaxed));
1245+
assert!(ADD_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1246+
assert!(INSERT_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1247+
world.despawn(source);
1248+
assert!(DISCARD_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1249+
assert!(REMOVE_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1250+
assert!(DESPAWN_CALLED.load(core::sync::atomic::Ordering::Relaxed));
12151251
}
12161252
}

0 commit comments

Comments
 (0)