boundschecker/
boundschecker.rs1use std::io;
4use std::io::stdout;
5use std::time::Instant;
6use teng::components::Component;
7use teng::rendering::pixel::Pixel;
8use teng::rendering::renderer::Renderer;
9use teng::util::planarvec::Bounds;
10use teng::{
11 install_panic_handler, terminal_cleanup, terminal_setup, Game, SharedState, UpdateInfo,
12};
13
14fn main() -> io::Result<()> {
15 terminal_setup()?;
16 install_panic_handler();
17
18 let mut game = Game::new(stdout());
19 game.install_recommended_components();
20 game.add_component(Box::new(BoundsCheckerComponent::new()));
21 game.run()?;
22
23 terminal_cleanup()?;
24
25 Ok(())
26}
27
28pub struct BoundsCheckerComponent {
29 first_loc: Option<(usize, usize)>,
30 second_loc: Option<(usize, usize)>,
31 sub_first_loc: Option<(usize, usize)>,
32 sub_second_loc: Option<(usize, usize)>,
33 union_instead_of_subtract: bool,
34}
35
36impl BoundsCheckerComponent {
37 pub fn new() -> Self {
38 Self {
39 first_loc: None,
40 second_loc: None,
41 sub_first_loc: None,
42 sub_second_loc: None,
43 union_instead_of_subtract: false,
44 }
45 }
46}
47
48impl Component for BoundsCheckerComponent {
49 fn update(&mut self, _update_info: UpdateInfo, shared_state: &mut SharedState) {
50 let pressed = shared_state.mouse_pressed.left;
52 if pressed {
53 self.first_loc = None;
54 self.second_loc = None;
55
56 self.first_loc = Some(shared_state.mouse_info.last_mouse_pos);
57 }
58
59 if !shared_state.mouse_info.left_mouse_down
61 && self.first_loc.is_some()
62 && self.second_loc.is_none()
63 {
64 self.second_loc = Some(shared_state.mouse_info.last_mouse_pos);
66 }
67
68 let pressed = shared_state.mouse_pressed.right;
70 if pressed {
71 self.sub_first_loc = None;
72 self.sub_second_loc = None;
73
74 self.sub_first_loc = Some(shared_state.mouse_info.last_mouse_pos);
75 }
76
77 if !shared_state.mouse_info.right_mouse_down
79 && self.sub_first_loc.is_some()
80 && self.sub_second_loc.is_none()
81 {
82 self.sub_second_loc = Some(shared_state.mouse_info.last_mouse_pos);
84 }
85
86 if shared_state.pressed_keys.did_press_char_ignore_case(' ') {
87 self.union_instead_of_subtract = !self.union_instead_of_subtract;
88 }
89 }
90
91 fn render(&self, renderer: &mut dyn Renderer, shared_state: &SharedState, depth_base: i32) {
92 let depth_base = i32::MAX - 1;
93
94 let mut min_x = 0;
95 let mut max_x = 0;
96 let mut min_y = 0;
97 let mut max_y = 0;
98
99 let mut first_bounds = None;
100
101 if let Some((x, y)) = self.first_loc {
102 let first_pos = (x, y);
103
104 let second_pos = if let Some((x, y)) = self.second_loc {
105 (x, y)
106 } else {
107 shared_state.mouse_info.last_mouse_pos
109 };
110
111 min_x = first_pos.0.min(second_pos.0);
112 max_x = first_pos.0.max(second_pos.0);
113 min_y = first_pos.1.min(second_pos.1);
114 max_y = first_pos.1.max(second_pos.1);
115
116 let bounds = Bounds {
117 min_x: min_x as i64,
118 max_x: max_x as i64,
119 min_y: min_y as i64,
120 max_y: max_y as i64,
121 };
122
123 first_bounds = Some(bounds);
124 }
125
126 let mut sub_bounds = None;
127
128 if let Some((x, y)) = self.sub_first_loc {
129 let first_pos = (x, y);
130
131 let second_pos = if let Some((x, y)) = self.sub_second_loc {
132 (x, y)
133 } else {
134 shared_state.mouse_info.last_mouse_pos
136 };
137
138 min_x = first_pos.0.min(second_pos.0);
139 max_x = first_pos.0.max(second_pos.0);
140 min_y = first_pos.1.min(second_pos.1);
141 max_y = first_pos.1.max(second_pos.1);
142
143 let bounds = Bounds {
144 min_x: min_x as i64,
145 max_x: max_x as i64,
146 min_y: min_y as i64,
147 max_y: max_y as i64,
148 };
149
150 sub_bounds = Some(bounds);
151 }
152
153 if self.union_instead_of_subtract {
154 match (first_bounds, sub_bounds) {
156 (Some(b1), Some(b2)) => {
157 let bound = b1.union(b2);
158 for x in bound.min_x..=bound.max_x {
159 for y in bound.min_y..=bound.max_y {
160 renderer.render_pixel(
161 x as usize,
162 y as usize,
163 Pixel::new('█'),
164 depth_base,
165 );
166 }
167 }
168 }
169 _ => {}
170 }
171 } else {
172 if let Some(bounds) = first_bounds {
174 let the_bounds = bounds.subtract(sub_bounds.unwrap_or(Bounds::empty()));
175
176 for bound in the_bounds.iter() {
177 for x in bound.min_x..=bound.max_x {
178 for y in bound.min_y..=bound.max_y {
179 renderer.render_pixel(
180 x as usize,
181 y as usize,
182 Pixel::new('█'),
183 depth_base,
184 );
185 }
186 }
187 }
188 }
189 }
190 }
191}