y_engine/
lib.rs

1use app::App;
2use state::{running, State};
3use winit::{
4    application::ApplicationHandler,
5    event::WindowEvent,
6    event_loop::{ActiveEventLoop, EventLoop},
7    window::WindowId,
8};
9
10pub mod app;
11pub mod state;
12pub mod util;
13
14pub struct YEngine<T: App + 'static> {
15    inner: Option<YEngineInner<T>>,
16}
17
18impl<T: App> ApplicationHandler for YEngine<T> {
19    fn resumed(&mut self, event_loop: &ActiveEventLoop) {
20        if self.inner.is_none() {
21            self.inner = Some(YEngineInner::new(event_loop));
22        }
23    }
24
25    fn window_event(&mut self, event_loop: &ActiveEventLoop, _: WindowId, event: WindowEvent) {
26        if let Some(inner) = self.inner.as_mut() {
27            inner.handle_window_event(event_loop, event);
28        }
29    }
30}
31
32impl<T: App + 'static> Default for YEngine<T> {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl<T: App + 'static> YEngine<T> {
39    pub fn new() -> Self {
40        Self { inner: None }
41    }
42
43    pub fn run(&mut self) {
44        let event_loop = EventLoop::new().unwrap();
45        event_loop.run_app(self).unwrap();
46    }
47}
48
49struct YEngineInner<T: App + 'static> {
50    state: state::State,
51    phantom: std::marker::PhantomData<T>,
52}
53
54impl<T: App> YEngineInner<T> {
55    fn new(event_loop: &ActiveEventLoop) -> Self {
56        Self {
57            state: state::State::new(event_loop),
58            phantom: std::marker::PhantomData,
59        }
60    }
61
62    fn transition_to_running(&mut self) {
63        let old_state = std::mem::replace(&mut self.state, state::State::None);
64        let State::Starting(starting) = old_state else {
65            panic!("Expected starting state");
66        };
67        self.state = State::Running(running::State::new::<T>(starting));
68    }
69
70    fn handle_window_event(&mut self, event_loop: &ActiveEventLoop, event: WindowEvent) {
71        if let State::Starting(state) = &self.state {
72            if state.finished() {
73                self.transition_to_running();
74            }
75        }
76
77        self.state.handle_window_event(event_loop, event);
78    }
79}