event-listener: add LazyEventSource
This commit is contained in:
parent
ce30901093
commit
8fc9ead21e
3 changed files with 82 additions and 2 deletions
|
|
@ -1,11 +1,28 @@
|
|||
use {
|
||||
crate::utils::linkedlist::{LinkedList, LinkedListIter, LinkedNode},
|
||||
crate::{
|
||||
state::State,
|
||||
utils::{
|
||||
linkedlist::{LinkedList, LinkedListIter, LinkedNode},
|
||||
queue::AsyncQueue,
|
||||
},
|
||||
},
|
||||
std::{
|
||||
cell::Cell,
|
||||
ops::Deref,
|
||||
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> {
|
||||
listeners: LinkedList<Weak<T>>,
|
||||
on_attach: Cell<Option<Box<dyn FnOnce()>>>,
|
||||
|
|
@ -15,6 +32,21 @@ pub struct EventListener<T: ?Sized> {
|
|||
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> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
@ -39,6 +71,10 @@ impl<T: ?Sized> EventSource<T> {
|
|||
self.listeners.is_not_empty()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.listeners.is_empty()
|
||||
}
|
||||
|
||||
pub fn on_attach(&self, f: Box<dyn FnOnce()>) {
|
||||
self.on_attach.set(Some(f));
|
||||
}
|
||||
|
|
@ -83,3 +119,39 @@ impl<T: ?Sized> EventListener<T> {
|
|||
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