Skip to main content

ferroui_linuxframebuffer/input/
raw_event_grouping_threading_helper.rs

1//! Groups raw events that arrive faster than the UI thread handles them
2//! (the port of `RawEventGroupingThreadingHelper.cs`).
3//!
4//! The reference queues from the thread of a backend. Raw events are
5//! objects of the UI thread here, so the queue is one of that thread; the
6//! order of events and the single post per burst are the reference's.
7
8use crate::raw_event_grouping::{RawEvent, RawEventGrouper};
9use ferroui_base::threading::{Dispatcher, DispatcherPriority};
10use std::cell::RefCell;
11use std::collections::VecDeque;
12use std::rc::Rc;
13
14struct State {
15    grouper: RawEventGrouper,
16    raw_queue: RefCell<VecDeque<RawEvent>>,
17}
18
19pub struct RawEventGroupingThreadingHelper {
20    state: Rc<State>,
21}
22
23impl RawEventGroupingThreadingHelper {
24    pub fn new(event_callback: impl Fn(RawEvent) + 'static) -> Self {
25        Self {
26            state: Rc::new(State {
27                grouper: RawEventGrouper::new(event_callback, None),
28                raw_queue: RefCell::default(),
29            }),
30        }
31    }
32
33    fn queue_handler(state: &State) {
34        loop {
35            let next = state.raw_queue.borrow_mut().pop_front();
36            let Some(next) = next else {
37                break;
38            };
39            state.grouper.handle_event(next);
40        }
41    }
42
43    pub fn on_event(&self, args: RawEvent) {
44        let mut raw_queue = self.state.raw_queue.borrow_mut();
45        raw_queue.push_back(args);
46        if raw_queue.len() == 1 {
47            let state = self.state.clone();
48            Dispatcher::ui_thread().post_local(move || Self::queue_handler(&state), DispatcherPriority::INPUT);
49        }
50    }
51
52    pub fn dispose(&self) {
53        let state = self.state.clone();
54        Dispatcher::ui_thread().post_local(
55            move || state.grouper.dispose(),
56            DispatcherPriority::from_value(DispatcherPriority::INPUT.value() + 1),
57        );
58    }
59}