euv_core/reactive/signal/
impl.rs1use crate::*;
2
3impl<T> Signal<T>
5where
6 T: Clone + PartialEq + 'static,
7{
8 pub fn create(value: T) -> Self {
18 let signal_inner: Rc<RefCell<SignalInner<T>>> =
19 Rc::new(RefCell::new(SignalInner::new(value, Vec::new(), true)));
20 let addr: usize = Rc::as_ptr(&signal_inner) as usize;
21 signal_inner_registry_mut().insert(addr, signal_inner as Rc<dyn Any>);
22 let mut signal: Signal<T> = Signal::new(0, std::marker::PhantomData);
23 signal.set_inner(addr);
24 signal
25 }
26
27 pub(crate) fn get_inner_addr(&self) -> usize {
33 self.get_inner()
34 }
35
36 pub fn get(&self) -> T {
42 let rc: Rc<RefCell<SignalInner<T>>> = get_signal_inner_rc(self.get_inner());
43 rc.borrow().get_value().clone()
44 }
45
46 pub fn try_get(&self) -> Option<T> {
53 let rc: Rc<RefCell<SignalInner<T>>> = get_signal_inner_rc(self.get_inner());
54 Some(rc.borrow().get_value().clone())
55 }
56
57 pub fn subscribe<F>(&self, callback: F)
63 where
64 F: FnMut() + 'static,
65 {
66 let rc: Rc<RefCell<SignalInner<T>>> = get_signal_inner_rc(self.get_inner());
67 rc.borrow_mut().get_mut_listeners().push(Box::new(callback));
68 }
69
70 pub fn replace_subscribe<F>(&self, callback: F)
79 where
80 F: FnMut() + 'static,
81 {
82 let rc: Rc<RefCell<SignalInner<T>>> = get_signal_inner_rc(self.get_inner());
83 let mut inner: RefMut<SignalInner<T>> = rc.borrow_mut();
84 let listeners: &mut Vec<Box<dyn FnMut()>> = inner.get_mut_listeners();
85 listeners.clear();
86 listeners.push(Box::new(callback));
87 }
88
89 pub fn clear_listeners(&self) {
92 let rc: Rc<RefCell<SignalInner<T>>> = get_signal_inner_rc(self.get_inner());
93 let mut inner: RefMut<SignalInner<T>> = rc.borrow_mut();
94 inner.set_alive(false);
95 inner.get_mut_listeners().clear();
96 }
97
98 pub fn set(&self, value: T) {
104 let rc: Rc<RefCell<SignalInner<T>>> = get_signal_inner_rc(self.get_inner());
105 let mut listeners: Vec<Box<dyn FnMut()>> = Vec::new();
106 {
107 let mut inner: RefMut<SignalInner<T>> = rc.borrow_mut();
108 if !inner.get_alive() {
109 return;
110 }
111 if *inner.get_value() == value {
112 return;
113 }
114 inner.set_value(value);
115 swap(inner.get_mut_listeners(), &mut listeners);
116 }
117 for listener in listeners.iter_mut() {
118 listener();
119 }
120 {
121 let mut inner: RefMut<SignalInner<T>> = rc.borrow_mut();
122 swap(inner.get_mut_listeners(), &mut listeners);
123 }
124 schedule_signal_update();
125 }
126
127 pub fn set_silent(&self, value: T) {
134 let rc: Rc<RefCell<SignalInner<T>>> = get_signal_inner_rc(self.get_inner());
135 let mut listeners: Vec<Box<dyn FnMut()>> = Vec::new();
136 {
137 let mut inner: RefMut<SignalInner<T>> = rc.borrow_mut();
138 if !inner.get_alive() {
139 return;
140 }
141 if *inner.get_value() == value {
142 return;
143 }
144 inner.set_value(value);
145 swap(inner.get_mut_listeners(), &mut listeners);
146 }
147 for listener in listeners.iter_mut() {
148 listener();
149 }
150 {
151 let mut inner: RefMut<SignalInner<T>> = rc.borrow_mut();
152 swap(inner.get_mut_listeners(), &mut listeners);
153 }
154 }
155
156 pub fn try_set(&self, value: T) -> bool {
166 let rc: Rc<RefCell<SignalInner<T>>> = get_signal_inner_rc(self.get_inner());
167 let mut listeners: Vec<Box<dyn FnMut()>> = Vec::new();
168 {
169 let mut inner: RefMut<SignalInner<T>> = rc.borrow_mut();
170 if !inner.get_alive() {
171 return false;
172 }
173 if *inner.get_value() == value {
174 return false;
175 }
176 inner.set_value(value);
177 swap(inner.get_mut_listeners(), &mut listeners);
178 }
179 for listener in listeners.iter_mut() {
180 listener();
181 }
182 {
183 let mut inner: RefMut<SignalInner<T>> = rc.borrow_mut();
184 swap(inner.get_mut_listeners(), &mut listeners);
185 }
186 schedule_signal_update();
187 true
188 }
189}
190
191impl<T> Deref for Signal<T>
193where
194 T: Clone + PartialEq + 'static,
195{
196 type Target = T;
197
198 fn deref(&self) -> &Self::Target {
199 panic!("Signal does not support direct dereference; use .get() instead");
200 }
201}
202
203impl<T> DerefMut for Signal<T>
205where
206 T: Clone + PartialEq + 'static,
207{
208 fn deref_mut(&mut self) -> &mut Self::Target {
209 panic!("Signal does not support direct dereference; use .set() instead");
210 }
211}
212
213impl<T> Clone for Signal<T>
215where
216 T: Clone + PartialEq + 'static,
217{
218 fn clone(&self) -> Self {
219 *self
220 }
221}
222
223impl<T> Copy for Signal<T> where T: Clone + PartialEq + 'static {}
225
226unsafe impl<T> Sync for SignalCell<T> where T: Clone + PartialEq + 'static {}
229
230impl<T> SignalCell<T>
232where
233 T: Clone + PartialEq + 'static,
234{
235 pub const fn empty() -> Self {
241 Self {
242 inner: UnsafeCell::new(None),
243 }
244 }
245
246 pub fn set(&self, signal: Signal<T>) {
256 unsafe {
257 let ptr: &mut Option<Signal<T>> = &mut *self.get_inner().get();
258 if ptr.is_some() {
259 panic!("SignalCell::set called on an already-initialized cell");
260 }
261 *ptr = Some(signal);
262 }
263 }
264
265 pub fn get(&self) -> Signal<T> {
275 unsafe {
276 let ptr: &Option<Signal<T>> = &*self.get_inner().get();
277 match ptr {
278 Some(signal) => *signal,
279 None => panic!("SignalCell::get called on an uninitialized cell"),
280 }
281 }
282 }
283}
284
285impl<T> Default for SignalCell<T>
287where
288 T: Clone + PartialEq + 'static,
289{
290 fn default() -> Self {
291 Self {
292 inner: UnsafeCell::new(None),
293 }
294 }
295}
296
297unsafe impl Sync for SignalInnerRegistryCell {}