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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use std::cell::{Cell, RefCell, RefMut};
use std::rc::Rc;

use femtos::Instant;

pub trait Observable<T> {
    fn set_observer<F>(&self, f: F)
    where
        F: Fn(&T) + 'static;
    fn notify(&self);
}

// TODO these could be used to imply how it should be used, or they could even be shorthands for T=bool, except TriState which would have 3
// TODO or maybe even tristate is T=Option<S>
#[allow(dead_code)]
type Output<T> = Signal<T>;
#[allow(dead_code)]
type Input<T> = Signal<T>;
#[allow(dead_code)]
type TriState<T> = Signal<T>;

#[derive(Clone, Debug, Default)]
pub struct Signal<T: Copy>(Rc<Cell<T>>);

impl<T: Copy> Signal<T> {
    pub fn new(init: T) -> Signal<T> {
        Signal(Rc::new(Cell::new(init)))
    }

    pub fn set(&mut self, value: T) {
        self.0.set(value);
    }

    pub fn get(&self) -> T {
        self.0.get()
    }
}

#[derive(Clone, Debug)]
pub struct EdgeSignal(Signal<bool>);

impl Default for EdgeSignal {
    fn default() -> Self {
        EdgeSignal(Signal::new(false))
    }
}

impl EdgeSignal {
    pub fn signal(&mut self) {
        self.0.set(true);
    }

    pub fn get(&mut self) -> bool {
        let value = self.0.get();
        self.0.set(false);
        value
    }
}

type ObservableCallback<T> = Box<dyn Fn(&T)>;

#[derive(Clone)]
pub struct ObservableSignal<T>(Rc<RefCell<(T, Option<ObservableCallback<T>>)>>);

impl<T> ObservableSignal<T> {
    pub fn new(init: T) -> ObservableSignal<T> {
        ObservableSignal(Rc::new(RefCell::new((init, None))))
    }

    pub fn borrow_mut(&self) -> RefMut<'_, T> {
        RefMut::map(self.0.borrow_mut(), |v| &mut v.0)
    }
}

impl<T> Observable<T> for ObservableSignal<T> {
    fn set_observer<F>(&self, f: F)
    where
        F: Fn(&T) + 'static,
    {
        self.0.borrow_mut().1 = Some(Box::new(f));
    }

    fn notify(&self) {
        let data = self.0.borrow();
        if let Some(closure) = &data.1 {
            closure(&data.0);
        }
    }
}

pub struct ObservableEdgeSignal(ObservableSignal<bool>);

impl Default for ObservableEdgeSignal {
    fn default() -> Self {
        ObservableEdgeSignal(ObservableSignal::new(false))
    }
}

impl ObservableEdgeSignal {
    pub fn set(&mut self) {
        *self.0.borrow_mut() = true;
        self.0.notify();
    }

    pub fn get(&mut self) -> bool {
        let mut addr = self.0.borrow_mut();
        let value = *addr;
        *addr = false;
        value
    }
}

impl Observable<bool> for ObservableEdgeSignal {
    fn set_observer<F>(&self, f: F)
    where
        F: Fn(&bool) + 'static,
    {
        self.0.set_observer(f)
    }

    fn notify(&self) {
        self.0.notify()
    }
}


pub trait SignalReceiver<T> {
    fn get_next(&self) -> (Instant, T);
    fn get_at(clock: Instant) -> T;
}

pub trait SignalDriver<T> {
    fn set_at(clock: Instant, value: T);
}


//pub struct LevelTriggeredOutput