1
0
Fork 0
forked from wry/wry

util: add generic event listener framework

This commit is contained in:
Julian Orth 2024-09-01 10:28:37 +02:00
parent 07b55e42c9
commit dbb9bd2299
2 changed files with 70 additions and 0 deletions

View file

@ -0,0 +1,69 @@
use {
crate::utils::linkedlist::{LinkedList, LinkedListIter, LinkedNode},
std::{
cell::Cell,
rc::{Rc, Weak},
},
};
pub struct EventSource<T: ?Sized> {
listeners: LinkedList<Weak<T>>,
on_attach: Cell<Option<Box<dyn FnOnce()>>>,
}
pub struct EventListener<T: ?Sized> {
link: LinkedNode<Weak<T>>,
}
impl<T: ?Sized> Default for EventSource<T> {
fn default() -> Self {
Self {
listeners: Default::default(),
on_attach: Default::default(),
}
}
}
impl<T: ?Sized> EventSource<T> {
pub fn iter(&self) -> EventSourceIter<T> {
EventSourceIter {
iter: self.listeners.iter(),
}
}
}
pub struct EventSourceIter<T: ?Sized> {
iter: LinkedListIter<Weak<T>>,
}
impl<T: ?Sized> Iterator for EventSourceIter<T> {
type Item = Rc<T>;
fn next(&mut self) -> Option<Self::Item> {
for weak in self.iter.by_ref() {
if let Some(t) = weak.upgrade() {
return Some(t);
}
}
None
}
}
impl<T: ?Sized> EventListener<T> {
pub fn new(t: Weak<T>) -> Self {
Self {
link: LinkedNode::detached(t),
}
}
pub fn attach(&self, source: &EventSource<T>) {
source.listeners.add_last_existing(&self.link);
if let Some(on_attach) = source.on_attach.take() {
on_attach();
}
}
pub fn detach(&self) {
self.link.detach();
}
}