graphics_rs/
graphics.rs

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> {}