1use crate::{phase::Phase, Scalar};
2use serde::{Deserialize, Serialize};
3use std::ops::Range;
4
5#[derive(Debug, Default, Clone, Serialize, Deserialize)]
7pub struct Transition<T> {
8 from: T,
9 to: T,
10 #[serde(default)]
11 pub phase: Phase,
12 #[serde(default)]
13 pub playing: bool,
14 #[serde(default)]
15 time: Scalar,
16}
17
18impl<T> Transition<T>
19where
20 T: Clone,
21{
22 pub fn new(from: T, to: T, phase: Phase) -> Self {
23 Self {
24 from,
25 to,
26 playing: false,
27 time: phase.time_frame().start,
28 phase,
29 }
30 }
31
32 pub fn instant(value: T) -> Self {
33 Self::new(
34 value.clone(),
35 value,
36 Phase::point(1.0).expect("Could not create point phase for instant transition"),
37 )
38 }
39
40 pub fn time(&self) -> Scalar {
41 self.time
42 }
43
44 pub fn start(&mut self) {
45 self.time = self.phase.time_frame().start;
46 }
47
48 pub fn end(&mut self) {
49 self.time = self.phase.time_frame().end;
50 }
51
52 pub fn set_time(&mut self, time: Scalar) {
53 self.time = time
54 .max(self.phase.time_frame().start)
55 .min(self.phase.time_frame().end);
56 }
57
58 pub fn in_progress(&self) -> bool {
59 self.time < self.phase.time_frame().end
60 }
61
62 pub fn is_complete(&self) -> bool {
63 !self.in_progress()
64 }
65
66 pub fn from(&self) -> &T {
67 &self.from
68 }
69
70 pub fn from_mut(&mut self) -> &mut T {
71 &mut self.from
72 }
73
74 pub fn to(&self) -> &T {
75 &self.to
76 }
77
78 pub fn to_mut(&mut self) -> &mut T {
79 &mut self.to
80 }
81
82 pub fn time_frame(&self) -> Range<Scalar> {
83 self.phase.time_frame()
84 }
85
86 pub fn duration(&self) -> Scalar {
87 self.phase.duration()
88 }
89
90 pub fn phase(&self) -> Scalar {
91 self.sample(self.time)
92 }
93
94 pub fn sample(&self, time: Scalar) -> Scalar {
95 self.phase.sample(time)
96 }
97
98 pub fn set(&mut self, value: T) {
99 self.from = self.to.clone();
100 self.to = value;
101 self.time = 0.0;
102 }
103
104 pub fn process(&mut self, delta_time: Scalar) {
105 if self.playing {
106 let time_frame = self.phase.time_frame();
107 let time = self.time + delta_time;
108 if time >= time_frame.end {
109 self.playing = false;
110 }
111 self.time = time.max(time_frame.start).min(time_frame.end);
112 }
113 }
114}
115
116impl<T> PartialEq for Transition<T>
117where
118 T: Clone + PartialEq,
119{
120 fn eq(&self, other: &Self) -> bool {
121 self.from == other.from
122 && self.to == other.to
123 && self.phase == other.phase
124 && self.playing == other.playing
125 && self.time == other.time
126 }
127}
128
129#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
131pub struct SwitchTransition {
132 value: bool,
133 #[serde(default)]
134 pub phase: Phase,
135 #[serde(default)]
136 pub playing: bool,
137 #[serde(default)]
138 time: Scalar,
139}
140
141impl SwitchTransition {
142 pub fn new(value: bool, phase: Phase) -> Self {
143 let time = if value {
144 phase.time_frame().end
145 } else {
146 phase.time_frame().start
147 };
148 Self {
149 value,
150 phase,
151 playing: false,
152 time,
153 }
154 }
155
156 pub fn instant(value: bool) -> Self {
157 Self::new(
158 value,
159 Phase::point(1.0).expect("Could not create point phase for instant switch"),
160 )
161 }
162
163 pub fn time(&self) -> Scalar {
164 self.time
165 }
166
167 pub fn start(&mut self) {
168 self.time = if self.value {
169 self.phase.time_frame().start
170 } else {
171 self.phase.time_frame().end
172 };
173 }
174
175 pub fn end(&mut self) {
176 self.time = if self.value {
177 self.phase.time_frame().end
178 } else {
179 self.phase.time_frame().start
180 };
181 }
182
183 pub fn set_time(&mut self, time: Scalar) {
184 self.time = time
185 .max(self.phase.time_frame().start)
186 .min(self.phase.time_frame().end);
187 }
188
189 pub fn in_progress(&self) -> bool {
190 if self.value {
191 self.time < self.phase.time_frame().end
192 } else {
193 self.time > self.phase.time_frame().start
194 }
195 }
196
197 pub fn is_complete(&self) -> bool {
198 !self.in_progress()
199 }
200
201 pub fn value(&self) -> bool {
202 self.value
203 }
204
205 pub fn duration(&self) -> Scalar {
206 self.phase.duration()
207 }
208
209 pub fn phase(&self) -> Scalar {
210 self.sample(self.time)
211 }
212
213 pub fn sample(&self, time: Scalar) -> Scalar {
214 self.phase.sample(time)
215 }
216
217 pub fn set(&mut self, value: bool) {
218 self.value = value;
219 }
220
221 pub fn process(&mut self, delta_time: Scalar) {
222 if self.playing {
223 let time_frame = self.phase.time_frame();
224 let time = if self.value {
225 let time = self.time + delta_time;
226 if time >= time_frame.end {
227 self.playing = false;
228 }
229 time
230 } else {
231 let time = self.time - delta_time;
232 if time <= time_frame.start {
233 self.playing = false;
234 }
235 time
236 };
237 self.time = time.max(time_frame.start).min(time_frame.end);
238 }
239 }
240}