@@ -2,7 +2,8 @@ use core::hint::black_box;
2
2
3
3
use benches:: bench;
4
4
use bevy_ecs:: bundle:: Bundle ;
5
- use bevy_ecs:: component:: ComponentCloneHandler ;
5
+ use bevy_ecs:: component:: ComponentCloneBehavior ;
6
+ use bevy_ecs:: entity:: EntityCloner ;
6
7
use bevy_ecs:: hierarchy:: ChildOf ;
7
8
use bevy_ecs:: reflect:: AppTypeRegistry ;
8
9
use bevy_ecs:: { component:: Component , world:: World } ;
@@ -52,7 +53,10 @@ type ComplexBundle = (C1, C2, C3, C4, C5, C6, C7, C8, C9, C10);
52
53
53
54
/// Sets the [`ComponentCloneHandler`] for all explicit and required components in a bundle `B` to
54
55
/// 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 {
56
60
// Get mutable access to the type registry, creating it if it does not exist yet.
57
61
let registry = world. get_resource_or_init :: < AppTypeRegistry > ( ) ;
58
62
@@ -67,12 +71,15 @@ fn set_reflect_clone_handler<B: Bundle + GetTypeRegistration>(world: &mut World)
67
71
// this bundle are saved.
68
72
let component_ids: Vec < _ > = world. register_bundle :: < B > ( ) . contributed_components ( ) . into ( ) ;
69
73
70
- let clone_handlers = world . get_component_clone_handlers_mut ( ) ;
74
+ let mut builder = EntityCloner :: build ( world ) ;
71
75
72
76
// Overwrite the clone handler for all components in the bundle to use `Reflect`, not `Clone`.
73
77
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 ( ) ) ;
75
79
}
80
+ builder. recursive ( recursive) ;
81
+
82
+ builder. finish ( )
76
83
}
77
84
78
85
/// 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>(
91
98
) {
92
99
let mut world = World :: default ( ) ;
93
100
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
+ } ;
97
106
98
107
// Spawn the first entity, which will be cloned in the benchmark routine.
99
108
let id = world. spawn ( B :: default ( ) ) . id ( ) ;
100
109
101
110
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) ) ;
106
113
world. flush ( ) ;
107
114
} ) ;
108
115
}
@@ -125,9 +132,15 @@ fn bench_clone_hierarchy<B: Bundle + Default + GetTypeRegistration>(
125
132
) {
126
133
let mut world = World :: default ( ) ;
127
134
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.
131
144
132
145
// Spawn the first entity, which will be cloned in the benchmark routine.
133
146
let id = world. spawn ( B :: default ( ) ) . id ( ) ;
@@ -148,18 +161,8 @@ fn bench_clone_hierarchy<B: Bundle + Default + GetTypeRegistration>(
148
161
}
149
162
}
150
163
151
- // Flush all `set_parent()` commands.
152
- world. flush ( ) ;
153
-
154
164
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) ) ;
163
166
world. flush ( ) ;
164
167
} ) ;
165
168
}
0 commit comments