1mod backend;
31pub mod builder;
32pub mod draw;
33pub mod info;
34pub mod painter;
35pub mod settings;
36pub mod vertex;
37
38pub use winit;
39
40use builder::Builder;
41use info::Info;
42
43use winit::{
44 event::*,
45 event_loop::{ControlFlow, EventLoop},
46 window::WindowBuilder,
47};
48
49use self::{backend::State, painter::Painter};
50
51#[derive(Default)]
53pub enum EventResult {
54 #[default]
55 Unhandled,
56 Handled,
57 Exit,
58}
59
60pub trait App {
63 fn init(&mut self, _builder: &mut Builder) {}
65
66 fn render(&mut self, painter: &mut Painter, builder: &mut Builder, info: &Info);
68
69 fn event(&mut self, event: &WindowEvent) -> EventResult;
72
73 fn update(&mut self, builder: &mut Builder, info: &Info);
75
76 fn run(self, settings: settings::RunSettings)
81 where
82 Self: Sized + 'static,
83 {
84 let event_loop = EventLoop::new();
85 self.run_with_event_loop(event_loop, settings);
86 }
87
88 fn run_with_event_loop(mut self, event_loop: EventLoop<()>, settings: settings::RunSettings)
90 where
91 Self: Sized + 'static,
92 {
93 let window = WindowBuilder::new().build(&event_loop).unwrap();
94 window.set_title(settings.title);
95 let mut state: State = pollster::block_on(State::new(window, &mut self));
96
97 event_loop.run(move |event, _, control_flow| match event {
98 Event::RedrawRequested(window_id) if window_id == state.window().id() => {
99 state.update(&mut self);
100 match state.render(&mut self) {
101 Ok(_) => {}
102 Err(wgpu::SurfaceError::Lost) => state.resize(state.size),
103 Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
104 Err(e) => eprintln!("{:?}", e),
105 }
106 }
107 Event::MainEventsCleared => {
108 if !settings.continuous {
109 control_flow.set_wait();
110 }
111
112 state.window().request_redraw();
113 }
114 Event::WindowEvent {
115 ref event,
116 window_id,
117 } if window_id == state.window().id() => match state.event(&mut self, event) {
118 EventResult::Unhandled => match event {
119 WindowEvent::CloseRequested => {
120 *control_flow = ControlFlow::Exit;
121 }
122 WindowEvent::Resized(physical_size) => {
123 state.resize(*physical_size);
124 }
125 WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
126 state.resize(**new_inner_size);
127 }
128 _ => {}
129 },
130 EventResult::Handled => {}
131 EventResult::Exit => *control_flow = ControlFlow::Exit,
132 },
133 Event::Resumed => {
134 state.create_surface();
135 }
136 Event::Suspended => {}
137
138 _ => {}
139 });
140 }
141}