maycoon_core/signal/
mod.rs1use crate::app::context::AppContext;
2use crate::reference::Ref;
3use crate::signal::fixed::FixedSignal;
4use crate::signal::map::MapSignal;
5use std::sync::Arc;
6
7pub mod fixed;
9
10pub mod memoized;
12
13pub mod state;
15
16pub mod map;
18
19pub mod eval;
21
22pub type Listener<T> = Box<dyn Fn(Ref<T>)>;
24
25pub type ArcSignal<T> = Arc<dyn Signal<T>>;
27
28pub trait Signal<T: 'static>: 'static {
36 fn get(&self) -> Ref<T>;
38
39 fn set_value(&self, value: T);
43
44 fn listen(&mut self, listener: Listener<T>);
46
47 fn notify(&self);
50
51 fn set(&self, value: T) {
53 self.set_value(value);
54 self.notify();
55 }
56
57 fn maybe(self: &Arc<Self>) -> MaybeSignal<T>
59 where
60 Self: Sized,
61 {
62 MaybeSignal::signal(self.clone())
63 }
64
65 fn map<U: 'static>(self: Arc<Self>, map: impl Fn(Ref<T>) -> Ref<U> + 'static) -> MaybeSignal<U>
69 where
70 Self: Sized,
71 {
72 self.maybe().map(map)
73 }
74
75 fn hook(self, context: &AppContext) -> Arc<Self>
79 where
80 Self: Sized,
81 {
82 context.use_signal(self)
83 }
84}
85
86#[derive(Clone)]
88pub enum MaybeSignal<T> {
89 Signal(ArcSignal<T>),
91 Value(Arc<T>),
93}
94
95impl<T: 'static> MaybeSignal<T> {
96 pub fn signal(signal: ArcSignal<T>) -> Self {
98 Self::Signal(signal)
99 }
100
101 pub fn value(value: T) -> Self {
103 Self::Value(Arc::new(value))
104 }
105
106 pub fn get(&self) -> Ref<T> {
111 match self {
112 MaybeSignal::Signal(signal) => signal.get(),
113 MaybeSignal::Value(value) => Ref::Arc(value.clone()),
114 }
115 }
116
117 pub fn into_signal(self) -> ArcSignal<T> {
121 match self {
122 MaybeSignal::Signal(signal) => signal,
123 MaybeSignal::Value(value) => {
124 Arc::new(FixedSignal::new(Arc::into_inner(value).unwrap()))
125 },
126 }
127 }
128
129 pub fn as_signal(&self) -> Option<ArcSignal<T>> {
131 match self {
132 MaybeSignal::Signal(signal) => Some(signal.clone()),
133 _ => None,
134 }
135 }
136
137 pub fn map<U: 'static>(self, map: impl Fn(Ref<T>) -> Ref<U> + 'static) -> MaybeSignal<U> {
141 let signal = self.into_signal();
142
143 MaybeSignal::signal(Arc::new(MapSignal::new(signal, map)))
144 }
145}
146
147impl<T: Default + 'static> Default for MaybeSignal<T> {
148 fn default() -> Self {
149 Self::value(T::default())
150 }
151}
152
153impl<T: 'static> From<T> for MaybeSignal<T> {
154 fn from(value: T) -> Self {
155 Self::value(value)
156 }
157}
158
159impl<T: 'static> From<ArcSignal<T>> for MaybeSignal<T> {
160 fn from(signal: ArcSignal<T>) -> Self {
161 Self::signal(signal)
162 }
163}
164
165impl<'a, T: 'static> From<&'a ArcSignal<T>> for MaybeSignal<T> {
166 fn from(value: &'a ArcSignal<T>) -> Self {
167 Self::signal(value.clone())
168 }
169}