1use crate::Result;
5use crate::TileProvider;
6use anyhow::Error;
7use sdl2::{
8 pixels::Color,
9 rect::{Point, Rect},
10 render::{Canvas, RenderTarget, TextureCreator},
11 surface::Surface,
12};
13
14pub type TileIndex = usize;
15
16pub trait Renderer {
17 fn place_surface(
18 &mut self,
19 surface: &Surface,
20 rect: Rect,
21 ) -> Result<()>;
22
23 fn place_tile(
24 &mut self,
25 tile: TileIndex,
26 destination: Point,
27 ) -> Result<()>;
28 fn fill_rect(&mut self, rect: Rect, color: Color) -> Result<()>;
29 fn fill(&mut self, color: Color) -> Result<()>;
30 fn draw_rect(&mut self, rect: Rect, color: Color) -> Result<()>;
31}
32
33pub struct MovePositionRenderer<'a> {
34 pub offset_x: i32,
35 pub offset_y: i32,
36 pub upstream: &'a mut dyn Renderer,
37}
38
39impl<'a> Renderer for MovePositionRenderer<'a> {
40 fn place_surface(
41 &mut self,
42 surface: &Surface,
43 mut rect: Rect,
44 ) -> Result<()> {
45 rect.offset(self.offset_x, self.offset_y);
46 self.upstream.place_surface(surface, rect)
47 }
48
49 fn place_tile(
50 &mut self,
51 tile: TileIndex,
52 destination: Point,
53 ) -> Result<()> {
54 self.upstream.place_tile(
55 tile,
56 destination.offset(self.offset_x, self.offset_y),
57 )
58 }
59
60 fn fill_rect(&mut self, mut rect: Rect, color: Color) -> Result<()> {
61 rect.offset(self.offset_x, self.offset_y);
62 self.upstream.fill_rect(rect, color)
63 }
64
65 fn fill(&mut self, color: Color) -> Result<()> {
66 self.upstream.fill(color)
67 }
68
69 fn draw_rect(&mut self, mut rect: Rect, color: Color) -> Result<()> {
70 rect.offset(self.offset_x, self.offset_y);
71 self.upstream.draw_rect(rect, color)
72 }
73}
74
75pub struct CanvasRenderer<'a, RT: RenderTarget, T> {
76 pub canvas: &'a mut Canvas<RT>,
77 pub texture_creator: &'a TextureCreator<T>,
78 pub tileprovider: &'a dyn TileProvider,
79}
80
81impl<'a, RT: RenderTarget, T> Renderer for CanvasRenderer<'a, RT, T> {
82 fn place_surface(
83 &mut self,
84 surface: &Surface,
85 rect: Rect,
86 ) -> Result<()> {
87 self.canvas
88 .copy(&surface.as_texture(self.texture_creator)?, None, rect)
89 .map_err(Error::msg)?;
90 Ok(())
91 }
92
93 fn place_tile(
94 &mut self,
95 tile: TileIndex,
96 destination: Point,
97 ) -> Result<()> {
98 let tile = self.tileprovider.get_tile(tile).unwrap();
99 let rect = Rect::new(
100 destination.x,
101 destination.y,
102 tile.width(),
103 tile.height(),
104 );
105 self.canvas
106 .copy(&tile.as_texture(self.texture_creator)?, None, rect)
107 .map_err(Error::msg)?;
108 Ok(())
109 }
110
111 fn fill_rect(&mut self, rect: Rect, color: Color) -> Result<()> {
112 self.canvas.set_draw_color(color);
113 self.canvas.fill_rect(rect).map_err(Error::msg)?;
114 Ok(())
115 }
116
117 fn fill(&mut self, color: Color) -> Result<()> {
118 self.canvas.set_draw_color(color);
119 self.canvas.clear();
120 Ok(())
121 }
122
123 fn draw_rect(&mut self, rect: Rect, color: Color) -> Result<()> {
124 self.canvas.set_draw_color(color);
125 self.canvas.draw_rect(rect).map_err(Error::msg)?;
126 Ok(())
127 }
128}