@@ -28,6 +28,7 @@ pub struct SceneSpawner {
28
28
scene_asset_event_reader : EventReader < AssetEvent < Scene > > ,
29
29
scenes_to_spawn : Vec < Handle < Scene > > ,
30
30
scenes_to_load : Vec < Handle < Scene > > ,
31
+ scenes_to_unload : Vec < Handle < Scene > > ,
31
32
}
32
33
33
34
#[ derive( Error , Debug ) ]
@@ -47,6 +48,10 @@ impl SceneSpawner {
47
48
self . scenes_to_load . push ( scene_handle) ;
48
49
}
49
50
51
+ pub fn unload ( & mut self , scene_handle : Handle < Scene > ) {
52
+ self . scenes_to_unload . push ( scene_handle) ;
53
+ }
54
+
50
55
pub fn load_sync (
51
56
& mut self ,
52
57
world : & mut World ,
@@ -58,6 +63,26 @@ impl SceneSpawner {
58
63
Ok ( ( ) )
59
64
}
60
65
66
+ pub fn unload_sync (
67
+ & mut self ,
68
+ world : & mut World ,
69
+ scene_handle : Handle < Scene > ,
70
+ ) -> Result < ( ) , SceneSpawnError > {
71
+ if let Some ( instance_ids) = self . spawned_scenes . get ( & scene_handle) {
72
+ for instance_id in instance_ids {
73
+ if let Some ( instance) = self . spawned_instances . get ( & instance_id) {
74
+ for entity in instance. entity_map . values ( ) {
75
+ let _ = world. despawn ( * entity) ; // Ignore the result, unload only cares if it exists.
76
+ }
77
+ }
78
+ }
79
+
80
+ self . loaded_scenes . remove ( & scene_handle) ;
81
+ self . spawned_scenes . remove ( & scene_handle) ;
82
+ }
83
+ Ok ( ( ) )
84
+ }
85
+
61
86
pub fn spawn_sync (
62
87
& mut self ,
63
88
world : & mut World ,
@@ -152,19 +177,27 @@ impl SceneSpawner {
152
177
world : & mut World ,
153
178
resources : & Resources ,
154
179
) -> Result < ( ) , SceneSpawnError > {
155
- let scenes_to_load = self . scenes_to_load . drain ( .. ) . collect :: < Vec < _ > > ( ) ;
156
- let mut non_existent_scenes = Vec :: new ( ) ;
180
+ let scenes_to_load = std :: mem :: take ( & mut self . scenes_to_load ) ;
181
+
157
182
for scene_handle in scenes_to_load {
158
183
match self . load_sync ( world, resources, scene_handle) {
159
184
Ok ( _) => { }
160
185
Err ( SceneSpawnError :: NonExistentScene { .. } ) => {
161
- non_existent_scenes . push ( scene_handle)
186
+ self . scenes_to_load . push ( scene_handle)
162
187
}
163
188
Err ( err) => return Err ( err) ,
164
189
}
165
190
}
166
191
167
- self . scenes_to_load = non_existent_scenes;
192
+ Ok ( ( ) )
193
+ }
194
+
195
+ pub fn unload_queued_scenes ( & mut self , world : & mut World ) -> Result < ( ) , SceneSpawnError > {
196
+ let scenes_to_unload = std:: mem:: take ( & mut self . scenes_to_unload ) ;
197
+
198
+ for scene_handle in scenes_to_unload {
199
+ self . unload_sync ( world, scene_handle) ?;
200
+ }
168
201
Ok ( ( ) )
169
202
}
170
203
@@ -173,19 +206,18 @@ impl SceneSpawner {
173
206
world : & mut World ,
174
207
resources : & Resources ,
175
208
) -> Result < ( ) , SceneSpawnError > {
176
- let scenes_to_spawn = self . scenes_to_spawn . drain ( .. ) . collect :: < Vec < _ > > ( ) ;
177
- let mut non_existent_scenes = Vec :: new ( ) ;
209
+ let scenes_to_spawn = std :: mem :: take ( & mut self . scenes_to_spawn ) ;
210
+
178
211
for scene_handle in scenes_to_spawn {
179
212
match self . spawn_sync ( world, resources, scene_handle) {
180
213
Ok ( _) => { }
181
214
Err ( SceneSpawnError :: NonExistentScene { .. } ) => {
182
- non_existent_scenes . push ( scene_handle)
215
+ self . scenes_to_spawn . push ( scene_handle)
183
216
}
184
217
Err ( err) => return Err ( err) ,
185
218
}
186
219
}
187
220
188
- self . scenes_to_spawn = non_existent_scenes;
189
221
Ok ( ( ) )
190
222
}
191
223
}
@@ -209,6 +241,7 @@ pub fn scene_spawner_system(world: &mut World, resources: &mut Resources) {
209
241
}
210
242
}
211
243
244
+ scene_spawner. unload_queued_scenes ( world) . unwrap ( ) ;
212
245
scene_spawner. load_queued_scenes ( world, resources) . unwrap ( ) ;
213
246
scene_spawner. spawn_queued_scenes ( world, resources) . unwrap ( ) ;
214
247
scene_spawner
0 commit comments