polyhorn_core/
weak.rs

1use std::rc::{Rc, Weak as WeakRc};
2
3use super::{Instance, Link, Memory, Platform, Reference, State};
4
5/// This is a weak reference to an instance that can be converted into a link at
6/// request.
7pub 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}