event-listener: add LazyEventSource
This commit is contained in:
parent
ce30901093
commit
8fc9ead21e
3 changed files with 82 additions and 2 deletions
|
|
@ -68,6 +68,7 @@ use {
|
||||||
clone3::ensure_reaper,
|
clone3::ensure_reaper,
|
||||||
clonecell::CloneCell,
|
clonecell::CloneCell,
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
|
event_listener::handle_lazy_event_sources,
|
||||||
fdcloser::FdCloser,
|
fdcloser::FdCloser,
|
||||||
nice::{did_elevate_scheduler, elevate_scheduler},
|
nice::{did_elevate_scheduler, elevate_scheduler},
|
||||||
numcell::NumCell,
|
numcell::NumCell,
|
||||||
|
|
@ -377,6 +378,7 @@ fn start_compositor2(
|
||||||
copy_device_registry: Rc::new(CopyDeviceRegistry::new(&ring, &engine, &eventfd_cache)),
|
copy_device_registry: Rc::new(CopyDeviceRegistry::new(&ring, &engine, &eventfd_cache)),
|
||||||
supports_presentation_feedback: Default::default(),
|
supports_presentation_feedback: Default::default(),
|
||||||
eventfd_cache,
|
eventfd_cache,
|
||||||
|
lazy_event_sources: Default::default(),
|
||||||
});
|
});
|
||||||
state.tracker.register(ClientId::from_raw(0));
|
state.tracker.register(ClientId::from_raw(0));
|
||||||
create_dummy_output(&state);
|
create_dummy_output(&state);
|
||||||
|
|
@ -577,6 +579,10 @@ fn start_global_event_handlers(state: &Rc<State>) -> Vec<SpawnedFuture<()>> {
|
||||||
Phase::PostLayout,
|
Phase::PostLayout,
|
||||||
handle_xdg_surface_configure_events(state.clone()),
|
handle_xdg_surface_configure_events(state.clone()),
|
||||||
),
|
),
|
||||||
|
eng.spawn(
|
||||||
|
"lazy event sources",
|
||||||
|
handle_lazy_event_sources(state.clone()),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ use {
|
||||||
clonecell::CloneCell,
|
clonecell::CloneCell,
|
||||||
copyhashmap::CopyHashMap,
|
copyhashmap::CopyHashMap,
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
event_listener::{EventListener, EventSource},
|
event_listener::{EventListener, EventSource, LazyEventSources},
|
||||||
fdcloser::FdCloser,
|
fdcloser::FdCloser,
|
||||||
hash_map_ext::HashMapExt,
|
hash_map_ext::HashMapExt,
|
||||||
linkedlist::LinkedList,
|
linkedlist::LinkedList,
|
||||||
|
|
@ -290,6 +290,7 @@ pub struct State {
|
||||||
pub copy_device_registry: Rc<CopyDeviceRegistry>,
|
pub copy_device_registry: Rc<CopyDeviceRegistry>,
|
||||||
pub supports_presentation_feedback: Cell<bool>,
|
pub supports_presentation_feedback: Cell<bool>,
|
||||||
pub eventfd_cache: Rc<EventfdCache>,
|
pub eventfd_cache: Rc<EventfdCache>,
|
||||||
|
pub lazy_event_sources: Rc<LazyEventSources>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Drop for State {
|
// impl Drop for State {
|
||||||
|
|
@ -1128,6 +1129,7 @@ impl State {
|
||||||
self.cpu_worker.clear();
|
self.cpu_worker.clear();
|
||||||
self.wait_for_syncobj.clear();
|
self.wait_for_syncobj.clear();
|
||||||
self.xdg_surface_configure_events.clear();
|
self.xdg_surface_configure_events.clear();
|
||||||
|
self.lazy_event_sources.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_toplevel_id(&self, id: ToplevelIdentifier) {
|
pub fn remove_toplevel_id(&self, id: ToplevelIdentifier) {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,28 @@
|
||||||
use {
|
use {
|
||||||
crate::utils::linkedlist::{LinkedList, LinkedListIter, LinkedNode},
|
crate::{
|
||||||
|
state::State,
|
||||||
|
utils::{
|
||||||
|
linkedlist::{LinkedList, LinkedListIter, LinkedNode},
|
||||||
|
queue::AsyncQueue,
|
||||||
|
},
|
||||||
|
},
|
||||||
std::{
|
std::{
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
|
ops::Deref,
|
||||||
rc::{Rc, Weak},
|
rc::{Rc, Weak},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub async fn handle_lazy_event_sources(state: Rc<State>) {
|
||||||
|
loop {
|
||||||
|
let source = state.lazy_event_sources.queue.pop().await;
|
||||||
|
source.queued.set(false);
|
||||||
|
for listener in source.listeners.iter() {
|
||||||
|
listener.triggered();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct EventSource<T: ?Sized> {
|
pub struct EventSource<T: ?Sized> {
|
||||||
listeners: LinkedList<Weak<T>>,
|
listeners: LinkedList<Weak<T>>,
|
||||||
on_attach: Cell<Option<Box<dyn FnOnce()>>>,
|
on_attach: Cell<Option<Box<dyn FnOnce()>>>,
|
||||||
|
|
@ -15,6 +32,21 @@ pub struct EventListener<T: ?Sized> {
|
||||||
link: LinkedNode<Weak<T>>,
|
link: LinkedNode<Weak<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct LazyEventSources {
|
||||||
|
queue: AsyncQueue<Rc<LazyEventSource>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LazyEventSourceListener {
|
||||||
|
fn triggered(self: Rc<Self>);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LazyEventSource {
|
||||||
|
sources: Rc<LazyEventSources>,
|
||||||
|
queued: Cell<bool>,
|
||||||
|
listeners: EventSource<dyn LazyEventSourceListener>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> Default for EventSource<T> {
|
impl<T: ?Sized> Default for EventSource<T> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -39,6 +71,10 @@ impl<T: ?Sized> EventSource<T> {
|
||||||
self.listeners.is_not_empty()
|
self.listeners.is_not_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.listeners.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn on_attach(&self, f: Box<dyn FnOnce()>) {
|
pub fn on_attach(&self, f: Box<dyn FnOnce()>) {
|
||||||
self.on_attach.set(Some(f));
|
self.on_attach.set(Some(f));
|
||||||
}
|
}
|
||||||
|
|
@ -83,3 +119,39 @@ impl<T: ?Sized> EventListener<T> {
|
||||||
self.link.upgrade()
|
self.link.upgrade()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deref for LazyEventSource {
|
||||||
|
type Target = EventSource<dyn LazyEventSourceListener>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.listeners
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LazyEventSource {
|
||||||
|
#[expect(dead_code)]
|
||||||
|
pub fn trigger(self: &Rc<Self>) {
|
||||||
|
if self.listeners.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if self.queued.replace(true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.sources.queue.push(self.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LazyEventSources {
|
||||||
|
#[expect(dead_code)]
|
||||||
|
pub fn create_source(self: &Rc<Self>) -> Rc<LazyEventSource> {
|
||||||
|
Rc::new(LazyEventSource {
|
||||||
|
sources: self.clone(),
|
||||||
|
queued: Default::default(),
|
||||||
|
listeners: Default::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&self) {
|
||||||
|
self.queue.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue