1use std::sync::{Arc, Weak};
2
3use super::{util::VarData, *};
4
5#[derive(Clone)]
9pub struct ArcVar<T: VarValue>(Arc<VarData>, PhantomData<T>);
10
11#[derive(Clone)]
13pub struct WeakArcVar<T: VarValue>(Weak<VarData>, PhantomData<T>);
14
15pub fn var<T: VarValue>(value: T) -> ArcVar<T> {
17 ArcVar(Arc::new(VarData::new(value)), PhantomData)
18}
19
20pub fn var_from<T: VarValue, U: Into<T>>(source: U) -> ArcVar<T> {
22 var(source.into())
23}
24
25pub fn var_default<T: VarValue + Default>() -> ArcVar<T> {
27 var(T::default())
28}
29
30impl<T: VarValue> WeakArcVar<T> {
31 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
350pub fn state_var() -> ArcVar<bool> {
355 var(false)
356}
357
358pub fn getter_var<T: VarValue + Default>() -> ArcVar<T> {
364 var(T::default())
365}