@@ -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,27 @@ 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 scenes_to_load = std :: mem :: take ( & mut self . scenes_to_load ) ;
183
+
157
184
for scene_handle in scenes_to_load {
158
185
match self . load_sync ( world, resources, scene_handle) {
159
186
Ok ( _) => { }
160
187
Err ( SceneSpawnError :: NonExistentScene { .. } ) => {
161
- non_existent_scenes . push ( scene_handle)
188
+ self . scenes_to_spawn . push ( scene_handle)
162
189
}
163
190
Err ( err) => return Err ( err) ,
164
191
}
165
192
}
166
193
167
- self . scenes_to_load = non_existent_scenes;
194
+ Ok ( ( ) )
195
+ }
196
+
197
+ pub fn unload_queued_scenes ( & mut self , world : & mut World ) -> Result < ( ) , SceneSpawnError > {
198
+ let scenes_to_unload = std:: mem:: take ( & mut self . scenes_to_unload ) ;
199
+
200
+ for scene_handle in scenes_to_unload {
201
+ self . unload_sync ( world, scene_handle) ?;
202
+ }
168
203
Ok ( ( ) )
169
204
}
170
205
@@ -173,19 +208,18 @@ impl SceneSpawner {
173
208
world : & mut World ,
174
209
resources : & Resources ,
175
210
) -> Result < ( ) , SceneSpawnError > {
176
- let scenes_to_spawn = self . scenes_to_spawn . drain ( .. ) . collect :: < Vec < _ > > ( ) ;
177
- let mut non_existent_scenes = Vec :: new ( ) ;
211
+ let scenes_to_spawn = std :: mem :: take ( & mut self . scenes_to_spawn ) ;
212
+
178
213
for scene_handle in scenes_to_spawn {
179
214
match self . spawn_sync ( world, resources, scene_handle) {
180
215
Ok ( _) => { }
181
216
Err ( SceneSpawnError :: NonExistentScene { .. } ) => {
182
- non_existent_scenes . push ( scene_handle)
217
+ self . scenes_to_spawn . push ( scene_handle)
183
218
}
184
219
Err ( err) => return Err ( err) ,
185
220
}
186
221
}
187
222
188
- self . scenes_to_spawn = non_existent_scenes;
189
223
Ok ( ( ) )
190
224
}
191
225
}
@@ -209,6 +243,7 @@ pub fn scene_spawner_system(world: &mut World, resources: &mut Resources) {
209
243
}
210
244
}
211
245
246
+ scene_spawner. unload_queued_scenes ( world) . unwrap ( ) ;
212
247
scene_spawner. load_queued_scenes ( world, resources) . unwrap ( ) ;
213
248
scene_spawner. spawn_queued_scenes ( world, resources) . unwrap ( ) ;
214
249
scene_spawner
0 commit comments