1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::cell::RefCell;
use num_traits::{WrappingAdd, WrappingSub, Zero};
use crate::signal::{ReadSignal, Signal, SignalReceiver, WriteSignal};
#[derive(Clone)]
pub struct SumTotal<T> {
deltas: WriteSignal<T>,
total: ReadSignal<T>,
}
impl<T: 'static + Zero + Clone + WrappingAdd> Default for SumTotal<T> {
fn default() -> Self {
let deltas = Signal::new(T::zero());
let total = deltas.read().map_to(AccumulateSum(RefCell::new(T::zero())));
Self {
deltas: deltas.write(),
total,
}
}
}
impl<T: 'static> SumTotal<T> {
pub fn read(&self) -> ReadSignal<T> {
self.total.clone()
}
}
pub struct SumElement<T: 'static + Clone + Zero + WrappingAdd + WrappingSub> {
current: RefCell<T>,
total: SumTotal<T>,
}
impl<T: 'static + Zero + Clone + Zero + WrappingAdd + WrappingSub> SumElement<T> {
pub fn new(total: &SumTotal<T>) -> Self {
Self {
current: RefCell::new(T::zero()),
total: total.clone(),
}
}
}
impl<T: 'static + Clone + Zero + WrappingAdd + WrappingSub> SignalReceiver<T, SumHandle>
for SumElement<T>
{
fn receive(&self, x: &T) -> SumHandle {
let delta = x.wrapping_sub(&self.current.borrow());
self.current.replace(x.clone());
self.total.deltas.set(delta);
SumHandle()
}
}
impl<T: 'static + Clone + Zero + WrappingAdd + WrappingSub> Drop for SumElement<T> {
fn drop(&mut self) {
self.total
.deltas
.set(T::zero().wrapping_sub(&self.current.borrow()));
}
}
pub struct SumHandle();
struct AccumulateSum<T>(RefCell<T>);
impl<T: 'static + Clone + WrappingAdd> SignalReceiver<T, T> for AccumulateSum<T> {
fn receive(&self, x: &T) -> T {
let mut total = self.0.borrow_mut();
*total = total.wrapping_add(x);
total.clone()
}
}