|
|
|
@ -1,15 +1,42 @@ |
|
|
|
|
use crate::EventHandle; |
|
|
|
|
use crossbeam_channel::{unbounded, Receiver, Sender}; |
|
|
|
|
use little_core::event::{Event, Key}; |
|
|
|
|
use std::collections::{HashMap, HashSet}; |
|
|
|
|
use std::{ |
|
|
|
|
collections::{HashMap, HashSet}, |
|
|
|
|
sync::{ |
|
|
|
|
atomic::{AtomicBool, Ordering}, |
|
|
|
|
Arc, |
|
|
|
|
}, |
|
|
|
|
thread, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/// An asynchronous event reactor
|
|
|
|
|
pub struct Reactor { |
|
|
|
|
rx: Receiver<Event>, |
|
|
|
|
handlers: HashMap<usize, Box<dyn EventHandle + 'static>>, |
|
|
|
|
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 { |
|
|
|
@ -28,21 +55,28 @@ struct KeyboardState { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Reactor { |
|
|
|
|
pub fn new() -> (Sender<Event>, Self) { |
|
|
|
|
pub fn new() -> ReactorHandle { |
|
|
|
|
let (tx, rx) = unbounded(); |
|
|
|
|
( |
|
|
|
|
tx, |
|
|
|
|
Self { |
|
|
|
|
rx, |
|
|
|
|
handlers: HashMap::new(), |
|
|
|
|
mouse: MouseState::default(), |
|
|
|
|
key: KeyboardState::default(), |
|
|
|
|
}, |
|
|
|
|
) |
|
|
|
|
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
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|