narui_core/context/
args.rs

1use 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/// shout arg is a macro for not requiring the implementation of PartialEq on
35/// all args.
36#[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;