ferroui_xaml_interactivity/behaviors/
disposing_behavior.rs1use crate::{StyledElementBehaviorImpl, StyledElementBehaviorImplExt, StyledElementBehaviorOfT};
4use ferroui_base::reactive::IDisposable;
5use ferroui_base::{ferro_class, FerroObjectImpl, StyledElementImpl, TypeInfo};
6use std::cell::RefCell;
7use std::rc::Rc;
8
9#[repr(C)]
16pub struct DisposingBehavior {
17 base: StyledElementBehaviorOfT,
18 disposable: RefCell<Option<Rc<dyn IDisposable>>>,
19}
20
21ferro_class! {
22 DisposingBehavior: StyledElementBehaviorOfT, virtuals DisposingBehaviorImpl: StyledElementBehaviorImpl {
23 fn on_attached_override(this) -> Rc<dyn IDisposable>;
27 }
28}
29
30ferroui_base::ferro_impl_classes!(DisposingBehavior: FerroObjectImpl, StyledElementImpl);
31
32impl DisposingBehaviorImpl for DisposingBehavior {
33 fn on_attached_override(_this: &Self) -> Rc<dyn IDisposable> {
34 panic!("DisposingBehavior is abstract: 'on_attached_override' must be implemented by the deriving class")
35 }
36}
37
38ferroui_base::ferro_overrides! {
39 impl StyledElementBehaviorImpl for DisposingBehavior {
40 fn on_attached(this: &Self) {
41 Self::parent_on_attached(this);
42
43 let previous = this.disposable.borrow_mut().take();
44 if let Some(previous) = previous {
45 previous.dispose();
46 }
47 let disposable = this.on_attached_override();
48 *this.disposable.borrow_mut() = Some(disposable);
49 }
50
51 fn on_detaching(this: &Self) {
52 Self::parent_on_detaching(this);
53
54 let disposable = this.disposable.borrow_mut().take();
55 if let Some(disposable) = disposable {
56 disposable.dispose();
57 }
58 }
59 }
60}
61
62impl DisposingBehavior {
63 pub fn construct(associated_type: &'static TypeInfo) -> Self {
66 Self { base: StyledElementBehaviorOfT::construct(associated_type), disposable: RefCell::new(None) }
67 }
68}