ferroui_diagnostics/diagnostics/view_models/
reactive_extensions.rs1use ferroui_base::data::model::INotifyPropertyChanged;
4use ferroui_base::reactive::{Disposable, IObservable, IObserver, Observable};
5use std::rc::Rc;
6
7pub struct ReactiveExtensions;
9
10impl ReactiveExtensions {
11 pub fn get_observable<TOwner, TValue>(
20 vm: &Rc<TOwner>,
21 property_name: &'static str,
22 property: impl Fn(&TOwner) -> TValue + 'static,
23 fire_immediately: bool,
24 ) -> Rc<dyn IObservable<TValue>>
25 where
26 TOwner: INotifyPropertyChanged + ?Sized + 'static,
27 TValue: 'static,
28 {
29 let vm = vm.clone();
30 let property: Rc<dyn Fn(&TOwner) -> TValue> = Rc::new(property);
31 Observable::create(move |o: Rc<dyn IObserver<TValue>>| {
32 let fire = {
33 let vm = vm.clone();
34 let property = property.clone();
35 Rc::new(move || o.on_next(property(&*vm)))
36 };
37
38 if fire_immediately {
39 fire();
40 }
41
42 let on_property_changed: Rc<dyn Fn(&str)> = Rc::new(move |e: &str| {
43 if e == property_name {
44 fire();
45 }
46 });
47
48 let token = vm.property_changed().add(on_property_changed);
49
50 let vm = vm.clone();
51 Disposable::create(move || {
52 vm.property_changed().remove(token);
53 })
54 })
55 }
56}