Skip to main content

gled_model/asset/scene/
mod.rs

1pub mod color;
2pub mod effect;
3
4pub mod grid;
5pub mod instance;
6
7use super::AssetTrait;
8use crate::patching::layout::LayoutSelection;
9use crate::sound::trigger_ref::{CollectSoundTriggers, SoundTriggerSet};
10use effect::Effect;
11use serde::{Deserialize, Serialize};
12use std::collections::BTreeSet;
13
14#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq)]
15pub struct Scene {
16    pub effects: Vec<Effect>,
17}
18
19impl Scene {
20    /// Selections the scene's effects override their tile with.
21    pub fn selections(&self) -> BTreeSet<LayoutSelection> {
22        self.effects
23            .iter()
24            .filter_map(|effect| effect.selection)
25            .collect()
26    }
27
28    pub fn effect(&mut self, index: usize) -> Option<&mut Effect> {
29        self.effects.get_mut(index)
30    }
31
32    pub fn effects(&self) -> &[Effect] {
33        &self.effects
34    }
35
36    /// Add an effect. Its GPU pipeline is built lazily by `ensure_pipelines`
37    /// on whichever thread renders this scene.
38    pub fn add_effect(&mut self, effect: Effect) -> usize {
39        self.effects.push(effect);
40
41        self.effects.len() - 1
42    }
43
44    pub fn remove_effect(&mut self, index: usize) -> Option<Effect> {
45        let mut effect = None;
46
47        if self.effects.len() > index {
48            effect = Some(self.effects.remove(index));
49        }
50
51        effect
52    }
53}
54
55impl AssetTrait for Scene {
56    const DIR_NAME: &'static str = "scenes";
57    const NAME: &'static str = "Scene";
58    const SHOW_NAME_IF_SELECTED: bool = true;
59}
60
61impl CollectSoundTriggers for Scene {
62    fn collect_sound_triggers(&self, triggers: &mut SoundTriggerSet) {
63        for effect in &self.effects {
64            effect.collect_sound_triggers(triggers);
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::patching::layout::LayoutRef;
73
74    fn effect(selection: Option<LayoutSelection>) -> Effect {
75        Effect {
76            selection,
77            ..Effect::default()
78        }
79    }
80
81    #[test]
82    fn effect_selections_are_the_overrides_only() {
83        let topology = LayoutSelection::default();
84        let layout = LayoutSelection::new(LayoutRef::Layout(0), 1);
85        let scene = Scene {
86            effects: vec![
87                effect(None),
88                effect(Some(layout)),
89                effect(Some(topology)),
90                effect(Some(layout)),
91            ],
92        };
93
94        assert_eq!(scene.selections(), BTreeSet::from([topology, layout]));
95    }
96}