@@ -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 . retain ( |handle| handle. id != scene_handle. id ) ;
81
+ self . spawned_scenes . retain ( |handle, _| handle. id != scene_handle. id ) ;
82
+ }
83
+ Ok ( ( ) )
84
+ }
85
+
61
86
pub fn spawn_sync (
62
87
& mut self ,
63
88
world : & mut World ,
@@ -152,19 +177,35 @@ 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 mut scenes_to_load = Vec :: new ( ) ;
181
+ std:: mem:: swap ( & mut self . scenes_to_load , & mut scenes_to_load) ;
182
+
157
183
for scene_handle in scenes_to_load {
158
184
match self . load_sync ( world, resources, scene_handle) {
159
185
Ok ( _) => { }
160
186
Err ( SceneSpawnError :: NonExistentScene { .. } ) => {
161
- non_existent_scenes . push ( scene_handle)
187
+ self . scenes_to_spawn . push ( scene_handle)
162
188
}
163
189
Err ( err) => return Err ( err) ,
164
190
}
165
191
}
166
192
167
- self . scenes_to_load = non_existent_scenes;
193
+ Ok ( ( ) )
194
+ }
195
+
196
+ pub fn unload_queued_scenes (
197
+ & mut self ,
198
+ world : & mut World ,
199
+ ) -> Result < ( ) , SceneSpawnError > {
200
+ let mut scenes_to_unload = Vec :: new ( ) ;
201
+ std:: mem:: swap ( & mut self . scenes_to_unload , & mut scenes_to_unload) ;
202
+
203
+ for scene_handle in scenes_to_unload {
204
+ match self . unload_sync ( world, scene_handle) {
205
+ Ok ( _) => { } ,
206
+ Err ( err) => return Err ( err) ,
207
+ }
208
+ }
168
209
Ok ( ( ) )
169
210
}
170
211
@@ -173,19 +214,19 @@ impl SceneSpawner {
173
214
world : & mut World ,
174
215
resources : & Resources ,
175
216
) -> Result < ( ) , SceneSpawnError > {
176
- let scenes_to_spawn = self . scenes_to_spawn . drain ( ..) . collect :: < Vec < _ > > ( ) ;
177
- let mut non_existent_scenes = Vec :: new ( ) ;
217
+ let mut scenes_to_spawn = Vec :: new ( ) ;
218
+ std:: mem:: swap ( & mut self . scenes_to_spawn , & mut scenes_to_spawn) ;
219
+
178
220
for scene_handle in scenes_to_spawn {
179
221
match self . spawn_sync ( world, resources, scene_handle) {
180
222
Ok ( _) => { }
181
223
Err ( SceneSpawnError :: NonExistentScene { .. } ) => {
182
- non_existent_scenes . push ( scene_handle)
224
+ self . scenes_to_spawn . push ( scene_handle)
183
225
}
184
226
Err ( err) => return Err ( err) ,
185
227
}
186
228
}
187
229
188
- self . scenes_to_spawn = non_existent_scenes;
189
230
Ok ( ( ) )
190
231
}
191
232
}
@@ -209,6 +250,7 @@ pub fn scene_spawner_system(world: &mut World, resources: &mut Resources) {
209
250
}
210
251
}
211
252
253
+ scene_spawner. unload_queued_scenes ( world) . unwrap ( ) ;
212
254
scene_spawner. load_queued_scenes ( world, resources) . unwrap ( ) ;
213
255
scene_spawner. spawn_queued_scenes ( world, resources) . unwrap ( ) ;
214
256
scene_spawner
0 commit comments