ferroui_android/
application_lifetime.rs1use ferroui_base::logging::{LogArea, LogEventLevel, Logger};
2use ferroui_base::Ref;
3use ferroui_controls::application_lifetimes::{
4 IActivityApplicationLifetime, IApplicationLifetime, ISingleViewApplicationLifetime,
5};
6use ferroui_controls::Control;
7use std::any::Any;
8use std::cell::RefCell;
9use std::rc::Rc;
10
11#[derive(Default)]
14pub struct ApplicationLifetime {
15 main_view: RefCell<Option<Ref<Control>>>,
16 main_view_factory: RefCell<Option<Rc<dyn Fn() -> Ref<Control>>>>,
17}
18
19impl ApplicationLifetime {
20 pub fn new() -> Rc<Self> {
21 Rc::new(Self::default())
22 }
23}
24
25impl IApplicationLifetime for ApplicationLifetime {
26 fn as_any(&self) -> &dyn Any {
27 self
28 }
29
30 fn as_single_view_application_lifetime(&self) -> Option<&dyn ISingleViewApplicationLifetime> {
31 Some(self)
32 }
33
34 fn as_activity_application_lifetime(&self) -> Option<&dyn IActivityApplicationLifetime> {
35 Some(self)
36 }
37}
38
39impl IActivityApplicationLifetime for ApplicationLifetime {
40 fn main_view_factory(&self) -> Option<Rc<dyn Fn() -> Ref<Control>>> {
41 self.main_view_factory.borrow().clone()
42 }
43
44 fn set_main_view_factory(&self, value: Option<Rc<dyn Fn() -> Ref<Control>>>) {
45 let previous = self.main_view_factory.replace(value);
46 drop(previous);
47 }
48}
49
50impl ISingleViewApplicationLifetime for ApplicationLifetime {
51 fn main_view(&self) -> Option<Ref<Control>> {
52 self.main_view.borrow().clone()
53 }
54
55 fn set_main_view(&self, value: Option<Ref<Control>>) {
56 let previous = self.main_view.replace(value.clone());
57 drop(previous);
58
59 if let Some(logger) = Logger::try_get(LogEventLevel::Warning, LogArea::ANDROID_PLATFORM) {
60 logger.log(
61 None,
62 "ISingleViewApplicationLifetime.MainView is not fully supported on Android. \
63 Consider setting IActivityApplicationLifetime.MainViewFactory.",
64 );
65 }
66 match value {
67 Some(main_view) => self.set_main_view_factory(Some(Rc::new(move || main_view.clone()))),
68 None => self.set_main_view_factory(None),
69 }
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
77
78 #[test]
79 fn the_lifetime_is_a_single_view_and_an_activity_lifetime() {
80 let lifetime = ApplicationLifetime::new();
81 let lifetime: &dyn IApplicationLifetime = &*lifetime;
82
83 assert!(lifetime.as_single_view_application_lifetime().is_some());
84 assert!(lifetime.as_activity_application_lifetime().is_some());
85 assert!(lifetime.as_controlled_application_lifetime().is_none());
86 assert!(lifetime.as_classic_desktop_style_application_lifetime().is_none());
87 }
88
89 #[test]
90 fn a_lifetime_starts_without_a_view_and_without_a_factory() {
91 let lifetime = ApplicationLifetime::new();
92
93 assert!(lifetime.main_view().is_none());
94 assert!(lifetime.main_view_factory().is_none());
95 }
96
97 #[test]
98 fn clearing_the_main_view_clears_the_factory() {
99 let lifetime = ApplicationLifetime::new();
100 lifetime.set_main_view_factory(Some(Rc::new(|| panic!("not called"))));
101
102 lifetime.set_main_view(None);
103
104 assert!(lifetime.main_view_factory().is_none());
105 }
106}