1#![allow(dead_code)]
2
3use std::sync::atomic::{AtomicBool, Ordering};
4use std::sync::Arc;
5
6use parking_lot::RwLock;
7
8type FateFn<T> = dyn Fn() -> T + Send + Sync + 'static;
9
10pub trait FateTrait: Send + Sync {
11 fn is_dirty(&self) -> bool;
12 fn set_dirty(&self);
13 fn add_dependent(&self, dependent: Box<dyn FateTrait>);
14 fn remove_dependent(&self, dependent: Box<dyn FateTrait>);
15 fn get_id(&self) -> usize;
16}
17
18enum Binding<T> {
19 Value(T),
20 Expression(Box<FateFn<T>>),
21}
22
23impl<T: Default> Default for Binding<T> {
24 fn default() -> Self {
25 Self::Value(T::default())
26 }
27}
28
29#[derive(Default)]
30struct FateDependencies {
31 dependencies: Vec<Box<dyn FateTrait>>,
32 dependents: Vec<Box<dyn FateTrait>>,
33}
34
35#[derive(Default, Clone)]
36pub struct Fate<T: Clone> {
37 cached_value: Arc<RwLock<T>>,
38 dirty: Arc<AtomicBool>,
39 dependencies: Arc<RwLock<FateDependencies>>,
40 data: Arc<RwLock<Binding<T>>>,
41}
42
43impl<T: 'static + Clone + Send + Sync> FateTrait for Fate<T> {
44 fn is_dirty(&self) -> bool {
45 self.dirty.load(Ordering::Acquire)
46 }
47
48 fn set_dirty(&self) {
49 self.dirty.store(true, Ordering::Release);
50 let data = self.dependencies.read();
51 for dependent in &data.dependents {
52 dependent.set_dirty();
53 }
54 }
55
56 fn add_dependent(&self, dependent: Box<dyn FateTrait>) {
57 let mut data = self.dependencies.write();
58 data.dependents.push(dependent);
59 }
60
61 fn remove_dependent(&self, dependent: Box<dyn FateTrait>) {
62 let mut data = self.dependencies.write();
63 let index = data
64 .dependents
65 .iter()
66 .position(|dep| dep.get_id() == dependent.get_id());
67 if let Some(index) = index {
68 data.dependents.remove(index);
69 }
70 }
71
72 fn get_id(&self) -> usize {
73 Arc::as_ptr(&self.dependencies) as usize
74 }
75}
76
77impl<T: 'static + Clone + Send + Sync> Fate<T> {
78 pub fn get(&self) -> T {
79 if self.is_dirty() {
80 let data = self.data.write();
81 let result = match &*data {
82 Binding::Value(value) => value.clone(),
83 Binding::Expression(expression) => expression(),
84 };
85 let mut cached_value = self.cached_value.write();
86 *cached_value = result.clone();
87 self.dirty.store(false, Ordering::Release);
88 result
89 } else {
90 self.cached_value.read().clone()
91 }
92 }
93
94 pub fn by_ref(&self, ref_fn: impl FnOnce(&T)) {
95 let data = self.data.read();
96 if let Binding::Value(value) = &*data {
97 ref_fn(value);
98 }
99 }
100
101 pub fn by_ref_mut(&self, mut_ref_fn: impl FnOnce(&mut T)) {
102 let mut dirtied = false;
103 {
104 let mut data = self.data.write();
105 if let Binding::Value(value) = &mut *data {
106 mut_ref_fn(value);
107
108 dirtied = true;
109 }
110 }
111 if dirtied {
112 self.set_dirty();
113 }
114 }
115
116 pub fn bind_value(&self, value: T) {
117 {
118 let mut data = self.data.write();
119 *data = Binding::Value(value);
120 }
121 self.set_dirty();
122 }
123
124 pub fn bind_expression(
125 &self,
126 expression: Box<FateFn<T>>,
127 dependencies: Vec<Box<dyn FateTrait>>,
128 ) {
129 self.set_dependencies(dependencies);
130 {
131 let mut data = self.data.write();
132 *data = Binding::Expression(expression);
133 }
134 self.set_dirty();
135 }
136
137 pub fn from_value(value: T) -> Fate<T> {
138 Fate {
139 cached_value: Arc::new(RwLock::new(value.clone())),
140 dirty: Arc::new(AtomicBool::new(false)),
141 data: Arc::new(RwLock::new(Binding::Value(value))),
142 dependencies: Arc::new(RwLock::new(FateDependencies {
143 dependencies: vec![],
144 dependents: vec![],
145 })),
146 }
147 }
148
149 pub fn from_expression(
150 expression: Box<FateFn<T>>,
151 dependencies: Vec<Box<dyn FateTrait>>,
152 ) -> Fate<T> {
153 let result = Fate {
154 cached_value: Arc::new(RwLock::new(expression())),
155 dirty: Arc::new(AtomicBool::new(false)),
156 data: Arc::new(RwLock::new(Binding::Expression(expression))),
157 dependencies: Arc::new(RwLock::new(FateDependencies {
158 dependencies: vec![],
159 dependents: vec![],
160 })),
161 };
162 result.set_dependencies(dependencies);
163 result
164 }
165
166 pub fn create_dependent_clone(&self) -> Self {
188 let self_clone = self.clone();
189 let dependent_clone = Fate::from_expression(
190 Box::new(move || {
191 let value = self_clone.get();
192 value
193 }),
194 vec![Box::new(self.clone())],
195 );
196 dependent_clone
197 }
198
199 fn clear_dependencies(&self) {
200 self.remove_all_dependencies();
201 let mut data = self.dependencies.write();
202 data.dependencies.clear();
203 }
204
205 fn remove_all_dependencies(&self) {
206 let data = self.dependencies.read();
207 for dependency in &data.dependencies {
208 dependency.remove_dependent(Box::new(self.clone()));
209 }
210 }
211
212 fn set_dependencies(&self, dependencies: Vec<Box<dyn FateTrait>>) {
213 self.remove_all_dependencies();
214 let mut data = self.dependencies.write();
215 data.dependencies = dependencies;
216 for dependency in &data.dependencies {
217 dependency.add_dependent(Box::new(self.clone()));
218 }
219 }
220}
221
222#[cfg(test)]
223mod tests {
224 use std::thread;
225
226 use fates_macro::fate;
227
228 use super::Fate;
229 use crate::FateTrait;
230
231 #[test]
232 fn simple() {
233 let a = Fate::from_value(3);
234 let b = Fate::from_value(5);
235 let a_clone = a.clone();
236 let b_clone = b.clone();
237 let c = Fate::from_expression(
238 Box::new(move || a_clone.get() + b_clone.get()),
239 vec![Box::new(a.clone()), Box::new(b.clone())],
240 );
241 assert_eq!(c.get(), 8);
242 b.bind_value(100);
243 assert_eq!(c.get(), 103);
244 }
245
246 #[test]
247 fn less_simple() {
248 let a = Fate::from_value(10);
249 let b = Fate::from_value(23);
250 let a_clone = a.clone();
251 let b_clone = b.clone();
252 let c = Fate::from_expression(
253 Box::new(move || a_clone.get() + b_clone.get() * b_clone.get()),
254 vec![Box::new(a.clone()), Box::new(b.clone())],
255 );
256 assert_eq!(c.get(), 10 + 23 * 23);
257 b.bind_value(113);
258 assert_eq!(c.get(), 10 + 113 * 113);
259
260 let c_clone = c.clone();
261 let a_clone = a.clone();
262 let d = Fate::from_expression(
263 Box::new(move || c_clone.get() * a_clone.get()),
264 vec![Box::new(c.clone()), Box::new(a.clone())],
265 );
266
267 assert_eq!(d.get(), (10 + 113 * 113) * 10);
268
269 let a_clone = a.clone();
270 let b_clone = b.clone();
271 let e = Fate::from_value(2);
272 let e_clone = e.clone();
273 c.bind_expression(
274 Box::new(move || a_clone.get() * b_clone.get() / e_clone.get()),
275 vec![
276 Box::new(a.clone()),
277 Box::new(b.clone()),
278 Box::new(e.clone()),
279 ],
280 );
281 assert_eq!(c.get(), 10 * 113 / 2);
282 }
283
284 #[test]
285 fn chain() {
286 fate! {
287 [a, b]
288 let a = "a".to_string();
289 let b = "b".to_string() + &a;
290 let c = "c".to_string() + &b;
291 }
292
293 assert_eq!(c.get(), "cba");
294 a.bind_value("c".to_string());
295 assert_eq!(c.get(), "cbc");
296 }
297
298 fn circular_reference() {
299 let a = Fate::from_value(3);
300 let b = Fate::from_value(5);
301 let a_clone = a.clone();
302 let b_clone = b.clone();
303 let c = Fate::from_expression(
304 Box::new(move || a_clone.get() + b_clone.get()),
305 vec![Box::new(a.clone()), Box::new(b.clone())],
306 );
307 let a_clone = a.clone();
308 let c_clone = c.clone();
309 b.bind_expression(
310 Box::new(move || a_clone.get() + c_clone.get()),
311 vec![Box::new(a.clone()), Box::new(c.clone())],
312 );
313 }
314
315 #[test]
316 fn macro_simple_test() {
317 let a = 5;
318 let b = a * 5;
319 let c = a * b;
320 fate! {
321 [a2, b2]
322 let a2 = 5;
323 let b2 = a2 * 5;
324 let c2 = a2 * b2;
325 }
326 assert_eq!(a, a2.get());
327 assert_eq!(b, b2.get());
328 assert_eq!(c, c2.get());
329
330 let a = 7;
331 let b = a * 5;
332 let c = a * b;
333
334 fate! {a2 = 7;}
335 assert_eq!(a, a2.get());
336 assert_eq!(b, b2.get());
337 assert_eq!(c, c2.get());
338 }
339
340 #[test]
341 fn thread_safe_test() {
342 fate! {
343 [a]
344 let a = 0;
345 let b = a * 10;
346 }
347
348 let mut thread_handles = Vec::new();
349 for _i in 1..100 {
350 let a2: Fate<_> = a.clone();
351 let b2: Fate<_> = b.clone();
352 let handle = thread::spawn(move || {
353 for i in 1..100 {
354 let value = 30;
355 fate! {a2 = i + value;}
356 let _r = b2.get();
357 }
360 });
361 thread_handles.push(handle);
362 }
363
364 for handle in thread_handles {
365 handle.join().unwrap();
366 }
367 }
368
369 #[test]
370 fn value_capture_test() {
371 let a = 5;
372 let b = 10;
373 fate! {
374 [c, d]
375 let c = 15; let d = a + b;
377 let e = c * d;
378 }
379
380 assert_eq!(c.get(), d.get());
381 assert_eq!(e.get(), c.get() * d.get());
382
383 fate! {c = a + b;}
384 assert_eq!(c.get(), a + b);
385 assert_eq!(e.get(), c.get() * d.get());
386 }
387
388 #[test]
389 fn explicit_fate_test() {
390 struct TestStruct {
391 fate: Fate<i32>,
392 }
393 fate! {
394 let a = 10;
395 }
396 let test_struct = TestStruct { fate: a.clone() };
397 assert_eq!(a.get(), 10);
398 fate! {a = 15;}
399 assert_eq!(test_struct.fate.get(), 15);
400 }
401
402 #[test]
403 fn mix_types_test() {
404 fate! {
405 [a, b]
406 let a = "String".to_string();
407 let b = 10;
408 let c = a + " " + &b.to_string();
409 }
410
411 assert_eq!(&c.get(), "String 10");
412
413 fate! {
414 a = "String2".to_string();
415 b = 100;
416 }
417
418 assert_eq!(&c.get(), "String2 100");
419 }
420
421 #[test]
422 fn ref_test() {
423 fate! {
424 let a = vec![1, 2, 3];
425 }
426 assert_eq!(a.get(), vec![1, 2, 3]);
427
428 a.by_ref_mut(|a| a.push(4));
429 assert_eq!(a.get(), vec![1, 2, 3, 4]);
430
431 let mut val = 2;
432 a.by_ref(|a| val = a[2]);
433 assert_eq!(val, 3);
434 }
435
436 #[test]
437 fn string_example_test() {
438 fate! {
439 [name]
440 let name = "Alex".to_string();
441 let hello = "Hello, ".to_string() + &name;
442 let goodbye = "Goodbye, ".to_string() + &name;
443 }
444 assert_eq!(&hello.get(), "Hello, Alex");
445 assert_eq!(&goodbye.get(), "Goodbye, Alex");
446
447 fate! {name = "Sam".to_string();}
448 assert_eq!(&hello.get(), "Hello, Sam");
449 assert_eq!(&goodbye.get(), "Goodbye, Sam");
450 }
451
452 #[test]
453 fn dependent_child_clone() {
454 fate! {
455 [a]
456 let a = 5;
457 let b = a + 3;
458 }
459 let child = b.create_dependent_clone();
460 assert_eq!(child.get(), 8);
461 fate! {
462 a = 10;
463 }
464 assert_eq!(b.get(), 13);
465 assert_eq!(b.is_dirty(), false);
466 assert_eq!(child.is_dirty(), true);
467 assert_eq!(child.get(), 13);
468 assert_eq!(child.is_dirty(), false);
469 }
470
471 #[test]
472 fn is_value_test() {
473 fate! {
474 [a]
475 let a = 5;
476 let b = a * 5;
477 }
478
479 {
480 let mut is_value = false;
481 a.by_ref_mut(|_a| {
482 is_value = true;
483 });
484 assert_eq!(is_value, true);
485 }
486 {
487 let mut is_value = false;
488 b.by_ref_mut(|_b| {
489 is_value = true;
490 });
491 assert_eq!(is_value, false);
492 }
493 }
494}