@@ -2,7 +2,8 @@ use core::hint::black_box;
22
33use benches:: bench;
44use bevy_ecs:: bundle:: Bundle ;
5- use bevy_ecs:: component:: ComponentCloneHandler ;
5+ use bevy_ecs:: component:: ComponentCloneBehavior ;
6+ use bevy_ecs:: entity:: EntityCloner ;
67use bevy_ecs:: hierarchy:: ChildOf ;
78use bevy_ecs:: reflect:: AppTypeRegistry ;
89use bevy_ecs:: { component:: Component , world:: World } ;
@@ -52,7 +53,10 @@ type ComplexBundle = (C1, C2, C3, C4, C5, C6, C7, C8, C9, C10);
5253
5354/// Sets the [`ComponentCloneHandler`] for all explicit and required components in a bundle `B` to
5455/// use the [`Reflect`] trait instead of [`Clone`].
55- fn set_reflect_clone_handler < B : Bundle + GetTypeRegistration > ( world : & mut World ) {
56+ fn reflection_cloner < B : Bundle + GetTypeRegistration > (
57+ world : & mut World ,
58+ recursive : bool ,
59+ ) -> EntityCloner {
5660 // Get mutable access to the type registry, creating it if it does not exist yet.
5761 let registry = world. get_resource_or_init :: < AppTypeRegistry > ( ) ;
5862
@@ -67,12 +71,15 @@ fn set_reflect_clone_handler<B: Bundle + GetTypeRegistration>(world: &mut World)
6771 // this bundle are saved.
6872 let component_ids: Vec < _ > = world. register_bundle :: < B > ( ) . contributed_components ( ) . into ( ) ;
6973
70- let clone_handlers = world . get_component_clone_handlers_mut ( ) ;
74+ let mut builder = EntityCloner :: build ( world ) ;
7175
7276 // Overwrite the clone handler for all components in the bundle to use `Reflect`, not `Clone`.
7377 for component in component_ids {
74- clone_handlers . set_component_handler ( component, ComponentCloneHandler :: reflect_handler ( ) ) ;
78+ builder . override_clone_behavior_with_id ( component, ComponentCloneBehavior :: reflect ( ) ) ;
7579 }
80+ builder. recursive ( recursive) ;
81+
82+ builder. finish ( )
7683}
7784
7885/// A helper function that benchmarks running the [`EntityCommands::clone_and_spawn()`] command on a
@@ -91,18 +98,18 @@ fn bench_clone<B: Bundle + Default + GetTypeRegistration>(
9198) {
9299 let mut world = World :: default ( ) ;
93100
94- if clone_via_reflect {
95- set_reflect_clone_handler :: < B > ( & mut world) ;
96- }
101+ let mut cloner = if clone_via_reflect {
102+ reflection_cloner :: < B > ( & mut world, false )
103+ } else {
104+ EntityCloner :: default ( )
105+ } ;
97106
98107 // Spawn the first entity, which will be cloned in the benchmark routine.
99108 let id = world. spawn ( B :: default ( ) ) . id ( ) ;
100109
101110 b. iter ( || {
102- // Queue the command to clone the entity.
103- world. commands ( ) . entity ( black_box ( id) ) . clone_and_spawn ( ) ;
104-
105- // Run the command.
111+ // clones the given entity
112+ cloner. spawn_clone ( & mut world, black_box ( id) ) ;
106113 world. flush ( ) ;
107114 } ) ;
108115}
@@ -125,9 +132,15 @@ fn bench_clone_hierarchy<B: Bundle + Default + GetTypeRegistration>(
125132) {
126133 let mut world = World :: default ( ) ;
127134
128- if clone_via_reflect {
129- set_reflect_clone_handler :: < B > ( & mut world) ;
130- }
135+ let mut cloner = if clone_via_reflect {
136+ reflection_cloner :: < B > ( & mut world, true )
137+ } else {
138+ let mut builder = EntityCloner :: build ( & mut world) ;
139+ builder. recursive ( true ) ;
140+ builder. finish ( )
141+ } ;
142+
143+ // Make the clone command recursive, so children are cloned as well.
131144
132145 // Spawn the first entity, which will be cloned in the benchmark routine.
133146 let id = world. spawn ( B :: default ( ) ) . id ( ) ;
@@ -148,18 +161,8 @@ fn bench_clone_hierarchy<B: Bundle + Default + GetTypeRegistration>(
148161 }
149162 }
150163
151- // Flush all `set_parent()` commands.
152- world. flush ( ) ;
153-
154164 b. iter ( || {
155- world
156- . commands ( )
157- . entity ( black_box ( id) )
158- . clone_and_spawn_with ( |builder| {
159- // Make the clone command recursive, so children are cloned as well.
160- builder. recursive ( true ) ;
161- } ) ;
162-
165+ cloner. spawn_clone ( & mut world, black_box ( id) ) ;
163166 world. flush ( ) ;
164167 } ) ;
165168}
0 commit comments