-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
87 lines (75 loc) · 2.06 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
pub const INCRO_VERSION: u64 = 1; // bumped on each incompatible ABI change
pub use evdev;
pub use scopeguard;
use evdev::InputEvent;
use event_sender::EventSender;
use std::ops::ControlFlow;
use std::sync::{
atomic::{AtomicBool, Ordering},
mpsc::Sender,
Arc,
};
mod event_sender;
mod r#macro;
/// Incro handle, contains all available methods for the callback
#[derive(Clone)]
#[repr(C)]
pub struct Incro {
event_sender: EventSender,
parent_thread: Option<ThreadHandle>,
}
/// Handle of an Incro-style spawned thread
#[derive(Clone)]
pub struct ThreadHandle {
should_stop: Arc<AtomicBool>,
}
impl Incro {
#[doc(hidden)]
pub fn new(event_sender: Sender<Vec<InputEvent>>) -> Self {
Self {
event_sender: EventSender::new(event_sender),
parent_thread: None,
}
}
#[must_use]
/// Emits fake events
pub fn emit(&self, events: &[InputEvent]) -> ControlFlow<()> {
if let Some(parent_thread) = &self.parent_thread {
if parent_thread.should_stop.load(Ordering::SeqCst) {
return ControlFlow::Break(());
}
}
self.force_emit(events);
ControlFlow::Continue(())
}
/// Emits fake events even if thread of `Incro` must be stopped
pub fn force_emit(&self, events: &[InputEvent]) {
self.event_sender.send(events);
}
/// Spawns a thread
pub fn thread<F: FnOnce(Incro) -> ControlFlow<()> + Send + 'static>(
&self,
f: F,
) -> ThreadHandle {
let mut incro = self.clone();
let atomic = Arc::new(AtomicBool::new(false));
let handle = ThreadHandle {
should_stop: Arc::clone(&atomic),
};
incro.parent_thread = Some(handle.clone());
std::thread::spawn(move || f(incro));
handle
}
}
impl ThreadHandle {
pub fn detach(self) {
std::mem::forget(self);
}
pub fn stop(self) {}
}
impl Drop for ThreadHandle {
fn drop(&mut self) {
self.should_stop
.store(true, std::sync::atomic::Ordering::SeqCst);
}
}