bevy_scene/
scene_loader.rs

1use crate::ron;
2use bevy_ecs::{
3    reflect::AppTypeRegistry,
4    world::{FromWorld, World},
5};
6use bevy_reflect::TypeRegistryArc;
7use thiserror::Error;
8
9#[cfg(feature = "serialize")]
10use {
11    crate::{serde::SceneDeserializer, DynamicScene},
12    bevy_asset::{io::Reader, AssetLoader, LoadContext},
13    serde::de::DeserializeSeed,
14};
15
16/// Asset loader for a Bevy dynamic scene (`.scn` / `.scn.ron`).
17///
18/// The loader handles assets serialized with [`DynamicScene::serialize`].
19#[derive(Debug)]
20pub struct SceneLoader {
21    #[cfg_attr(
22        not(feature = "serialize"),
23        expect(dead_code, reason = "only used with `serialize` feature")
24    )]
25    type_registry: TypeRegistryArc,
26}
27
28impl FromWorld for SceneLoader {
29    fn from_world(world: &mut World) -> Self {
30        let type_registry = world.resource::<AppTypeRegistry>();
31        SceneLoader {
32            type_registry: type_registry.0.clone(),
33        }
34    }
35}
36
37/// Possible errors that can be produced by [`SceneLoader`]
38#[non_exhaustive]
39#[derive(Debug, Error)]
40pub enum SceneLoaderError {
41    /// An [IO Error](std::io::Error)
42    #[error("Error while trying to read the scene file: {0}")]
43    Io(#[from] std::io::Error),
44    /// A [RON Error](ron::error::SpannedError)
45    #[error("Could not parse RON: {0}")]
46    RonSpannedError(#[from] ron::error::SpannedError),
47}
48
49#[cfg(feature = "serialize")]
50impl AssetLoader for SceneLoader {
51    type Asset = DynamicScene;
52    type Settings = ();
53    type Error = SceneLoaderError;
54
55    async fn load(
56        &self,
57        reader: &mut dyn Reader,
58        _settings: &(),
59        _load_context: &mut LoadContext<'_>,
60    ) -> Result<Self::Asset, Self::Error> {
61        let mut bytes = Vec::new();
62        reader.read_to_end(&mut bytes).await?;
63        let mut deserializer = ron::de::Deserializer::from_bytes(&bytes)?;
64        let scene_deserializer = SceneDeserializer {
65            type_registry: &self.type_registry.read(),
66        };
67        Ok(scene_deserializer
68            .deserialize(&mut deserializer)
69            .map_err(|e| deserializer.span_error(e))?)
70    }
71
72    fn extensions(&self) -> &[&str] {
73        &["scn", "scn.ron"]
74    }
75}