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}