taika/
app_handler.rs

1use crate::{window::Window, RenderSettings, QUIT};
2use std::{
3    sync::{Arc, Mutex},
4    time::Instant,
5};
6use winit::{application::ApplicationHandler, event::WindowEvent};
7
8pub(crate) struct AppState<'a> {
9    pub device: Arc<Mutex<wgpu::Device>>,
10    pub queue: Arc<Mutex<wgpu::Queue>>,
11    pub windows: Vec<Arc<Mutex<Window<'a>>>>,
12    pub instance: wgpu::Instance,
13    pub adapter: wgpu::Adapter,
14    pub render_settings: RenderSettings,
15}
16
17impl<'a> ApplicationHandler<()> for AppState<'a> {
18    fn user_event(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop, _event: ()) {}
19
20    fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
21        for window in &self.windows {
22            let window_attributes = winit::window::WindowAttributes::default()
23                .with_title(window.lock().unwrap().title.clone())
24                .with_min_inner_size(winit::dpi::LogicalSize::new(20.0, 20.0));
25            let win = event_loop.create_window(window_attributes).unwrap();
26            window.lock().unwrap().init(&self.instance, win).unwrap();
27        }
28
29        for window in &self.windows {
30            window.lock().unwrap().configure_surface(
31                &self.adapter,
32                &self.device.lock().unwrap(),
33                &self.render_settings,
34            );
35        }
36        let windows = self.windows.clone();
37        let device = self.device.clone();
38        let queue = self.queue.clone();
39        for window in &windows {
40            window
41                .lock()
42                .unwrap()
43                .do_device_init(&self.adapter, device.clone(), queue.clone());
44        }
45        for window in &self.windows {
46            window.lock().unwrap().request_redraw();
47        }
48    }
49
50    fn window_event(
51        &mut self,
52        event_loop: &winit::event_loop::ActiveEventLoop,
53        window_id: winit::window::WindowId,
54        event: winit::event::WindowEvent,
55    ) {
56        if *QUIT.lock().unwrap() {
57            event_loop.exit();
58            for window in self.windows.iter() {
59                window.lock().unwrap().do_closed();
60            }
61            return;
62        }
63        for window in self.windows.iter() {
64            if window.lock().unwrap().get_window_id() == window_id {
65                match event {
66                    WindowEvent::Resized(physical_size) => {
67                        window.lock().unwrap().resize_surface(
68                            &self.device.lock().unwrap(),
69                            physical_size,
70                            &self.queue.lock().unwrap(),
71                        );
72                    }
73                    WindowEvent::CloseRequested => {
74                        window.lock().unwrap().do_closed();
75                        event_loop.exit();
76                    }
77                    WindowEvent::Focused(focused) => {
78                        window.lock().unwrap().do_focus(focused);
79                    }
80                    WindowEvent::RedrawRequested => {
81                        let mut window = window.lock().unwrap();
82                        if let Some(max_framerate) = self.render_settings.max_framerate {
83                            if window.last_frame.elapsed().as_secs_f64()
84                                < 1.0 / max_framerate as f64
85                                && !self.render_settings.vsync
86                            {
87                                window.request_redraw();
88                                break;
89                            }
90                        }
91                        window.last_frame = Instant::now();
92                        window.do_frame();
93                        let surface = window.get_surface();
94                        let frame = surface.get_current_texture();
95                        if let Err(err) = frame {
96                            println!("Failed to get current frame. Window state listed below:");
97                            println!("Error: {:?}", err);
98                            return;
99                        }
100                        let frame = frame.unwrap();
101                        let view = frame.texture.create_view(&wgpu::TextureViewDescriptor {
102                            format: Some(window.get_target_properties().view_format),
103                            ..Default::default()
104                        });
105                        let mut encoder = self.device.lock().unwrap().create_command_encoder(
106                            &wgpu::CommandEncoderDescriptor { label: None },
107                        );
108                        let pipeline = window.get_render_pipeline();
109                        let pipeline = pipeline.lock();
110                        pipeline.unwrap().render(
111                            &self.device.lock().unwrap(),
112                            &mut encoder,
113                            &self.queue.lock().unwrap(),
114                            &view,
115                            window.get_target_properties(),
116                        );
117                        self.queue.lock().unwrap().submit(Some(encoder.finish()));
118                        window.pre_present_notify();
119                        frame.present();
120                        window.do_after_frame();
121                        window.request_redraw();
122                    }
123                    _ => {}
124                }
125                window.lock().unwrap().do_window_event(&event);
126                break;
127            }
128        }
129    }
130
131    fn device_event(
132        &mut self,
133        _event_loop: &winit::event_loop::ActiveEventLoop,
134        _device_id: winit::event::DeviceId,
135        _event: winit::event::DeviceEvent,
136    ) {
137    }
138
139    fn about_to_wait(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) {}
140}