From a7381dda967c04ed157012a01f238efb31f30eb9 Mon Sep 17 00:00:00 2001 From: Joda Date: Fri, 5 Sep 2025 13:16:55 -0500 Subject: [PATCH] Guard against VisibilityClass duplicates Co-authored-by: Dimitrios Loukadakis --- crates/bevy_camera/src/visibility/mod.rs | 33 ++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/crates/bevy_camera/src/visibility/mod.rs b/crates/bevy_camera/src/visibility/mod.rs index 8ac0ea4fe565d..090191ebe19d0 100644 --- a/crates/bevy_camera/src/visibility/mod.rs +++ b/crates/bevy_camera/src/visibility/mod.rs @@ -679,8 +679,14 @@ pub fn add_visibility_class( ) where C: 'static, { - if let Some(mut visibility_class) = world.get_mut::(entity) { - visibility_class.push(TypeId::of::()); + let Some(mut visibility_class) = world.get_mut::(entity) else { + // potentially warn in this case? + return; + }; + + let type_id = TypeId::of::(); + if !visibility_class.contains(&type_id) { + visibility_class.push(type_id); } } @@ -988,4 +994,27 @@ mod test { assert_eq!(1, size_of::()); assert_eq!(1, size_of::>()); } + + #[derive(Component, Default, Clone, Reflect)] + #[require(VisibilityClass)] + #[reflect(Component, Default, Clone)] + #[component(on_add = add_visibility_class::)] + struct TestVisibilityClassHook; + + #[test] + fn test_add_visibility_class_hook() { + let mut world = World::new(); + let entity = world.spawn(TestVisibilityClassHook).id(); + let entity_clone = world.spawn_empty().id(); + world + .entity_mut(entity) + .clone_with_opt_out(entity_clone, |_| {}); + + let entity_visibility_class = world.entity(entity).get::().unwrap(); + assert_eq!(entity_visibility_class.len(), 1); + + let entity_clone_visibility_class = + world.entity(entity_clone).get::().unwrap(); + assert_eq!(entity_clone_visibility_class.len(), 1); + } }