Skip to main content

concinnity_asset/
scene.rs

1// Scene marker schema.
2
3use crate::{AssetId, de_opt_asset_ref};
4
5/// A named group of world content.
6///
7/// [Prop](#prop)s belong to a Scene by naming convention: props whose `name`
8/// begins with `<scene_name>_` are associated with that Scene. Props not
9/// prefixed by any scene name are visible in every scene.
10///
11/// The first declared Scene is active at world start. Scene changes are driven
12/// by actions: a UI `scene:<name>` action ([HitRegion](#hitregion) /
13/// [KeyBinding](#keybinding)) or a [Behavior](#behavior) scene node jumps to
14/// the named scene, with the transition ("Cut" or "FadeBlack") declared on the
15/// jump.
16#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
17#[serde(default)]
18pub struct Scene {
19    /// Asset identity; injected via `inject_name`. Not part of `args`.
20    #[serde(skip)]
21    pub asset_id: AssetId,
22    /// A [CameraShot](#camerashot) or [Camera3D](#camera3d) to activate when
23    /// this scene becomes active. `None` keeps the current camera unchanged.
24    #[serde(deserialize_with = "de_opt_asset_ref")]
25    pub camera_shot: Option<AssetId>,
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31
32    #[test]
33    fn a_scene_with_no_shot_leaves_the_camera_where_it_is() {
34        let s = Scene::default();
35        assert!(s.camera_shot.is_none());
36        assert_eq!(s.asset_id, AssetId::default());
37        assert!(
38            serde_json::from_str::<Scene>("{}")
39                .unwrap()
40                .camera_shot
41                .is_none()
42        );
43    }
44
45    #[test]
46    fn a_named_shot_parses_and_round_trips_through_postcard() {
47        crate::test_support::install_resolvers();
48        let s: Scene = serde_json::from_str(r#"{"camera_shot":"establishing"}"#).unwrap();
49        assert_eq!(s.camera_shot, Some(AssetId(12)));
50
51        let bytes = postcard::to_allocvec(&s).unwrap();
52        let back: Scene = postcard::from_bytes(&bytes).unwrap();
53        assert_eq!(back.camera_shot, Some(AssetId(12)));
54        assert_eq!(back.asset_id, AssetId::default());
55    }
56}