Created
October 9, 2023 17:19
-
-
Save PsichiX/0c7a99f80afd8827baeab42b968b206c to your computer and use it in GitHub Desktop.
View-Model usage test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const FOO_VIEW_MODEL: &str = "foo"; | |
const COUNTER_PROPERTY: &str = "counter"; | |
const FLAG_PROPERTY: &str = "flag"; | |
// view-model data type | |
struct Foo { | |
// can hold view-model value wrapper that implicitly notifies on mutation. | |
counter: ViewModelValue<usize>, | |
// or can hold raw notifiers to explicitly notify. | |
flag: bool, | |
flag_notifier: ViewModelNotifier, | |
} | |
impl Foo { | |
fn toggle(&mut self) { | |
self.flag = !self.flag; | |
self.flag_notifier.notify(); | |
} | |
} | |
#[test] | |
fn test_view_model() { | |
let a = WidgetId::from_str("a:root/a").unwrap(); | |
let b = WidgetId::from_str("b:root/b").unwrap(); | |
let mut collection = ViewModelCollection::default(); | |
// create new view-model and add it to collection. | |
// `produce` method allows to setup notifiers as we construct view-model. | |
let mut view_model = ViewModel::produce(|properties| Foo { | |
counter: ViewModelValue::new(0, properties.notifier(COUNTER_PROPERTY)), | |
flag: false, | |
flag_notifier: properties.notifier(FLAG_PROPERTY), | |
}); | |
// handle to view-model data we can use to share around. | |
// it stays alive as long as its view-model object. | |
let mut handle = view_model.lazy::<Foo>().unwrap(); | |
collection.insert(FOO_VIEW_MODEL.to_owned(), view_model); | |
// unbound properties won't trigger notification until we bind widgets to them. | |
assert_eq!(collection.consume_notified_common_root().is_valid(), false); | |
handle.write().unwrap().toggle(); | |
assert_eq!(collection.consume_notified_common_root().is_valid(), false); | |
assert!(collection | |
.get_mut(FOO_VIEW_MODEL) | |
.unwrap() | |
.properties | |
.bindings(COUNTER_PROPERTY) | |
.unwrap() | |
.is_notified()); | |
assert!(collection | |
.get_mut(FOO_VIEW_MODEL) | |
.unwrap() | |
.properties | |
.bindings(FLAG_PROPERTY) | |
.unwrap() | |
.is_notified()); | |
// bind widget to properties. | |
// whenever property gets notified, its widgets will rebuild. | |
collection | |
.get_mut(FOO_VIEW_MODEL) | |
.unwrap() | |
.properties | |
.bindings(COUNTER_PROPERTY) | |
.unwrap() | |
.bind(a); | |
collection | |
.get_mut(FOO_VIEW_MODEL) | |
.unwrap() | |
.properties | |
.bindings(FLAG_PROPERTY) | |
.unwrap() | |
.bind(b); | |
// once we bind properties, notification will be triggered. | |
assert_eq!( | |
collection.consume_notified_common_root().path(), | |
Some("root") | |
); | |
// automatically notify on view-model value mutation. | |
*handle.write().unwrap().counter += 1; | |
assert_eq!( | |
collection.consume_notified_common_root().path(), | |
Some("root/a"), | |
); | |
// proxy notify via view-model method call. | |
handle.write().unwrap().toggle(); | |
assert_eq!( | |
collection.consume_notified_common_root().path(), | |
Some("root/b"), | |
); | |
// rebuilding widgets tree will occur always from common root of notified widgets. | |
*handle.write().unwrap().counter += 1; | |
handle.write().unwrap().toggle(); | |
assert_eq!( | |
collection.consume_notified_common_root().path(), | |
Some("root"), | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment