Skip to main content

euv_engine/scene/
impl.rs

1use crate::*;
2
3/// Implements static scene creation for `SceneManager`.
4impl SceneManager {
5    /// Creates a new `SceneRc` wrapping the given scene in a reference-counted cell.
6    ///
7    /// # Arguments
8    ///
9    /// - `T` - The concrete scene type implementing `Scene`.
10    ///
11    /// # Returns
12    ///
13    /// - `SceneRc` - The wrapped scene.
14    pub fn create_scene<T>(scene: T) -> SceneRc
15    where
16        T: Scene + 'static,
17    {
18        Rc::new(RefCell::new(scene))
19    }
20}
21
22/// Implements scene registration and lifecycle management for `SceneManager`.
23impl SceneManager {
24    /// Registers a scene under the given name.
25    ///
26    /// # Arguments
27    ///
28    /// - `String` - The name to register the scene under.
29    /// - `SceneRc` - The scene to register.
30    pub fn register(&mut self, name: String, scene: SceneRc) {
31        self.get_mut_scenes().insert(name, scene);
32    }
33
34    /// Unregisters and removes the scene with the given name.
35    ///
36    /// # Arguments
37    ///
38    /// - `&str` - The name of the scene to remove.
39    pub fn unregister(&mut self, name: &str) {
40        self.get_mut_scenes().remove(name);
41    }
42
43    /// Transitions to the scene with the given name.
44    ///
45    /// Calls `on_exit` on the current scene and `on_enter` on the new scene.
46    /// Returns `false` if no scene with the given name is registered.
47    ///
48    /// # Arguments
49    ///
50    /// - `&str` - The name of the scene to switch to.
51    ///
52    /// # Returns
53    ///
54    /// - `bool` - True if the transition was successful.
55    pub fn switch_to(&mut self, name: &str) -> bool {
56        if !self.get_scenes().contains_key(name) {
57            return false;
58        }
59        let current_name: Option<String> = self.get_mut_current_scene_name().clone();
60        if let Some(name) = current_name.as_ref()
61            && let Some(current_scene) = self.get_scenes().get(name)
62        {
63            current_scene.borrow_mut().on_exit();
64        }
65        self.set_current_scene_name(Some(name.to_string()));
66        if let Some(new_scene) = self.get_scenes().get(name) {
67            new_scene.borrow_mut().on_enter();
68        }
69        true
70    }
71
72    /// Requests a deferred scene transition to be applied on the next update.
73    ///
74    /// # Arguments
75    ///
76    /// - `String` - The name of the scene to switch to.
77    pub fn request_transition(&mut self, name: String) {
78        self.set_pending_scene_name(Some(name));
79    }
80
81    /// Processes a pending scene transition if one was requested.
82    pub fn process_pending_transition(&mut self) {
83        let Some(name) = self.get_mut_pending_scene_name().take() else {
84            return;
85        };
86        self.switch_to(&name);
87    }
88
89    /// Calls `on_update` on the current scene.
90    ///
91    /// # Arguments
92    ///
93    /// - `f64` - The delta time in seconds.
94    pub fn update(&mut self, delta_time: f64) {
95        self.process_pending_transition();
96        let current_name: Option<String> = self.get_mut_current_scene_name().clone();
97        let Some(current_name) = current_name.as_ref() else {
98            return;
99        };
100        let Some(scene) = self.get_scenes().get(current_name) else {
101            return;
102        };
103        scene.borrow_mut().on_update(delta_time);
104    }
105
106    /// Calls `on_render` on the current scene.
107    ///
108    /// # Arguments
109    ///
110    /// - `&CanvasRenderingContext2d` - The canvas rendering context.
111    pub fn render(&self, context: &CanvasRenderingContext2d) {
112        let Some(current_name) = self.current_scene_name.as_ref() else {
113            return;
114        };
115        let Some(scene) = self.get_scenes().get(current_name) else {
116            return;
117        };
118        scene.borrow().on_render(context);
119    }
120
121    /// Returns whether a scene with the given name is registered.
122    ///
123    /// # Arguments
124    ///
125    /// - `&str` - The scene name to check.
126    ///
127    /// # Returns
128    ///
129    /// - `bool` - True if the scene is registered.
130    pub fn has_scene(&self, name: &str) -> bool {
131        self.get_scenes().contains_key(name)
132    }
133
134    /// Returns the name of the currently active scene.
135    ///
136    /// # Returns
137    ///
138    /// - `Option<&str>` - The current scene name, or `None`.
139    pub fn current_name(&self) -> Option<&str> {
140        self.current_scene_name.as_deref()
141    }
142}
143
144/// Implements `Default` for `SceneManager` as a new empty manager.
145impl Default for SceneManager {
146    fn default() -> SceneManager {
147        SceneManager::new()
148    }
149}