narui_core/context/
args.rs1use crate::{Fragment, WidgetContext};
2use derivative::Derivative;
3
4use smallvec::SmallVec;
5use std::{any::Any, marker::PhantomData};
6
7#[derive(Debug, Derivative)]
8#[derivative(Default(bound = "", new = "true"))]
9pub struct ArgRef<T> {
10 marker: PhantomData<T>,
11}
12impl<T> Clone for ArgRef<T> {
13 fn clone(&self) -> Self { Self::new() }
14}
15impl<T> Copy for ArgRef<T> {}
16impl<T> ArgRef<T> {
17 pub unsafe fn parse<'a>(&self, any: &'a dyn Any) -> &'a T
18 where
19 T: 'static,
20 {
21 any.downcast_ref().expect("wrong type for argument")
22 }
23
24 pub fn for_value(_: &T) -> Self { Default::default() }
25}
26
27pub fn listen_args<'a>(
28 context: &'a mut WidgetContext,
29 key: &Fragment,
30) -> &'a SmallVec<[Box<dyn Any>; 8]> {
31 context.fragment_store.get_args(*key).as_ref().unwrap()
32}
33
34#[macro_export]
37macro_rules! shout_args_ {
38 ($context:expr, $idx:ident, $($values:expr,)*) => {
39 match $context.fragment_store.get_args_mut($idx) {
40 None => $context.fragment_store.set_args($idx, $crate::_macro_api::smallvec![$(Box::new($values) as _,)*]),
41 Some(old_values) => {
42 let mut idx = 0;
43 let mut any_changed = false;
44 #[allow(unused)]
45 fn constrain_type<T>(a: &mut T, b: &T) {}
46 $({
47 let old_value = &mut old_values[idx];
48 let old = old_value.downcast_mut().expect("wrong type for argument");
49 constrain_type(old, &$values);
50 if !$crate::_macro_api::all_eq!(&*old, &$values) {
51 *old = $values;
52 any_changed = true;
53 }
54 idx += 1;
55 })*
56 if any_changed {
57 $context.fragment_store.set_args_dirty($idx);
58 }
59 }
60 };
61 };
62}
63pub use shout_args_ as shout_args;