Skip to main content

furmint_runtime/
events.rs

1//! Module for handling events
2
3use specs::{System, WriteExpect};
4use std::sync::mpsc::Receiver;
5
6#[non_exhaustive]
7/// Enum of possible app events
8#[derive(Debug, PartialEq)]
9pub enum AppEvent {
10    /// An event that should be sent from e.g. SIGINT handler or graphics thread to terminate the
11    /// main runtime loop gracefully
12    ExitRequested,
13}
14
15pub(crate) struct AppEventReceivingSystem {
16    receiver: Receiver<AppEvent>,
17}
18
19impl AppEventReceivingSystem {
20    /// Create a new instance of [`AppEventReceivingSystem`]
21    pub fn new(receiver: Receiver<AppEvent>) -> Self {
22        Self { receiver }
23    }
24}
25
26impl<'a> System<'a> for AppEventReceivingSystem {
27    type SystemData = WriteExpect<'a, Events<AppEvent>>;
28
29    fn run(&mut self, mut events: Self::SystemData) {
30        #[allow(clippy::single_match)] // this match block will grow, so justified ig
31        match self.receiver.try_recv() {
32            Ok(AppEvent::ExitRequested) => {
33                events.send(AppEvent::ExitRequested);
34            }
35            _ => {}
36        }
37    }
38}
39
40/// Struct representing events
41#[derive(Debug)]
42pub struct Events<T> {
43    current: Vec<T>,
44    next: Vec<T>,
45}
46
47impl<T> Default for Events<T> {
48    fn default() -> Self {
49        Self {
50            current: Vec::new(),
51            next: Vec::new(),
52        }
53    }
54}
55
56impl<T> Events<T> {
57    /// Send an event
58    pub fn send(&mut self, event: T) {
59        self.next.push(event);
60    }
61
62    /// Read events from the current frame/batch
63    pub fn iter(&self) -> impl Iterator<Item = &T> {
64        self.current.iter()
65    }
66
67    /// Clear current events and swap it with next array of events
68    pub(crate) fn update(&mut self) {
69        self.current.clear();
70        std::mem::swap(&mut self.current, &mut self.next);
71    }
72
73    /// Clear all buffered events
74    #[allow(unused)]
75    pub(crate) fn clear(&mut self) {
76        self.current.clear();
77        self.next.clear();
78    }
79
80    /// Is the current event buffer empty?
81    pub fn is_empty(&self) -> bool {
82        self.current.is_empty()
83    }
84}