1use crate::logic::LogicValue;
2use crate::resolved_signal::{ResolvedSignal, ResolvedSignalArr};
3use crate::signal::{Signal, SignalArr};
4use std::array;
5use std::fmt::Display;
6use std::ops::{Index, IndexMut};
7use std::random::random;
8use std::sync::{Arc, RwLock};
9
10pub(crate) enum WriteableSignal {
11 Signal(Signal),
12 ResolvedSignal(ResolvedSignal),
13}
14
15pub trait PortOut: Send + Sync + 'static
16where
17 LogicValue: Copy + PartialEq + Send + Sync + Display + 'static,
18{
19 fn write(&self, new_value: LogicValue);
20 fn attach(&mut self, signal: Signal);
21 fn attach_resolved(&mut self, signal: ResolvedSignal);
22}
23
24pub(crate) struct OutputPort {
25 pub signals: Vec<WriteableSignal>,
26 id: u128,
27}
28
29impl OutputPort {
30 fn new() -> Self {
31 OutputPort {
32 signals: Vec::new(),
33 id: random(),
34 }
35 }
36}
37
38impl PortOut for OutputPort {
39 fn write(&self, new_value: LogicValue) {
40 self.signals
41 .iter()
42 .for_each(|writeable_signal| match writeable_signal {
43 WriteableSignal::Signal(signal) => signal.write(new_value),
44 WriteableSignal::ResolvedSignal(signal) => signal.write(new_value, self.id),
45 });
46 }
47
48 fn attach(&mut self, signal: Signal) {
49 self.signals.push(WriteableSignal::Signal(signal));
50 }
51
52 fn attach_resolved(&mut self, signal: ResolvedSignal) {
53 self.signals.push(WriteableSignal::ResolvedSignal(signal));
54 }
55}
56
57#[derive(Clone)]
60pub struct SROut
61where
62 LogicValue: Copy + PartialEq + Send + Sync + Display + 'static,
63{
64 port: Arc<RwLock<dyn PortOut>>,
65}
66
67impl SROut
68where
69 LogicValue: Copy + PartialEq + Send + Sync + Display + 'static,
70{
71 pub fn new() -> Self {
72 SROut {
73 port: Arc::new(RwLock::new(OutputPort::new())),
74 }
75 }
76
77 pub fn write(&self, new_value: LogicValue) {
78 self.port.write().unwrap().write(new_value);
79 }
80
81 pub fn attach(&mut self, signal: &Signal) {
82 self.port.write().unwrap().attach(signal.clone());
83 }
84
85 pub fn set_to(&mut self, other: &SROut) {
86 self.port = other.port.clone();
87 }
88}
89
90impl SROut {
91 pub fn attach_resolved(&mut self, signal: &ResolvedSignal) {
92 self.port.write().unwrap().attach_resolved(signal.clone());
93 }
94}
95
96#[derive(Clone)]
98pub struct SROutArr<const N: usize>
99where
100 LogicValue: Copy + PartialEq + Send + Sync + Display + 'static,
101{
102 ports: [SROut; N],
103}
104
105impl<const N: usize> SROutArr<N>
106where
107 LogicValue: Copy + PartialEq + Send + Sync + Display + 'static,
108{
109 pub fn new() -> Self {
110 SROutArr {
111 ports: array::from_fn(|_| SROut::new()),
112 }
113 }
114
115 pub fn write(&self, new_value: [LogicValue; N]) {
116 for i in 0..N {
117 self.ports[i].write(new_value[i])
118 }
119 }
120
121 pub fn attach(&mut self, signals: &SignalArr<N>) {
122 for i in 0..N {
123 self.ports[i].attach(&signals[i])
124 }
125 }
126
127 pub fn set_to(&mut self, other: &SROutArr<N>) {
128 for i in 0..N {
129 self.ports[i].set_to(&other.ports[i])
130 }
131 }
132}
133
134impl<const N: usize> SROutArr<N> {
135 pub fn attach_resolved(&mut self, signals: &ResolvedSignalArr<N>) {
136 for i in 0..N {
137 self.ports[i].attach_resolved(&signals[i])
138 }
139 }
140}
141
142impl<const N: usize> Index<usize> for SROutArr<N>
143where
144 LogicValue: Copy + PartialEq + Send + Sync + Display + 'static,
145{
146 type Output = SROut;
147
148 fn index(&self, index: usize) -> &Self::Output {
149 &self.ports[index]
150 }
151}
152
153impl<const N: usize> IndexMut<usize> for SROutArr<N>
154where
155 LogicValue: Copy + PartialEq + Send + Sync + Display + 'static,
156{
157 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
158 &mut self.ports[index]
159 }
160}