fui_core/observable/
event.rs1use std::cell::RefCell;
2use std::rc::Rc;
3use std::rc::Weak;
4
5use crate::Callback;
6
7pub struct EventSubscription {
17 _callbacks: Vec<Rc<dyn CallbackObject>>,
18}
19
20impl EventSubscription {
21 pub fn from_many(event_subscriptions: Vec<EventSubscription>) -> Self {
22 let mut callbacks = Vec::new();
23 for mut subscription in event_subscriptions.into_iter() {
24 callbacks.append(&mut subscription._callbacks);
25 }
26 EventSubscription {
27 _callbacks: callbacks,
28 }
29 }
30}
31
32impl Drop for EventSubscription {
33 fn drop(&mut self) {}
34}
35
36pub trait CallbackObject {}
37impl<A> CallbackObject for Callback<A> {}
38
39pub struct Event<A> {
40 callbacks: RefCell<Vec<Weak<Callback<A>>>>,
41}
42
43impl<A: 'static + Clone> Event<A> {
44 pub fn new() -> Self {
45 Event {
46 callbacks: RefCell::new(Vec::new()),
47 }
48 }
49
50 pub fn subscribe<F: 'static + FnMut(A)>(&mut self, f: F) -> EventSubscription {
51 let mut callback = Callback::<A>::empty();
52 callback.set_sync(f);
53 let rc_callback = Rc::new(callback);
54 let weak_callback = Rc::downgrade(&rc_callback);
55 self.callbacks.borrow_mut().push(weak_callback);
56
57 EventSubscription {
58 _callbacks: vec![rc_callback],
59 }
60 }
61
62 pub fn emit(&self, args: A) {
63 let mut cleanup = false;
64
65 for weak_callback in self.callbacks.borrow().iter() {
66 match weak_callback.upgrade() {
67 Some(callback) => {
68 callback.emit(args.clone());
69 }
70 _ => {
71 cleanup = true;
72 }
73 }
74 }
75
76 if cleanup {
77 self.callbacks.borrow_mut().retain(|weak_callback| {
78 let got_ref = weak_callback.clone().upgrade();
79 match got_ref {
80 None => false,
81 _ => true,
82 }
83 });
84 }
85 }
86}