telar_reactive_core/
signal.rs1use std::marker::PhantomData;
2
3use crate::runtime::{self, SignalId};
4
5fn read_with<T: 'static, R>(id: SignalId, f: impl FnOnce(&T) -> R) -> R {
6 runtime::track_signal(id);
7 runtime::with_signal_value::<T, R>(id, f)
8}
9
10fn peek_with<T: 'static, R>(id: SignalId, f: impl FnOnce(&T) -> R) -> R {
11 runtime::with_signal_value::<T, R>(id, f)
12}
13
14pub struct ReadSignal<T: 'static> {
15 pub(crate) id: SignalId,
16 _marker: PhantomData<T>,
17}
18
19impl<T: 'static> Clone for ReadSignal<T> {
20 fn clone(&self) -> Self {
21 runtime::clone_signal(self.id);
22 ReadSignal {
23 id: self.id,
24 _marker: PhantomData,
25 }
26 }
27}
28
29impl<T: 'static> Drop for ReadSignal<T> {
30 fn drop(&mut self) {
31 runtime::drop_signal(self.id);
32 }
33}
34
35impl<T: Clone + 'static> ReadSignal<T> {
36 pub fn get(&self) -> T {
37 read_with::<T, T>(self.id, |v| v.clone())
38 }
39
40 pub fn peek(&self) -> T {
41 peek_with::<T, T>(self.id, |v| v.clone())
42 }
43}
44
45impl<T: 'static> ReadSignal<T> {
46 pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> R {
47 read_with::<T, R>(self.id, f)
48 }
49}
50
51pub struct RwSignal<T: 'static> {
52 pub(crate) id: SignalId,
53 _marker: PhantomData<T>,
54}
55
56impl<T: 'static> Clone for RwSignal<T> {
57 fn clone(&self) -> Self {
58 runtime::clone_signal(self.id);
59 RwSignal {
60 id: self.id,
61 _marker: PhantomData,
62 }
63 }
64}
65
66impl<T: 'static> Drop for RwSignal<T> {
67 fn drop(&mut self) {
68 runtime::drop_signal(self.id);
69 }
70}
71
72impl<T: 'static> RwSignal<T> {
73 pub fn set(&self, value: T) {
74 runtime::set_signal_value(self.id, value);
75 runtime::notify_signal(self.id);
76 }
77
78 pub fn update(&self, f: impl FnOnce(&mut T)) {
79 runtime::update_signal_value::<T>(self.id, f);
80 runtime::notify_signal(self.id);
81 }
82
83 pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> R {
84 read_with::<T, R>(self.id, f)
85 }
86
87 pub fn peek_with<R>(&self, f: impl FnOnce(&T) -> R) -> R {
90 peek_with::<T, R>(self.id, f)
91 }
92
93 pub fn read_only(&self) -> ReadSignal<T> {
94 runtime::clone_signal(self.id);
95 ReadSignal {
96 id: self.id,
97 _marker: PhantomData,
98 }
99 }
100}
101
102impl<T: Clone + 'static> RwSignal<T> {
103 pub fn get(&self) -> T {
104 read_with::<T, T>(self.id, |v| v.clone())
105 }
106
107 pub fn peek(&self) -> T {
108 peek_with::<T, T>(self.id, |v| v.clone())
109 }
110}
111
112impl RwSignal<bool> {
113 pub fn toggle(&self) {
115 self.update(|v| *v = !*v);
116 }
117}
118
119pub fn signal<T: 'static>(value: T) -> RwSignal<T> {
120 let id = runtime::create_signal_storage(value, 1);
121 RwSignal {
122 id,
123 _marker: PhantomData,
124 }
125}