Skip to content

Commit ba68eaf

Browse files
committed
refactor: accept only one observer for evdev event loop
1 parent da6a89a commit ba68eaf

3 files changed

Lines changed: 50 additions & 33 deletions

File tree

evdev/src/main/rust/evdev_manager/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

evdev/src/main/rust/evdev_manager/core/src/event_loop.rs

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use mio::{Events, Interest, Poll, Registry, Token, Waker};
1111
use slab::Slab;
1212
use std::collections::HashMap;
1313
use std::error::Error;
14+
use std::fmt;
1415
use std::fs::read_dir;
1516
use std::io;
1617
use std::io::ErrorKind;
@@ -21,6 +22,11 @@ use std::sync::{mpsc, Arc, OnceLock, RwLock};
2122
use std::time::{Duration, Instant};
2223
use tokio::task::JoinHandle;
2324

25+
/// This callback returns true if the observer consumed the input event.
26+
/// Parameters: device_id (slab key), device_identifier, event
27+
pub type EvdevObserver =
28+
fn(device_id: usize, device_identifier: &DeviceIdentifier, event: &InputEvent) -> bool;
29+
2430
/// Key for device path map - only JNI-exposed fields (excludes version).
2531
/// Used for O(1) HashMap lookup when matching devices.
2632
#[derive(Hash, Eq, PartialEq)]
@@ -46,27 +52,49 @@ static EVENT_LOOP_MANAGER: OnceLock<EventLoopManager> = OnceLock::new();
4652

4753
const WAKER_TOKEN: Token = Token(0);
4854

49-
/// This callback returns true if the observer consumed the input event.
50-
/// Parameters: device_id (slab key), device_identifier, event
51-
pub type EvdevObserver =
52-
fn(device_id: usize, device_identifier: &DeviceIdentifier, event: &InputEvent) -> bool;
53-
5455
pub struct EventLoopManager {
5556
stop_flag: Arc<AtomicBool>,
5657
poll: Arc<RwLock<Poll>>,
5758
registry: Arc<Registry>,
5859
join_handle: RwLock<Option<JoinHandle<()>>>,
5960
waker: Waker,
60-
observers: Arc<RwLock<Slab<EvdevObserver>>>,
61+
observer: EvdevObserver,
6162
grabbed_devices: Arc<RwLock<Slab<GrabbedDevice>>>,
6263
}
6364

65+
impl fmt::Debug for EventLoopManager {
66+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67+
let is_running = self.join_handle.read().map(|h| h.is_some()).unwrap_or(false);
68+
let device_count = self
69+
.grabbed_devices
70+
.read()
71+
.map(|d| d.len())
72+
.unwrap_or(0);
73+
74+
f.debug_struct("EventLoopManager")
75+
.field("is_running", &is_running)
76+
.field("grabbed_device_count", &device_count)
77+
.finish_non_exhaustive()
78+
}
79+
}
80+
6481
impl EventLoopManager {
82+
/// Initialize the EventLoopManager with an observer. Must be called once before `get()`.
83+
/// Panics if called more than once.
84+
pub fn init(observer: EvdevObserver) {
85+
EVENT_LOOP_MANAGER
86+
.set(Self::new(observer))
87+
.expect("EventLoopManager already initialized");
88+
}
89+
90+
/// Get the EventLoopManager instance. Panics if `init()` was not called.
6591
pub fn get() -> &'static EventLoopManager {
66-
EVENT_LOOP_MANAGER.get_or_init(Self::new)
92+
EVENT_LOOP_MANAGER
93+
.get()
94+
.expect("EventLoopManager not initialized. Call init() first.")
6795
}
6896

69-
fn new() -> Self {
97+
fn new(observer: EvdevObserver) -> Self {
7098
let poll = Poll::new().unwrap();
7199
let registry = poll.registry().try_clone().unwrap();
72100
let waker = Waker::new(&registry, WAKER_TOKEN).unwrap();
@@ -78,7 +106,7 @@ impl EventLoopManager {
78106
registry: Arc::new(registry),
79107
join_handle: RwLock::new(None),
80108
waker,
81-
observers: Arc::new(RwLock::new(Slab::with_capacity(16))),
109+
observer,
82110
grabbed_devices: Arc::new(RwLock::new(Slab::with_capacity(32))),
83111
}
84112
}
@@ -93,7 +121,7 @@ impl EventLoopManager {
93121
} else {
94122
self.stop_flag.store(false, Ordering::Relaxed);
95123

96-
let observers = self.observers.clone();
124+
let observer = self.observer;
97125
let grabbed_devices = self.grabbed_devices.clone();
98126

99127
let (tx, rx) = mpsc::channel();
@@ -103,7 +131,7 @@ impl EventLoopManager {
103131

104132
let join_handle = get_runtime().spawn(async move {
105133
tx.send(()).unwrap();
106-
EventLoopThread::new(stop_flag_clone, poll_lock_clone, observers, grabbed_devices)
134+
EventLoopThread::new(stop_flag_clone, poll_lock_clone, observer, grabbed_devices)
107135
.start();
108136
});
109137

@@ -279,10 +307,6 @@ impl EventLoopManager {
279307
device.write_event(event_type, code, value)
280308
}
281309

282-
pub fn register_observer(&self, observer: EvdevObserver) {
283-
self.observers.write().unwrap().insert(observer);
284-
}
285-
286310
/// Get the paths to all the real (non uinput) connected devices.
287311
pub fn get_all_real_devices(&self) -> Result<Vec<PathBuf>, EvdevError> {
288312
let mut paths: Vec<PathBuf> = Vec::new();
@@ -323,21 +347,21 @@ impl EventLoopManager {
323347
struct EventLoopThread {
324348
stop_flag: Arc<AtomicBool>,
325349
poll: Arc<RwLock<Poll>>,
326-
observers: Arc<RwLock<Slab<EvdevObserver>>>,
350+
observer: EvdevObserver,
327351
grabbed_devices: Arc<RwLock<Slab<GrabbedDevice>>>,
328352
}
329353

330354
impl EventLoopThread {
331355
pub fn new(
332356
stop_flag: Arc<AtomicBool>,
333357
poll: Arc<RwLock<Poll>>,
334-
observers: Arc<RwLock<Slab<EvdevObserver>>>,
358+
observer: EvdevObserver,
335359
grabbed_devices: Arc<RwLock<Slab<GrabbedDevice>>>,
336360
) -> Self {
337361
EventLoopThread {
338362
stop_flag,
339363
poll,
340-
observers,
364+
observer,
341365
grabbed_devices,
342366
}
343367
}
@@ -401,7 +425,7 @@ impl EventLoopThread {
401425
flags = ReadFlag::NORMAL;
402426
// Keep this logging line. Debug/verbose events will be disabled in production.
403427
debug!("Evdev event: {:?}", input_event);
404-
self.process_observers(slab_key, &input_event, grabbed_device);
428+
self.process_event(slab_key, &input_event, grabbed_device);
405429
}
406430
Ok((ReadStatus::Sync, _event)) => {
407431
// Continue reading sync events
@@ -416,21 +440,15 @@ impl EventLoopThread {
416440
}
417441
}
418442

419-
fn process_observers(
443+
fn process_event(
420444
&self,
421445
device_id: usize,
422446
event: &InputEvent,
423447
grabbed_device: &GrabbedDevice,
424448
) {
425-
let mut consume = false;
426-
427-
for (_, observer) in self.observers.read().unwrap().iter() {
428-
if observer(device_id, &grabbed_device.device_id, event) {
429-
consume = true;
430-
}
431-
}
449+
let consumed = (self.observer)(device_id, &grabbed_device.device_id, event);
432450

433-
if !consume {
451+
if !consumed {
434452
let (event_type, event_code) = event_code_to_int(&event.event_code);
435453
grabbed_device
436454
.write_event(event_type, event_code, event.value)

evdev/src/main/rust/evdev_manager/jni/src/jni_bridge.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,11 @@ pub extern "system" fn Java_io_github_sds100_keymapper_sysbridge_service_BaseSys
5151
panic!("JNI observer already initialized");
5252
}
5353

54-
// Register the observer with the event loop
55-
EventLoopManager::get().register_observer(|device_id, device_identifier, event| {
54+
// Initialize and start the event loop with the observer
55+
EventLoopManager::init(|device_id, device_identifier, event| {
5656
get_jni_observer().on_event(device_id, device_identifier, event)
5757
});
5858

59-
// Start the event loop
6059
EventLoopManager::get()
6160
.start()
6261
.inspect_err(|e| error!("Failed to start event loop: {:?}", e))

0 commit comments

Comments
 (0)