1use std::any::TypeId;
2
3use super::*;
4
5pub type BoxedVar<T> = Box<dyn VarBoxed<T>>;
7
8pub type BoxedWeakVar<T> = Box<dyn WeakVarBoxed<T>>;
10
11pub type BoxedAnyVar = Box<dyn AnyVar>;
13
14pub type BoxedAnyWeakVar = Box<dyn AnyWeakVar>;
16
17impl<T: VarValue> Clone for BoxedWeakVar<T> {
18 fn clone(&self) -> Self {
19 self.clone_boxed()
20 }
21}
22
23impl Clone for BoxedAnyVar {
24 fn clone(&self) -> Self {
25 self.clone_any()
26 }
27}
28
29impl Clone for BoxedAnyWeakVar {
30 fn clone(&self) -> Self {
31 self.clone_any()
32 }
33}
34
35impl crate::private::Sealed for Box<dyn AnyVar> {}
36
37impl AnyVar for Box<dyn AnyVar> {
38 fn clone_any(&self) -> BoxedAnyVar {
39 (**self).clone_any()
40 }
41
42 fn as_any(&self) -> &dyn Any {
43 (**self).as_any()
44 }
45
46 fn as_unboxed_any(&self) -> &dyn Any {
47 (**self).as_unboxed_any()
48 }
49
50 fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
51 self
52 }
53
54 fn var_type_id(&self) -> TypeId {
55 (**self).var_type_id()
56 }
57
58 fn get_any(&self) -> Box<dyn AnyVarValue> {
59 (**self).get_any()
60 }
61
62 fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
63 (**self).with_any(read)
64 }
65
66 fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
67 (**self).with_new_any(read)
68 }
69
70 fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
71 (**self).set_any(value)
72 }
73
74 fn last_update(&self) -> VarUpdateId {
75 (**self).last_update()
76 }
77
78 fn is_contextual(&self) -> bool {
79 (**self).is_contextual()
80 }
81
82 fn capabilities(&self) -> VarCapability {
83 (**self).capabilities()
84 }
85
86 fn is_animating(&self) -> bool {
87 (**self).is_animating()
88 }
89
90 fn modify_importance(&self) -> usize {
91 (**self).modify_importance()
92 }
93
94 fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
95 (**self).hook_any(pos_modify_action)
96 }
97
98 fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
99 (**self).hook_animation_stop(handler)
100 }
101
102 fn strong_count(&self) -> usize {
103 (**self).strong_count()
104 }
105
106 fn weak_count(&self) -> usize {
107 (**self).weak_count()
108 }
109
110 fn actual_var_any(&self) -> BoxedAnyVar {
111 (**self).actual_var_any()
112 }
113
114 fn downgrade_any(&self) -> BoxedAnyWeakVar {
115 (**self).downgrade_any()
116 }
117
118 fn var_ptr(&self) -> VarPtr {
119 (**self).var_ptr()
120 }
121
122 fn get_debug(&self) -> Txt {
123 (**self).get_debug()
124 }
125
126 fn update(&self) -> Result<(), VarIsReadOnlyError> {
127 (**self).update()
128 }
129
130 fn map_debug(&self) -> BoxedVar<Txt> {
131 (**self).map_debug()
132 }
133}
134
135#[doc(hidden)]
136pub trait VarBoxed<T: VarValue>: AnyVar {
137 fn clone_boxed(&self) -> BoxedVar<T>;
138 fn with_boxed(&self, read: &mut dyn FnMut(&T));
139 fn modify_boxed(&self, modify: Box<dyn FnOnce(&mut VarModify<T>) + Send>) -> Result<(), VarIsReadOnlyError>;
140 fn actual_var_boxed(self: Box<Self>) -> BoxedVar<T>;
141 fn downgrade_boxed(&self) -> BoxedWeakVar<T>;
142 fn read_only_boxed(&self) -> BoxedVar<T>;
143 fn boxed_any_boxed(self: Box<Self>) -> BoxedAnyVar;
144}
145impl<T: VarValue, V: Var<T>> VarBoxed<T> for V {
146 fn clone_boxed(&self) -> BoxedVar<T> {
147 self.clone().boxed()
148 }
149
150 fn with_boxed(&self, read: &mut dyn FnMut(&T)) {
151 self.with(read)
152 }
153
154 fn modify_boxed(&self, modify: Box<dyn FnOnce(&mut VarModify<T>) + Send>) -> Result<(), VarIsReadOnlyError> {
155 self.modify(modify)
156 }
157
158 fn actual_var_boxed(self: Box<Self>) -> BoxedVar<T> {
159 (*self).actual_var().boxed()
160 }
161
162 fn downgrade_boxed(&self) -> BoxedWeakVar<T> {
163 self.downgrade().boxed()
164 }
165
166 fn read_only_boxed(&self) -> BoxedVar<T> {
167 self.read_only().boxed()
168 }
169
170 fn boxed_any_boxed(self: Box<Self>) -> BoxedAnyVar {
171 self
172 }
173}
174
175#[doc(hidden)]
176pub trait WeakVarBoxed<T: VarValue>: AnyWeakVar {
177 fn clone_boxed(&self) -> BoxedWeakVar<T>;
178 fn upgrade_boxed(&self) -> Option<BoxedVar<T>>;
179}
180impl<T: VarValue, W: WeakVar<T>> WeakVarBoxed<T> for W {
181 fn clone_boxed(&self) -> BoxedWeakVar<T> {
182 self.clone().boxed()
183 }
184
185 fn upgrade_boxed(&self) -> Option<BoxedVar<T>> {
186 self.upgrade().map(Var::boxed)
187 }
188}
189
190impl<T: VarValue> crate::private::Sealed for BoxedWeakVar<T> {}
191
192impl<T: VarValue> AnyWeakVar for BoxedWeakVar<T> {
193 fn clone_any(&self) -> BoxedAnyWeakVar {
194 (**self).clone_any()
195 }
196
197 fn strong_count(&self) -> usize {
198 (**self).strong_count()
199 }
200
201 fn weak_count(&self) -> usize {
202 (**self).weak_count()
203 }
204
205 fn upgrade_any(&self) -> Option<BoxedAnyVar> {
206 (**self).upgrade_any()
207 }
208
209 fn as_any(&self) -> &dyn Any {
210 self
211 }
212}
213impl<T: VarValue> WeakVar<T> for BoxedWeakVar<T> {
214 type Upgrade = BoxedVar<T>;
215
216 fn upgrade(&self) -> Option<Self::Upgrade> {
217 (**self).upgrade_boxed()
218 }
219}
220
221impl<T: VarValue> crate::private::Sealed for BoxedVar<T> {}
222
223impl<T: VarValue> Clone for BoxedVar<T> {
224 fn clone(&self) -> Self {
225 (**self).clone_boxed()
226 }
227}
228
229impl<T: VarValue> AnyVar for BoxedVar<T> {
230 fn clone_any(&self) -> BoxedAnyVar {
231 (**self).clone_any()
232 }
233
234 fn as_any(&self) -> &dyn Any {
235 self
236 }
237
238 fn as_unboxed_any(&self) -> &dyn Any {
239 (**self).as_unboxed_any()
240 }
241
242 fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
243 self
244 }
245
246 fn var_type_id(&self) -> TypeId {
247 (**self).var_type_id()
248 }
249
250 fn get_any(&self) -> Box<dyn AnyVarValue> {
251 (**self).get_any()
252 }
253
254 fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
255 (**self).with_any(read)
256 }
257
258 fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
259 (**self).with_new_any(read)
260 }
261
262 fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
263 (**self).set_any(value)
264 }
265
266 fn last_update(&self) -> VarUpdateId {
267 (**self).last_update()
268 }
269
270 fn is_contextual(&self) -> bool {
271 (**self).is_contextual()
272 }
273
274 fn capabilities(&self) -> VarCapability {
275 (**self).capabilities()
276 }
277
278 fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
279 (**self).hook_any(pos_modify_action)
280 }
281
282 fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
283 (**self).hook_animation_stop(handler)
284 }
285
286 fn strong_count(&self) -> usize {
287 (**self).strong_count()
288 }
289
290 fn weak_count(&self) -> usize {
291 (**self).weak_count()
292 }
293
294 fn actual_var_any(&self) -> BoxedAnyVar {
295 (**self).actual_var_any()
296 }
297
298 fn downgrade_any(&self) -> BoxedAnyWeakVar {
299 (**self).downgrade_any()
300 }
301
302 fn is_animating(&self) -> bool {
303 (**self).is_animating()
304 }
305
306 fn modify_importance(&self) -> usize {
307 (**self).modify_importance()
308 }
309
310 fn var_ptr(&self) -> VarPtr {
311 (**self).var_ptr()
312 }
313
314 fn get_debug(&self) -> Txt {
315 (**self).get_debug()
316 }
317
318 fn update(&self) -> Result<(), VarIsReadOnlyError> {
319 (**self).update()
320 }
321
322 fn map_debug(&self) -> BoxedVar<Txt> {
323 (**self).map_debug()
324 }
325}
326
327impl<T: VarValue> IntoVar<T> for BoxedVar<T> {
328 type Var = Self;
329
330 fn into_var(self) -> Self::Var {
331 self
332 }
333}
334
335impl<T: VarValue> Var<T> for BoxedVar<T> {
336 type ReadOnly = BoxedVar<T>;
337
338 type ActualVar = BoxedVar<T>;
339
340 type Downgrade = BoxedWeakVar<T>;
341
342 type Map<O: VarValue> = BoxedVar<O>;
343 type MapBidi<O: VarValue> = BoxedVar<O>;
344
345 type FlatMap<O: VarValue, V: Var<O>> = BoxedVar<O>;
346
347 type FilterMap<O: VarValue> = BoxedVar<O>;
348 type FilterMapBidi<O: VarValue> = BoxedVar<O>;
349
350 type MapRef<O: VarValue> = BoxedVar<O>;
351 type MapRefBidi<O: VarValue> = BoxedVar<O>;
352
353 type Easing = BoxedVar<T>;
354
355 fn with<R, F>(&self, read: F) -> R
356 where
357 F: FnOnce(&T) -> R,
358 {
359 #[cfg(feature = "dyn_closure")]
360 let read: Box<dyn FnOnce(&T) -> R> = Box::new(read);
361 boxed_var_with(self, read)
362 }
363
364 fn modify<F>(&self, modify: F) -> Result<(), VarIsReadOnlyError>
365 where
366 F: FnOnce(&mut VarModify<T>) + Send + 'static,
367 {
368 let modify = Box::new(modify);
369 (**self).modify_boxed(modify)
370 }
371
372 fn boxed(self) -> BoxedVar<T> {
373 self
374 }
375
376 fn boxed_any(self) -> BoxedAnyVar
377 where
378 Self: Sized,
379 {
380 self.clone_any()
382 }
383
384 fn actual_var(self) -> BoxedVar<T> {
385 self.actual_var_boxed()
386 }
387
388 fn downgrade(&self) -> BoxedWeakVar<T> {
389 (**self).downgrade_boxed()
390 }
391
392 fn into_value(self) -> T {
393 self.get()
394 }
395
396 fn read_only(&self) -> Self::ReadOnly {
397 if self.capabilities().is_always_read_only() {
398 self.clone()
399 } else {
400 (**self).read_only_boxed()
401 }
402 }
403
404 fn map<O, M>(&self, map: M) -> Self::Map<O>
405 where
406 O: VarValue,
407 M: FnMut(&T) -> O + Send + 'static,
408 {
409 var_map_mixed(self, map)
410 }
411
412 fn map_bidi<O, M, B>(&self, map: M, map_back: B) -> Self::MapBidi<O>
413 where
414 O: VarValue,
415 M: FnMut(&T) -> O + Send + 'static,
416 B: FnMut(&O) -> T + Send + 'static,
417 {
418 var_map_bidi_mixed(self, map, map_back)
419 }
420
421 fn flat_map<O, V, M>(&self, map: M) -> Self::FlatMap<O, V>
422 where
423 O: VarValue,
424 V: Var<O>,
425 M: FnMut(&T) -> V + Send + 'static,
426 {
427 var_flat_map_mixed(self, map)
428 }
429
430 fn filter_map<O, M, I>(&self, map: M, fallback: I) -> Self::FilterMap<O>
431 where
432 O: VarValue,
433 M: FnMut(&T) -> Option<O> + Send + 'static,
434 I: Fn() -> O + Send + Sync + 'static,
435 {
436 var_filter_map_mixed(self, map, fallback)
437 }
438
439 fn filter_map_bidi<O, M, B, I>(&self, map: M, map_back: B, fallback: I) -> Self::FilterMapBidi<O>
440 where
441 O: VarValue,
442 M: FnMut(&T) -> Option<O> + Send + 'static,
443 B: FnMut(&O) -> Option<T> + Send + 'static,
444 I: Fn() -> O + Send + Sync + 'static,
445 {
446 var_filter_map_bidi_mixed(self, map, map_back, fallback)
447 }
448
449 fn map_ref<O, M>(&self, map: M) -> Self::MapRef<O>
450 where
451 O: VarValue,
452 M: Fn(&T) -> &O + Send + Sync + 'static,
453 {
454 var_map_ref(self, map).boxed()
455 }
456
457 fn map_ref_bidi<O, M, B>(&self, map: M, map_mut: B) -> Self::MapRefBidi<O>
458 where
459 O: VarValue,
460 M: Fn(&T) -> &O + Send + Sync + 'static,
461 B: Fn(&mut T) -> &mut O + Send + Sync + 'static,
462 {
463 var_map_ref_bidi(self, map, map_mut).boxed()
464 }
465
466 fn easing<F>(&self, duration: Duration, easing: F) -> Self::Easing
467 where
468 T: Transitionable,
469 F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
470 {
471 var_easing_mixed(self, duration, easing)
472 }
473
474 fn easing_with<F, S>(&self, duration: Duration, easing: F, sampler: S) -> Self::Easing
475 where
476 T: Transitionable,
477 F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
478 S: Fn(&animation::Transition<T>, EasingStep) -> T + Send + Sync + 'static,
479 {
480 var_easing_with_mixed(self, duration, easing, sampler)
481 }
482}
483
484fn boxed_var_with<T: VarValue, R, F>(var: &BoxedVar<T>, read: F) -> R
485where
486 F: FnOnce(&T) -> R,
487{
488 let mut read = Some(read);
489 let mut result = None;
490 (**var).with_boxed(&mut |var_value| {
491 let read = read.take().unwrap();
492 result = Some(read(var_value));
493 });
494 result.take().unwrap()
495}