1use std::rc::{Rc, Weak as WeakRc};
2
3use super::{Instance, Link, Memory, Platform, Reference, State};
4
5pub struct Weak<P>
8where
9 P: Platform + ?Sized,
10{
11 instance: WeakRc<Instance<P>>,
12}
13
14impl<P> Weak<P>
15where
16 P: Platform + ?Sized,
17{
18 pub fn new(instance: &Rc<Instance<P>>) -> Weak<P> {
19 Weak {
20 instance: Rc::downgrade(instance),
21 }
22 }
23
24 pub fn with_link<F, T>(&self, op: F) -> Option<T>
25 where
26 F: FnOnce(&WeakLink<P>) -> T,
27 {
28 if let Some(instance) = self.instance.upgrade() {
29 Some(op(&WeakLink {
30 instance: &instance,
31 memory: &instance.memory(),
32 }))
33 } else {
34 None
35 }
36 }
37}
38
39impl<P> Clone for Weak<P>
40where
41 P: Platform + ?Sized,
42{
43 fn clone(&self) -> Self {
44 Weak {
45 instance: self.instance.clone(),
46 }
47 }
48}
49
50pub struct WeakLink<'a, P>
51where
52 P: Platform + ?Sized,
53{
54 instance: &'a Rc<Instance<P>>,
55 memory: &'a Memory,
56}
57
58impl<'a, P> WeakLink<'a, P>
59where
60 P: Platform + ?Sized,
61{
62 pub fn new(instance: &'a Rc<Instance<P>>, memory: &'a Memory) -> WeakLink<'a, P> {
63 WeakLink { instance, memory }
64 }
65}
66
67impl<'a, P> Link for WeakLink<'a, P>
68where
69 P: Platform + ?Sized,
70{
71 type Platform = P;
72
73 fn instance(&self) -> &Rc<Instance<Self::Platform>> {
74 self.instance
75 }
76
77 fn memory(&self) -> &Memory {
78 self.memory
79 }
80}
81
82pub struct WeakReference<P, T>(Weak<P>, Reference<T>)
83where
84 P: Platform + ?Sized,
85 T: 'static;
86
87impl<P, T> WeakReference<P, T>
88where
89 P: Platform + ?Sized,
90 T: 'static,
91{
92 pub fn new(weak: Weak<P>, reference: Reference<T>) -> WeakReference<P, T> {
93 WeakReference(weak, reference)
94 }
95
96 pub fn replace(&self, value: impl Into<T>) -> Option<T> {
97 self.0.with_link(|link| self.1.replace(link, value.into()))
98 }
99
100 pub fn apply<F, O>(&self, op: F) -> Option<O>
101 where
102 F: FnOnce(&mut T) -> O,
103 {
104 self.0.with_link(|link| self.1.apply(link, op))
105 }
106
107 pub fn with_link<F, O>(&self, op: F) -> Option<O>
108 where
109 F: FnOnce(&WeakLink<P>) -> O,
110 {
111 self.0.with_link(op)
112 }
113
114 pub fn queue_rerender(&self) -> bool {
115 self.0.with_link(|link| link.queue_rerender()).is_some()
116 }
117}
118
119impl<P, T> Clone for WeakReference<P, T>
120where
121 P: Platform + ?Sized,
122 T: 'static,
123{
124 fn clone(&self) -> Self {
125 WeakReference(self.0.clone(), self.1)
126 }
127}
128
129pub struct WeakState<P, T>(Weak<P>, State<T>)
130where
131 P: Platform + ?Sized,
132 T: 'static;
133
134impl<P, T> WeakState<P, T>
135where
136 P: Platform + ?Sized,
137 T: 'static,
138{
139 pub fn new(weak: Weak<P>, state: State<T>) -> WeakState<P, T> {
140 WeakState(weak, state)
141 }
142
143 pub fn replace(&self, value: T) -> Option<T> {
144 self.0.with_link(|link| self.1.replace(link, value))
145 }
146}
147
148impl<P, T> Clone for WeakState<P, T>
149where
150 P: Platform + ?Sized,
151 T: 'static,
152{
153 fn clone(&self) -> Self {
154 WeakState(self.0.clone(), self.1)
155 }
156}