util: add generic event listener framework
This commit is contained in:
parent
07b55e42c9
commit
dbb9bd2299
2 changed files with 70 additions and 0 deletions
|
|
@ -14,6 +14,7 @@ pub mod copyhashmap;
|
||||||
pub mod debug_fn;
|
pub mod debug_fn;
|
||||||
pub mod double_click_state;
|
pub mod double_click_state;
|
||||||
pub mod errorfmt;
|
pub mod errorfmt;
|
||||||
|
pub mod event_listener;
|
||||||
pub mod fdcloser;
|
pub mod fdcloser;
|
||||||
pub mod gfx_api_ext;
|
pub mod gfx_api_ext;
|
||||||
pub mod hash_map_ext;
|
pub mod hash_map_ext;
|
||||||
|
|
|
||||||
69
src/utils/event_listener.rs
Normal file
69
src/utils/event_listener.rs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue