bevy_atomic_save/
save.rs

1use super::*;
2
3/// A [`Component`] which indicates that its [`Entity`] should be saved.
4///
5/// Any entity with a [`Save`] component is despawned during [`SaveStage::Load`].
6#[derive(Component, Default, Clone)]
7pub struct Save;
8
9/// A [`RunCriteria`] which returns [`ShouldRun::Yes`] if there is a save [`Request`] present; [`ShouldRun::No`] otherwise.
10pub fn should_save(request: Option<Res<Request>>) -> ShouldRun {
11    match request.map(|request| request.should_save()) {
12        Some(true) => ShouldRun::Yes,
13        _ => ShouldRun::No,
14    }
15}
16
17/// A [`System`] which handles a save [`Request`].
18pub fn save(world: &mut World) {
19    if let Some(Request::Save { path, mode }) = world.remove_resource::<Request>() {
20        let entities: Vec<Entity> = match mode {
21            SaveMode::Filtered => world
22                .query_filtered::<Entity, With<Save>>()
23                .iter(world)
24                .collect(),
25            SaveMode::Dump => world.iter_entities().collect(),
26        };
27
28        let scene = save_world(world, entities);
29        match scene.serialize_ron(world.resource::<AppTypeRegistry>()) {
30            Ok(serialized_scene) => match File::create(&path) {
31                Ok(mut file) => match file.write_all(serialized_scene.as_bytes()) {
32                    Ok(()) => info!("save successful: {path:?}"),
33                    Err(why) => error!("save failed: {why:?}"),
34                },
35                Err(why) => {
36                    error!("file creation failed: {why:?}");
37                }
38            },
39            Err(why) => {
40                error!("serialization failed: {why:?}");
41            }
42        }
43    }
44}
45
46/// Saves the `entities` within the given [`World`] and returns it as a serializable [`DynamicScene`].
47pub fn save_world(world: &World, entities: impl IntoIterator<Item = Entity>) -> DynamicScene {
48    let mut scene_builder = DynamicSceneBuilder::from_world(world);
49    scene_builder.extract_entities(entities.into_iter());
50    scene_builder.build()
51}