You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
1.8 KiB
82 lines
1.8 KiB
use crate::EventHandle;
|
|
use crossbeam_channel::{unbounded, Receiver, Sender};
|
|
use little_core::event::{Event, Key};
|
|
use std::{
|
|
collections::{HashMap, HashSet},
|
|
sync::{
|
|
atomic::{AtomicBool, Ordering},
|
|
Arc,
|
|
},
|
|
thread,
|
|
};
|
|
|
|
/// An asynchronous event reactor
|
|
pub struct Reactor {
|
|
rx: Receiver<Event>,
|
|
run: Arc<AtomicBool>,
|
|
handlers: HashMap<usize, Box<dyn EventHandle + Send + 'static>>,
|
|
mouse: MouseState,
|
|
key: KeyboardState,
|
|
}
|
|
|
|
/// A runtime handle to the event reactor
|
|
pub struct ReactorHandle {
|
|
run: Arc<AtomicBool>,
|
|
tx: Sender<Event>,
|
|
}
|
|
|
|
impl ReactorHandle {
|
|
/// Stop the event reactor thread
|
|
pub fn stop(&self) {
|
|
self.run.store(false, Ordering::Relaxed);
|
|
}
|
|
|
|
/// Send an event to the reactor
|
|
pub fn send(&self, e: Event) {
|
|
self.tx.send(e).unwrap();
|
|
}
|
|
}
|
|
|
|
/// Encode the state the mouse can be in
|
|
#[derive(Default)]
|
|
struct MouseState {
|
|
pos: (f32, f32),
|
|
left: bool,
|
|
right: bool,
|
|
middle: bool,
|
|
x1: bool,
|
|
x2: bool,
|
|
}
|
|
|
|
/// Encode the state the keyboard can be in
|
|
#[derive(Default)]
|
|
struct KeyboardState {
|
|
pressed: HashSet<Key>,
|
|
}
|
|
|
|
impl Reactor {
|
|
pub fn new() -> ReactorHandle {
|
|
let (tx, rx) = unbounded();
|
|
let run = Arc::new(true.into());
|
|
|
|
// Create and start the event reactor
|
|
let this = Self {
|
|
rx,
|
|
run: Arc::clone(&run),
|
|
handlers: HashMap::new(),
|
|
mouse: MouseState::default(),
|
|
key: KeyboardState::default(),
|
|
};
|
|
thread::spawn(move || this.run());
|
|
|
|
// Then return a handle
|
|
ReactorHandle { run, tx }
|
|
}
|
|
|
|
/// Run a detached event reactor
|
|
pub fn run(self) {
|
|
while self.run.load(Ordering::Relaxed) {
|
|
// Do things
|
|
}
|
|
}
|
|
}
|
|
|