1pub enum SceneSwitch<C> {
20 None,
21 Push(Box<dyn Scene<C>>),
22 Replace(Box<dyn Scene<C>>),
23 Pop,
24}
25
26pub trait Scene<C> {
30 fn update(
31 &mut self,
32 gameworld: &mut C,
33 ctx: &mut crate::Context,
34 quad_ctx: &mut miniquad::graphics::GraphicsContext,
35 ) -> SceneSwitch<C>;
36 fn draw(
37 &mut self,
38 gameworld: &mut C,
39 ctx: &mut crate::Context,
40 quad_ctx: &mut miniquad::graphics::GraphicsContext,
41 ) -> crate::GameResult<()>;
42 fn resize_event(
43 &mut self,
44 _gameworld: &mut C,
45 _ctx: &mut crate::Context,
46 _quad_ctx: &mut miniquad::graphics::GraphicsContext,
47 _width: f32,
48 _height: f32,
49 ) {
50 }
51 #[allow(clippy::too_many_arguments)]
52 fn mouse_motion_event(
53 &mut self,
54 _gameworld: &mut C,
55 _ctx: &mut crate::Context,
56 _quad_ctx: &mut miniquad::graphics::GraphicsContext,
57 _x: f32,
58 _y: f32,
59 _dx: f32,
60 _dy: f32,
61 ) {
62 }
63 fn mouse_wheel_event(
64 &mut self,
65 _gameworld: &mut C,
66 _ctx: &mut crate::Context,
67 _quad_ctx: &mut miniquad::graphics::GraphicsContext,
68 _x: f32,
69 _y: f32,
70 ) {
71 }
72 fn mouse_button_down_event(
73 &mut self,
74 _gameworld: &mut C,
75 _ctx: &mut crate::Context,
76 _quad_ctx: &mut miniquad::graphics::GraphicsContext,
77 _button: crate::event::MouseButton,
78 _x: f32,
79 _y: f32,
80 ) {
81 }
82 fn mouse_button_up_event(
83 &mut self,
84 _gameworld: &mut C,
85 _ctx: &mut crate::Context,
86 _quad_ctx: &mut miniquad::graphics::GraphicsContext,
87 _button: crate::event::MouseButton,
88 _x: f32,
89 _y: f32,
90 ) {
91 }
92 fn key_down_event(
93 &mut self,
94 _gameworld: &mut C,
95 _ctx: &mut crate::Context,
96 _quad_ctx: &mut miniquad::graphics::GraphicsContext,
97 _key: crate::event::KeyCode,
98 ) {
99 }
100 fn key_up_event(
101 &mut self,
102 _gameworld: &mut C,
103 _ctx: &mut crate::Context,
104 _quad_ctx: &mut miniquad::graphics::GraphicsContext,
105 _key: crate::event::KeyCode,
106 ) {
107 }
108
109 fn name(&self) -> &str;
111 fn draw_previous(&self) -> bool {
115 false
116 }
117}
118
119impl<C> SceneSwitch<C> {
120 pub fn replace<S>(scene: S) -> Self
125 where
126 S: Scene<C> + 'static,
127 {
128 SceneSwitch::Replace(Box::new(scene))
129 }
130
131 pub fn push<S>(scene: S) -> Self
133 where
134 S: Scene<C> + 'static,
135 {
136 SceneSwitch::Push(Box::new(scene))
137 }
138}
139
140pub struct SceneStack<C> {
142 pub world: C,
143 scenes: Vec<Box<dyn Scene<C>>>,
144}
145
146impl<C> SceneStack<C> {
147 pub fn new(_ctx: &mut crate::Context, global_state: C) -> Self {
148 Self {
149 world: global_state,
150 scenes: Vec::new(),
151 }
152 }
153
154 pub fn push(&mut self, scene: Box<dyn Scene<C>>) {
156 self.scenes.push(scene)
157 }
158
159 pub fn pop(&mut self) -> Box<dyn Scene<C>> {
162 self.scenes
163 .pop()
164 .expect("ERROR: Popped an empty scene stack.")
165 }
166
167 pub fn current(&self) -> &dyn Scene<C> {
169 &**self
170 .scenes
171 .last()
172 .expect("ERROR: Tried to get current scene of an empty scene stack.")
173 }
174
175 pub fn switch(&mut self, next_scene: SceneSwitch<C>) -> Option<Box<dyn Scene<C>>> {
178 match next_scene {
179 SceneSwitch::None => None,
180 SceneSwitch::Pop => {
181 let s = self.pop();
182 Some(s)
183 }
184 SceneSwitch::Push(s) => {
185 self.push(s);
186 None
187 }
188 SceneSwitch::Replace(s) => {
189 let old_scene = self.pop();
190 self.push(s);
191 Some(old_scene)
192 }
193 }
194 }
195
196 pub fn update(
200 &mut self,
201 ctx: &mut crate::Context,
202 quad_ctx: &mut miniquad::graphics::GraphicsContext,
203 ) {
204 let next_scene = {
205 let current_scene = &mut **self
206 .scenes
207 .last_mut()
208 .expect("Tried to update empty scene stack");
209 current_scene.update(&mut self.world, ctx, quad_ctx)
210 };
211 self.switch(next_scene);
212 }
213
214 fn draw_scenes(
219 scenes: &mut [Box<dyn Scene<C>>],
220 world: &mut C,
221 ctx: &mut crate::Context,
222 quad_ctx: &mut miniquad::graphics::GraphicsContext,
223 ) {
224 assert!(!scenes.is_empty());
225 if let Some((current, rest)) = scenes.split_last_mut() {
226 if current.draw_previous() {
227 SceneStack::draw_scenes(rest, world, ctx, quad_ctx);
228 }
229 current
230 .draw(world, ctx, quad_ctx)
231 .expect("I would hope drawing a scene never fails!");
232 }
233 }
234
235 pub fn draw(
237 &mut self,
238 ctx: &mut crate::Context,
239 quad_ctx: &mut miniquad::graphics::GraphicsContext,
240 ) {
241 SceneStack::draw_scenes(&mut self.scenes, &mut self.world, ctx, quad_ctx)
242 }
243}
244
245impl<C, E: std::error::Error> crate::event::EventHandler<E> for SceneStack<C> {
246 fn update(
247 &mut self,
248 ctx: &mut crate::Context,
249 quad_ctx: &mut miniquad::graphics::GraphicsContext,
250 ) -> Result<(), E> {
251 self.update(ctx, quad_ctx);
252 Ok(())
253 }
254
255 fn draw(
256 &mut self,
257 ctx: &mut crate::Context,
258 quad_ctx: &mut miniquad::graphics::GraphicsContext,
259 ) -> Result<(), E> {
260 self.draw(ctx, quad_ctx);
261 Ok(())
262 }
263
264 fn resize_event(
265 &mut self,
266 ctx: &mut crate::Context,
267 quad_ctx: &mut miniquad::graphics::GraphicsContext,
268 width: f32,
269 height: f32,
270 ) {
271 let current_scene = &mut **self
272 .scenes
273 .last_mut()
274 .expect("Tried to update empty scene stack");
275
276 current_scene.resize_event(&mut self.world, ctx, quad_ctx, width, height)
277 }
278
279 fn mouse_motion_event(
280 &mut self,
281 ctx: &mut crate::Context,
282 quad_ctx: &mut miniquad::graphics::GraphicsContext,
283 x: f32,
284 y: f32,
285 dx: f32,
286 dy: f32,
287 ) {
288 let current_scene = &mut **self
289 .scenes
290 .last_mut()
291 .expect("Tried to update empty scene stack");
292
293 current_scene.mouse_motion_event(&mut self.world, ctx, quad_ctx, x, y, dx, dy);
294 }
295
296 fn mouse_wheel_event(
297 &mut self,
298 ctx: &mut crate::Context,
299 quad_ctx: &mut miniquad::graphics::GraphicsContext,
300 x: f32,
301 y: f32,
302 ) {
303 let current_scene = &mut **self
304 .scenes
305 .last_mut()
306 .expect("Tried to update empty scene stack");
307
308 current_scene.mouse_wheel_event(&mut self.world, ctx, quad_ctx, x, y);
309 }
310
311 fn mouse_button_down_event(
312 &mut self,
313 ctx: &mut crate::Context,
314 quad_ctx: &mut miniquad::graphics::GraphicsContext,
315 button: crate::event::MouseButton,
316 x: f32,
317 y: f32,
318 ) {
319 let current_scene = &mut **self
320 .scenes
321 .last_mut()
322 .expect("Tried to update empty scene stack");
323
324 current_scene.mouse_button_down_event(&mut self.world, ctx, quad_ctx, button, x, y);
325 }
326 fn mouse_button_up_event(
327 &mut self,
328 ctx: &mut crate::Context,
329 quad_ctx: &mut miniquad::graphics::GraphicsContext,
330 button: crate::event::MouseButton,
331 x: f32,
332 y: f32,
333 ) {
334 let current_scene = &mut **self
335 .scenes
336 .last_mut()
337 .expect("Tried to update empty scene stack");
338
339 current_scene.mouse_button_up_event(&mut self.world, ctx, quad_ctx, button, x, y);
340 }
341
342 fn key_down_event(
343 &mut self,
344 ctx: &mut crate::Context,
345 quad_ctx: &mut miniquad::graphics::GraphicsContext,
346 keycode: crate::event::KeyCode,
347 _keymods: crate::event::KeyMods,
348 _repeat: bool,
349 ) {
350 let current_scene = &mut **self
351 .scenes
352 .last_mut()
353 .expect("Tried to update empty scene stack");
354
355 current_scene.key_down_event(&mut self.world, ctx, quad_ctx, keycode);
356 }
357
358 fn key_up_event(
359 &mut self,
360 ctx: &mut crate::Context,
361 quad_ctx: &mut miniquad::graphics::GraphicsContext,
362 keycode: crate::event::KeyCode,
363 _keymods: crate::event::KeyMods,
364 ) {
365 let current_scene = &mut **self
366 .scenes
367 .last_mut()
368 .expect("Tried to update empty scene stack");
369
370 current_scene.key_up_event(&mut self.world, ctx, quad_ctx, keycode);
371 }
372}