zng_var/
arc.rs

1use std::sync::{Arc, Weak};
2
3use super::{util::VarData, *};
4
5/// Reference counted read/write variable.
6///
7/// This is the primary variable type, it can be instantiated using the [`var`] and [`var_from`] functions.
8#[derive(Clone)]
9pub struct ArcVar<T: VarValue>(Arc<VarData>, PhantomData<T>);
10
11/// Weak reference to a [`ArcVar<T>`].
12#[derive(Clone)]
13pub struct WeakArcVar<T: VarValue>(Weak<VarData>, PhantomData<T>);
14
15/// New ref counted read/write variable with initial `value`.
16pub fn var<T: VarValue>(value: T) -> ArcVar<T> {
17    ArcVar(Arc::new(VarData::new(value)), PhantomData)
18}
19
20/// New ref counted read/write variable with initial value converted from `source`.
21pub fn var_from<T: VarValue, U: Into<T>>(source: U) -> ArcVar<T> {
22    var(source.into())
23}
24
25/// New ref counted read/write variable with default initial value.
26pub fn var_default<T: VarValue + Default>() -> ArcVar<T> {
27    var(T::default())
28}
29
30impl<T: VarValue> WeakArcVar<T> {
31    /// New reference to nothing.
32    pub fn new() -> Self {
33        Self(Weak::new(), PhantomData)
34    }
35}
36
37impl<T: VarValue> Default for WeakArcVar<T> {
38    fn default() -> Self {
39        Self::new()
40    }
41}
42
43impl<T: VarValue> crate::private::Sealed for ArcVar<T> {}
44
45impl<T: VarValue> crate::private::Sealed for WeakArcVar<T> {}
46
47impl<T: VarValue> AnyVar for ArcVar<T> {
48    fn clone_any(&self) -> BoxedAnyVar {
49        Box::new(self.clone())
50    }
51
52    fn as_any(&self) -> &dyn Any {
53        self
54    }
55
56    fn as_unboxed_any(&self) -> &dyn Any {
57        self
58    }
59
60    fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
61        let me: BoxedVar<T> = self;
62        Box::new(me)
63    }
64
65    fn var_type_id(&self) -> TypeId {
66        TypeId::of::<T>()
67    }
68
69    fn get_any(&self) -> Box<dyn AnyVarValue> {
70        Box::new(self.get())
71    }
72
73    fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
74        self.with(|v| read(v))
75    }
76
77    fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
78        self.with_new(|v| read(v)).is_some()
79    }
80
81    fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
82        self.modify(var_set_any(value));
83        Ok(())
84    }
85
86    fn last_update(&self) -> VarUpdateId {
87        self.0.last_update()
88    }
89
90    fn is_contextual(&self) -> bool {
91        false
92    }
93
94    fn capabilities(&self) -> VarCapability {
95        VarCapability::MODIFY
96    }
97
98    fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
99        self.0.push_hook(pos_modify_action)
100    }
101
102    fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
103        self.0.push_animation_hook(handler)
104    }
105
106    fn strong_count(&self) -> usize {
107        Arc::strong_count(&self.0)
108    }
109
110    fn weak_count(&self) -> usize {
111        Arc::weak_count(&self.0)
112    }
113
114    fn actual_var_any(&self) -> BoxedAnyVar {
115        Box::new(self.clone())
116    }
117
118    fn downgrade_any(&self) -> BoxedAnyWeakVar {
119        Box::new(WeakArcVar(Arc::downgrade(&self.0), PhantomData::<T>))
120    }
121
122    fn is_animating(&self) -> bool {
123        self.0.is_animating()
124    }
125
126    fn modify_importance(&self) -> usize {
127        self.0.modify_importance()
128    }
129
130    fn var_ptr(&self) -> VarPtr {
131        VarPtr::new_arc(&self.0)
132    }
133
134    fn get_debug(&self) -> Txt {
135        self.with(var_debug)
136    }
137
138    fn update(&self) -> Result<(), VarIsReadOnlyError> {
139        Var::modify(self, var_update)
140    }
141
142    fn map_debug(&self) -> BoxedVar<Txt> {
143        Var::map(self, var_debug).boxed()
144    }
145}
146
147impl<T: VarValue> AnyWeakVar for WeakArcVar<T> {
148    fn clone_any(&self) -> BoxedAnyWeakVar {
149        Box::new(self.clone())
150    }
151
152    fn strong_count(&self) -> usize {
153        self.0.strong_count()
154    }
155
156    fn weak_count(&self) -> usize {
157        self.0.weak_count()
158    }
159
160    fn upgrade_any(&self) -> Option<BoxedAnyVar> {
161        self.0.upgrade().map(|rc| Box::new(ArcVar(rc, PhantomData::<T>)) as _)
162    }
163
164    fn as_any(&self) -> &dyn Any {
165        self
166    }
167}
168
169impl<T: VarValue> IntoVar<T> for ArcVar<T> {
170    type Var = Self;
171
172    fn into_var(self) -> Self::Var {
173        self
174    }
175}
176
177impl<T: VarValue> ArcVar<T> {
178    #[cfg(feature = "dyn_closure")]
179    fn modify_impl(&self, modify: Box<dyn FnOnce(&mut VarModify<T>) + Send + 'static>) -> Result<(), VarIsReadOnlyError> {
180        let me = self.clone();
181        VARS.schedule_update(
182            Box::new(move || {
183                me.0.apply_modify(modify);
184            }),
185            std::any::type_name::<T>(),
186        );
187        Ok(())
188    }
189
190    #[cfg(not(feature = "dyn_closure"))]
191    fn modify_impl(&self, modify: impl FnOnce(&mut VarModify<T>) + Send + 'static) -> Result<(), VarIsReadOnlyError> {
192        let me = self.clone();
193        VARS.schedule_update(
194            Box::new(move || {
195                me.0.apply_modify(modify);
196            }),
197            std::any::type_name::<T>(),
198        );
199        Ok(())
200    }
201
202    impl_infallible_write! {
203        for<T>
204    }
205}
206
207impl<T: VarValue> Var<T> for ArcVar<T> {
208    type ReadOnly = types::ReadOnlyVar<T, Self>;
209
210    type ActualVar = Self;
211
212    type Downgrade = WeakArcVar<T>;
213
214    type Map<O: VarValue> = ReadOnlyArcVar<O>;
215    type MapBidi<O: VarValue> = ArcVar<O>;
216
217    type FlatMap<O: VarValue, V: Var<O>> = types::ArcFlatMapVar<O, V>;
218
219    type FilterMap<O: VarValue> = ReadOnlyArcVar<O>;
220    type FilterMapBidi<O: VarValue> = ArcVar<O>;
221
222    type MapRef<O: VarValue> = types::MapRef<T, O, Self>;
223    type MapRefBidi<O: VarValue> = types::MapRefBidi<T, O, Self>;
224
225    type Easing = ReadOnlyArcVar<T>;
226
227    fn with<R, F>(&self, read: F) -> R
228    where
229        F: FnOnce(&T) -> R,
230    {
231        self.0.with(read)
232    }
233
234    fn modify<F>(&self, modify: F) -> Result<(), VarIsReadOnlyError>
235    where
236        F: FnOnce(&mut VarModify<T>) + Send + 'static,
237    {
238        #[cfg(feature = "dyn_closure")]
239        let modify: Box<dyn FnOnce(&mut VarModify<T>) + Send + 'static> = Box::new(modify);
240        self.modify_impl(modify)
241    }
242
243    fn actual_var(self) -> Self {
244        self
245    }
246
247    fn downgrade(&self) -> WeakArcVar<T> {
248        WeakArcVar(Arc::downgrade(&self.0), PhantomData::<T>)
249    }
250
251    fn into_value(self) -> T {
252        match Arc::try_unwrap(self.0) {
253            Ok(data) => data.into_value(),
254            Err(rc) => Self(rc, PhantomData).get(),
255        }
256    }
257
258    fn read_only(&self) -> Self::ReadOnly {
259        types::ReadOnlyVar::new(self.clone())
260    }
261
262    fn map<O, M>(&self, map: M) -> Self::Map<O>
263    where
264        O: VarValue,
265        M: FnMut(&T) -> O + Send + 'static,
266    {
267        var_map(self, map)
268    }
269
270    fn map_bidi<O, M, B>(&self, map: M, map_back: B) -> Self::MapBidi<O>
271    where
272        O: VarValue,
273        M: FnMut(&T) -> O + Send + 'static,
274        B: FnMut(&O) -> T + Send + 'static,
275    {
276        var_map_bidi(self, map, map_back)
277    }
278
279    fn flat_map<O, V, M>(&self, map: M) -> Self::FlatMap<O, V>
280    where
281        O: VarValue,
282        V: Var<O>,
283        M: FnMut(&T) -> V + Send + 'static,
284    {
285        var_flat_map(self, map)
286    }
287
288    fn filter_map<O, M, I>(&self, map: M, fallback: I) -> Self::FilterMap<O>
289    where
290        O: VarValue,
291        M: FnMut(&T) -> Option<O> + Send + 'static,
292        I: Fn() -> O + Send + Sync + 'static,
293    {
294        var_filter_map(self, map, fallback)
295    }
296
297    fn filter_map_bidi<O, M, B, I>(&self, map: M, map_back: B, fallback: I) -> Self::FilterMapBidi<O>
298    where
299        O: VarValue,
300        M: FnMut(&T) -> Option<O> + Send + 'static,
301        B: FnMut(&O) -> Option<T> + Send + 'static,
302        I: Fn() -> O + Send + Sync + 'static,
303    {
304        var_filter_map_bidi(self, map, map_back, fallback)
305    }
306
307    fn map_ref<O, M>(&self, map: M) -> Self::MapRef<O>
308    where
309        O: VarValue,
310        M: Fn(&T) -> &O + Send + Sync + 'static,
311    {
312        var_map_ref(self, map)
313    }
314
315    fn map_ref_bidi<O, M, B>(&self, map: M, map_mut: B) -> Self::MapRefBidi<O>
316    where
317        O: VarValue,
318        M: Fn(&T) -> &O + Send + Sync + 'static,
319        B: Fn(&mut T) -> &mut O + Send + Sync + 'static,
320    {
321        var_map_ref_bidi(self, map, map_mut)
322    }
323
324    fn easing<F>(&self, duration: Duration, easing: F) -> Self::Easing
325    where
326        T: Transitionable,
327        F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
328    {
329        var_easing(self, duration, easing)
330    }
331
332    fn easing_with<F, S>(&self, duration: Duration, easing: F, sampler: S) -> Self::Easing
333    where
334        T: Transitionable,
335        F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
336        S: Fn(&animation::Transition<T>, EasingStep) -> T + Send + Sync + 'static,
337    {
338        var_easing_with(self, duration, easing, sampler)
339    }
340}
341
342impl<T: VarValue> WeakVar<T> for WeakArcVar<T> {
343    type Upgrade = ArcVar<T>;
344
345    fn upgrade(&self) -> Option<ArcVar<T>> {
346        self.0.upgrade().map(|rc| ArcVar(rc, PhantomData))
347    }
348}
349
350/// Variable for state properties (`is_*`, `has_*`).
351///
352/// State variables are `bool` probes that are set by the property, they are created automatically
353/// by the property default when used in `when` expressions, but can be created manually.
354pub fn state_var() -> ArcVar<bool> {
355    var(false)
356}
357
358/// Variable for getter properties (`get_*`, `actual_*`).
359///
360/// Getter variables are inited with a default value that is overridden by the property on node init and updated
361/// by the property when the internal state they track changes. They are created automatically by the property
362/// default when used in `when` expressions, but can be created manually.
363pub fn getter_var<T: VarValue + Default>() -> ArcVar<T> {
364    var(T::default())
365}