(&mut self)
| 238 | } |
| 239 | |
| 240 | pub fn run(&mut self) -> anyhow::Result<()> { |
| 241 | self.draw()?; |
| 242 | |
| 243 | while self.state != AppState::Exiting { |
| 244 | let mut should_draw = false; |
| 245 | |
| 246 | let first_event = match self |
| 247 | .event_rx |
| 248 | .recv_timeout(Duration::from_millis(TICK_RATE_MS)) |
| 249 | { |
| 250 | Ok(event) => Some(event), |
| 251 | Err(mpsc::RecvTimeoutError::Timeout) => None, |
| 252 | Err(mpsc::RecvTimeoutError::Disconnected) => break, |
| 253 | }; |
| 254 | |
| 255 | if let Some(event) = first_event { |
| 256 | self.handle_event(&event)?; |
| 257 | should_draw |= self.event_caused_change; |
| 258 | |
| 259 | let mut deferred_mouse_move: Option<Event> = None; |
| 260 | for _ in 0..MAX_EVENTS_PER_FRAME { |
| 261 | let next = match self.event_rx.try_recv() { |
| 262 | Ok(next) => next, |
| 263 | Err(mpsc::TryRecvError::Empty) => break, |
| 264 | Err(mpsc::TryRecvError::Disconnected) => { |
| 265 | self.state = AppState::Exiting; |
| 266 | break; |
| 267 | } |
| 268 | }; |
| 269 | |
| 270 | let is_mouse_move = matches!( |
| 271 | next, |
| 272 | Event::Mouse(crossterm::event::MouseEvent { |
| 273 | kind: crossterm::event::MouseEventKind::Moved, |
| 274 | .. |
| 275 | }) |
| 276 | ); |
| 277 | |
| 278 | if is_mouse_move { |
| 279 | deferred_mouse_move = Some(next); |
| 280 | continue; |
| 281 | } |
| 282 | |
| 283 | if let Some(moved) = deferred_mouse_move.take() { |
| 284 | self.handle_event(&moved)?; |
| 285 | should_draw |= self.event_caused_change; |
| 286 | } |
| 287 | |
| 288 | self.handle_event(&next)?; |
| 289 | should_draw |= self.event_caused_change; |
| 290 | } |
| 291 | |
| 292 | if let Some(moved) = deferred_mouse_move { |
| 293 | self.handle_event(&moved)?; |
| 294 | should_draw |= self.event_caused_change; |
| 295 | } |
| 296 | } |
| 297 |
no test coverage detected