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