1use crate::{
2 context::Context, input::InputContext, render::RenderContext, time::TimeContext, window,
3};
4use winit::event_loop::EventLoop;
5
6pub trait Callbacks {
10 #[allow(unused_variables)]
12 fn init(&self, ctx: &mut Context) {}
13
14 #[allow(unused_variables)]
18 fn update(&mut self, ctx: &mut Context) -> bool {
19 false
20 }
21}
22
23pub(crate) struct App<C: Callbacks> {
26 pub(crate) callbacks: C,
27}
28
29impl<C> App<C>
31where
32 C: Callbacks + 'static,
33{
34 pub(crate) fn update(&mut self, ctx: &mut Context) -> bool {
37 ctx.time.update_time();
39
40 if self.callbacks.update(ctx) {
42 return true;
43 }
44
45 ctx.input.keyboard.save_keys();
47 ctx.input.keyboard.save_modifiers();
48 ctx.input.mouse.save_buttons();
49 ctx.input.mouse.set_mouse_delta((0.0, 0.0));
50
51 false
52 }
53}
54
55pub fn run<C: Callbacks + 'static>(callbacks: C)
59where
60 C: Callbacks + 'static,
61{
62 env_logger::init();
63 let app = App { callbacks };
64
65 let (mut ctx, event_loop) = pollster::block_on(build_context());
66
67 app.callbacks.init(&mut ctx);
68
69 pollster::block_on(window::run_window(event_loop, app, ctx));
70}
71
72async fn build_context() -> (Context, EventLoop<()>) {
73 let (window, event_loop) = window::new_window();
74
75 let time = TimeContext::default();
76 let input = InputContext::default();
77 let render = RenderContext::new(window).await;
78 let context = Context {
79 render,
80 time,
81 input,
82 };
83
84 (context, event_loop)
85}