1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(test), no_std)]
3
4#[derive(Debug, Default, Clone, PartialEq, Eq)]
6pub struct TimedSignal {
7 state: bool,
9
10 tick_action: TickAction,
12
13 inverted: bool,
15}
16
17#[derive(Debug, Default, Clone, PartialEq, Eq)]
19enum TickAction {
20 #[default]
22 None,
23
24 Set(u64, bool),
26
27 SetFor(u64, bool),
30
31 Blink(u32),
33}
34
35impl TimedSignal {
36 pub fn new() -> Self {
38 Self::default()
39 }
40
41 pub fn update(&mut self, tick: u64) -> bool {
45 match self.tick_action {
46 TickAction::Set(trigger_tick, state) => {
47 if tick >= trigger_tick {
48 self.state = state;
49 self.tick_action = TickAction::None;
50 }
51 }
52 TickAction::SetFor(duration_ticks, state) => {
53 self.state = state;
54 self.tick_action = TickAction::Set(tick + duration_ticks, !state);
55 return self.update(tick);
56 }
57 TickAction::Blink(blink_period) => {
58 self.state = (tick as u32 % blink_period) < (blink_period >> 1)
59 }
60 _ => {}
61 }
62
63 self.state()
64 }
65
66 pub fn state(&self) -> bool {
68 self.state ^ self.inverted
69 }
70
71 pub fn set_inverted(&mut self, inverted: bool) {
73 self.inverted = inverted;
74 }
75
76 pub fn is_inverted(&self) -> bool {
78 self.inverted
79 }
80
81 pub fn set(&mut self, state: bool) {
83 self.state = state;
84 self.tick_action = TickAction::None;
85 }
86
87 pub fn on(&mut self) {
89 self.set(true);
90 }
91
92 pub fn off(&mut self) {
94 self.set(false);
95 }
96
97 pub fn toggle(&mut self) {
99 self.set(!self.state);
100 }
101
102 pub fn blink(&mut self, period: u32) {
106 self.tick_action = TickAction::Blink(period);
107 }
108
109 pub fn set_at(&mut self, trigger_tick: u64, state: bool) {
111 self.tick_action = TickAction::Set(trigger_tick, state);
112 }
113
114 pub fn set_until(&mut self, trigger_tick: u64, state: bool) {
116 self.set(state);
117 self.tick_action = TickAction::Set(trigger_tick, !state);
118 }
119
120 pub fn set_for(&mut self, duration_ticks: u64, state: bool) {
122 if self.tick_action == TickAction::None {
123 self.tick_action = TickAction::SetFor(duration_ticks, state);
124 }
125 }
126
127 pub fn set_for_retrigger(&mut self, duration_ticks: u64, state: bool) {
129 self.tick_action = TickAction::SetFor(duration_ticks, state);
130 }
131
132 pub fn on_at(&mut self, trigger_tick: u64) {
134 self.set_at(trigger_tick, true);
135 }
136
137 pub fn on_until(&mut self, trigger_tick: u64) {
139 self.set_until(trigger_tick, true);
140 }
141
142 pub fn on_for(&mut self, duration_ticks: u64) {
144 self.set_for(duration_ticks, true);
145 }
146
147 pub fn off_at(&mut self, trigger_tick: u64) {
149 self.set_at(trigger_tick, false);
150 }
151
152 pub fn off_until(&mut self, trigger_tick: u64) {
154 self.set_until(trigger_tick, false);
155 }
156
157 pub fn off_for(&mut self, duration_ticks: u64) {
159 self.set_for(duration_ticks, false);
160 }
161
162 pub fn toggle_at(&mut self, trigger_tick: u64) {
164 if self.tick_action == TickAction::None {
165 self.tick_action = TickAction::Set(trigger_tick, !self.state);
166 }
167 }
168
169 pub fn toggle_until(&mut self, trigger_tick: u64) {
171 if self.tick_action == TickAction::None {
172 self.toggle();
173 self.tick_action = TickAction::Set(trigger_tick, !self.state);
174 }
175 }
176
177 pub fn toggle_for(&mut self, duration_ticks: u64) {
179 if self.tick_action == TickAction::None {
180 self.tick_action = TickAction::SetFor(duration_ticks, !self.state);
181 }
182 }
183
184 pub fn toggle_for_retrigger(&mut self, duration_ticks: u64) {
186 match self.tick_action {
187 TickAction::Set(_, state) => {
188 self.tick_action = TickAction::SetFor(duration_ticks, !state);
189 }
190 _ => {
191 self.tick_action = TickAction::SetFor(duration_ticks, !self.state);
192 }
193 }
194 }
195}
196
197#[cfg(test)]
198mod tests;