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}