1use std::num::NonZeroU32;
2use std::sync::Arc;
3
4use winit::window::Window;
5use winit::{
6 dpi::PhysicalSize,
7 event::{Event, WindowEvent},
8 event_loop::EventLoop,
9 window::WindowBuilder,
10};
11
12use crate::color::Color;
13use crate::traits::canvas::Canvas;
14use crate::traits::canvas_handler::CanvasHandler;
15use crate::traits::{handles_draw_request::HandlesDrawRequest, requests_draw::RequestDraw};
16
17pub struct Graphics<'a, T>
18where
19 T: RequestDraw<'a> + Canvas,
20{
21 canvas: &'a mut T,
22 window: Option<Arc<Window>>,
23}
24
25fn copy_color_buffers(dst: &mut [Color], src: &[Color]) {
26 for (d, s) in dst.iter_mut().zip(src.iter()) {
27 *d = *s;
28 }
29}
30
31impl<'a, T: RequestDraw<'a> + Canvas> Graphics<'a, T> {
32 pub fn create(canvas: &'a mut T) -> Result<Self, String> {
33 Ok(Self {
34 canvas: canvas,
35 window: None,
36 })
37 }
38
39 pub fn run<G: CanvasHandler>(&mut self, handler: &mut G) -> Result<(), String> {
40 let event_loop = EventLoop::new().map_err(|error| error.to_string())?;
41
42 let window = WindowBuilder::new()
43 .with_resizable(false)
44 .with_inner_size(PhysicalSize::new(
45 self.canvas.width() as u32,
46 self.canvas.height() as u32,
47 ))
48 .build(&event_loop)
49 .map_err(|error| error.to_string())?;
50
51 let window = Arc::new(window);
52
53 self.window = Some(window.clone());
54
55 let graphics_context =
56 softbuffer::Context::new(window.clone()).map_err(|error| error.to_string())?;
57
58 let mut surface = softbuffer::Surface::new(&graphics_context, window.clone())
59 .map_err(|error| error.to_string())?;
60
61 surface
62 .resize(
63 NonZeroU32::new(self.canvas.width() as u32).unwrap(),
64 NonZeroU32::new(self.canvas.height() as u32).unwrap(),
65 )
66 .expect("could not resize surface!");
67
68 event_loop
69 .run(move |event, window_target| match event {
70 Event::WindowEvent { event, .. } => match event {
71 WindowEvent::CloseRequested => {
72 window_target.exit();
73 }
74 WindowEvent::RedrawRequested => {
75 handler.update(self.canvas);
76 let mut buffer = surface.buffer_mut().expect("could not get mut buffer!");
77 let mut mb = buffer.as_mut();
78 copy_color_buffers(&mut mb, self.canvas.buffer_mut_slice());
79
80 buffer.present().unwrap();
81 }
82 _ => (),
83 },
84 _ => window.request_redraw(),
85 })
86 .map_err(|error| error.to_string())?;
87
88 Ok(())
89 }
90}
91
92impl<'a, T: RequestDraw<'a> + Canvas> HandlesDrawRequest for Graphics<'a, T> {
93 fn draw(&self) {
94 if let Some(window) = &self.window {
95 window.request_redraw()
96 }
97 }
98}
99
100unsafe impl<'a, T: RequestDraw<'a> + Canvas> Sync for Graphics<'a, T> {}