ascii_forge/renderer/
buffer.rs1use crate::prelude::*;
2
3#[derive(Debug)]
25pub struct Buffer {
26 size: Vec2,
27 cells: Vec<Cell>,
28}
29
30impl AsMut<Buffer> for Buffer {
31 fn as_mut(&mut self) -> &mut Buffer {
32 self
33 }
34}
35
36impl Buffer {
37 pub fn new(size: impl Into<Vec2>) -> Self {
39 let size = size.into();
40 Self {
41 size,
42 cells: vec![Cell::default(); size.x as usize * size.y as usize],
43 }
44 }
45
46 pub fn size(&self) -> Vec2 {
48 self.size
49 }
50
51 pub fn set<C: Into<Cell>>(&mut self, loc: impl Into<Vec2>, cell: C) {
53 let idx = self.index_of(loc);
54
55 self.cells[idx] = cell.into();
56 }
57
58 pub fn fill<C: Into<Cell>>(&mut self, cell: C) {
60 let cell = cell.into();
61 for i in 0..self.cells.len() {
62 self.cells[i] = cell.clone()
63 }
64 }
65
66 pub fn get(&self, loc: impl Into<Vec2>) -> &Cell {
68 let idx = self.index_of(loc);
69 &self.cells[idx]
70 }
71
72 pub fn get_mut(&mut self, loc: impl Into<Vec2>) -> &mut Cell {
74 let idx = self.index_of(loc);
75 &mut self.cells[idx]
76 }
77
78 fn index_of(&self, loc: impl Into<Vec2>) -> usize {
79 let loc = loc.into();
80 let idx = loc.y as usize * self.size.x as usize + loc.x as usize;
81
82 debug_assert!((idx as u16) < self.size.x * self.size.y);
83
84 idx.min((self.size.x as usize * self.size.y as usize) - 1)
85 }
86
87 pub fn clear(&mut self) {
89 *self = Self::new(self.size);
90 }
91
92 pub fn diff<'a>(&self, other: &'a Buffer) -> Vec<(Vec2, &'a Cell)> {
94 assert!(self.size == other.size);
95
96 let mut res = vec![];
97
98 for x in 0..self.size.x {
99 for y in 0..self.size.y {
100 if self.get((x, y)) != other.get((x, y)) {
101 res.push((vec2(x, y), other.get((x, y))))
102 }
103 }
104 }
105
106 res
107 }
108
109 pub fn shrink(&mut self) {
111 let mut max_whitespace_x = 0;
112 let mut max_whitespace_y = 0;
113 for x in (0..self.size.x).rev() {
114 for y in (0..self.size.y).rev() {
115 if !self.get((x, y)).is_empty() {
116 max_whitespace_x = x.max(max_whitespace_x);
117 max_whitespace_y = y.max(max_whitespace_y);
118 }
119 }
120 }
121
122 self.resize(vec2(max_whitespace_x + 1, max_whitespace_y + 1));
123 }
124
125 pub fn resize(&mut self, new_size: impl Into<Vec2>) {
127 let new_size = new_size.into();
128 if self.size == new_size {
129 return;
130 }
131
132 let mut new_elements = vec![];
133
134 for y in 0..new_size.y {
135 for x in 0..new_size.x {
136 new_elements.push(self.get((x, y)).clone());
137 }
138 }
139
140 self.size = new_size;
141 self.cells = new_elements;
142 }
143
144 pub fn sized_element<R: Render>(item: R) -> Self {
147 let mut buff = Buffer::new((100, 100));
148 render!(buff, vec2(0, 0) => [ item ]);
149 buff.shrink();
150 buff
151 }
152}
153
154impl Render for Buffer {
155 fn render(&self, loc: Vec2, buffer: &mut Buffer) -> Vec2 {
156 for x in 0..self.size.x {
157 if x + loc.x >= buffer.size.x {
158 break;
159 }
160
161 for y in 0..self.size.y {
162 if y + loc.y >= buffer.size.y {
163 break;
164 }
165
166 let dest = vec2(x + loc.x, y + loc.y);
167
168 buffer.set(dest, self.get(vec2(x, y)).clone());
169 }
170 }
171 vec2(loc.x + buffer.size().x, loc.y + buffer.size().y)
172 }
173}