1#![allow(dead_code)]
2
3use super::time_signature::TimeSignature;
8use std::cmp::Ordering;
9
10#[derive(Clone, Copy, Debug, Eq, Ord)]
11pub struct MusicTime {
13 bar: u16,
14 beat: u8,
15 beat_interval: u8,
16}
17
18impl MusicTime {
19 pub fn new(bar: u16, beat: u8, beat_interval: u8) -> MusicTime {
31 MusicTime {
32 bar,
33 beat,
34 beat_interval,
35 }
36 }
37
38 pub fn get_bar(&self) -> u16 {
40 self.bar
41 }
42
43 pub fn get_beat(&self) -> u8 {
45 self.beat
46 }
47
48 pub fn get_beat_interval(&self) -> u8 {
50 self.beat_interval
51 }
52
53 pub fn advance_beat(&mut self, time_signature: &TimeSignature) {
75 if self.beat >= time_signature.get_numerator() {
76 self.beat = 1;
77 self.bar += 1;
78 } else {
79 self.beat += 1;
80 }
81 }
82
83 pub fn advance_beat_interval(&mut self, time_signature: &TimeSignature) {
109 const INTERVAL_RESOLUTION: u8 = 16;
110 if self.beat_interval >= INTERVAL_RESOLUTION / 2 {
111 self.beat_interval = 1;
112 self.advance_beat(time_signature);
113 } else {
114 self.beat_interval += 1;
115 }
116 }
117}
118
119impl PartialEq for MusicTime {
120 fn eq(&self, other: &Self) -> bool {
121 self.bar == other.bar
122 && self.beat == other.beat
123 && self.beat_interval == other.beat_interval
124 }
125}
126
127impl PartialOrd for MusicTime {
128 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
129 let other_time_sum = other.bar * 100 + other.beat as u16 * 10 + other.beat_interval as u16;
130 let self_time_sum = self.bar * 100 + self.beat as u16 * 10 + self.beat_interval as u16;
131 self_time_sum.partial_cmp(&other_time_sum)
132 }
133}
134
135impl Default for MusicTime {
136 fn default() -> MusicTime {
138 MusicTime {
139 bar: 1,
140 beat: 1,
141 beat_interval: 1,
142 }
143 }
144}
145
146mod tests {
147 #[test]
148 fn test_order() {
149 use crate::music_time::MusicTime;
150
151 assert_eq!(MusicTime::new(1, 1, 1) < MusicTime::new(2, 1, 1), true);
152 assert_eq!(MusicTime::new(2, 1, 1) > MusicTime::new(1, 1, 1), true);
153 assert_eq!(MusicTime::new(1, 1, 1) <= MusicTime::new(1, 1, 1), true);
154 assert_eq!(MusicTime::new(1, 1, 1) >= MusicTime::new(1, 1, 1), true);
155
156 assert_eq!(MusicTime::new(1, 1, 1) < MusicTime::new(1, 2, 1), true);
157 assert_eq!(MusicTime::new(1, 2, 1) > MusicTime::new(1, 1, 1), true);
158 assert_eq!(MusicTime::new(1, 1, 1) < MusicTime::new(1, 2, 1), true);
159 assert_eq!(MusicTime::new(1, 2, 1) > MusicTime::new(1, 1, 1), true);
160
161 assert_eq!(MusicTime::new(1, 1, 1) < MusicTime::new(1, 1, 2), true);
162 assert_eq!(MusicTime::new(1, 1, 2) > MusicTime::new(1, 1, 1), true);
163 assert_eq!(MusicTime::new(1, 1, 1) < MusicTime::new(1, 1, 2), true);
164 assert_eq!(MusicTime::new(1, 1, 2) > MusicTime::new(1, 1, 1), true);
165 }
166
167 #[test]
168 fn test_equality() {
169 use crate::music_time::MusicTime;
170
171 let a = MusicTime::new(1, 2, 3);
172 let b = MusicTime::new(1, 2, 3);
173 assert_eq!(a == b, true);
174
175 let a = MusicTime::default();
176 let b: MusicTime = Default::default();
177 assert_eq!(a == b, true);
178 assert_eq!(a.get_bar() == 1 && b.get_bar() == 1, true);
179
180 let a = MusicTime::new(2, 1, 1);
181 let b = MusicTime::new(2, 3, 2);
182 assert_eq!(a == b, false);
183 }
184
185 #[test]
186 fn test_advance() {
187 use crate::{music_time::MusicTime, time_signature::TimeSignature};
188
189 let time_signature = TimeSignature::new(4, 4);
190 let mut a = MusicTime::default();
191 assert_eq!(a.get_bar() == 1 && a.get_beat() == 1, true);
192 a.advance_beat(&time_signature);
193 assert_eq!(a.get_bar() == 1 && a.get_beat() == 2, true);
194 a.advance_beat(&time_signature);
195 assert_eq!(a.get_bar() == 1 && a.get_beat() == 3, true);
196 a.advance_beat(&time_signature);
197 assert_eq!(a.get_bar() == 1 && a.get_beat() == 4, true);
198 a.advance_beat(&time_signature);
199 assert_eq!(a.get_bar() == 2 && a.get_beat() == 1, true);
200
201 let time_signature = TimeSignature::new(3, 4);
202 let mut a = MusicTime::default();
203 assert_eq!(a.get_bar() == 1 && a.get_beat() == 1, true);
204 a.advance_beat(&time_signature);
205 assert_eq!(a.get_bar() == 1 && a.get_beat() == 2, true);
206 a.advance_beat(&time_signature);
207 assert_eq!(a.get_bar() == 1 && a.get_beat() == 3, true);
208 a.advance_beat(&time_signature);
209 assert_eq!(a.get_bar() == 2 && a.get_beat() == 1, true);
210 a.advance_beat(&time_signature);
211 assert_eq!(a.get_bar() == 2 && a.get_beat() == 2, true);
212
213 let time_signature = TimeSignature::new(1, 4);
214 let mut a = MusicTime::default();
215 assert_eq!(a.get_bar() == 1 && a.get_beat() == 1, true);
216 a.advance_beat(&time_signature);
217 assert_eq!(a.get_bar() == 2 && a.get_beat() == 1, true);
218 a.advance_beat(&time_signature);
219 assert_eq!(a.get_bar() == 3 && a.get_beat() == 1, true);
220 a.advance_beat(&time_signature);
221 assert_eq!(a.get_bar() == 4 && a.get_beat() == 1, true);
222 a.advance_beat(&time_signature);
223 assert_eq!(a.get_bar() == 5 && a.get_beat() == 1, true);
224 }
225
226 #[test]
227 fn test_advance_beat_interval() {
228 use crate::{music_time::MusicTime, time_signature::TimeSignature};
229 let time_signature = TimeSignature::new(4, 4);
230 let mut a = MusicTime::default();
231 assert_eq!(a, MusicTime::new(1, 1, 1));
232 a.advance_beat_interval(&time_signature);
233 assert_eq!(a, MusicTime::new(1, 1, 2));
234 a.advance_beat_interval(&time_signature);
235 a.advance_beat_interval(&time_signature);
236 a.advance_beat_interval(&time_signature);
237 a.advance_beat_interval(&time_signature);
238 a.advance_beat_interval(&time_signature);
239 a.advance_beat_interval(&time_signature);
240 assert_eq!(a, MusicTime::new(1, 1, 8));
241 a.advance_beat_interval(&time_signature);
242 assert_eq!(a, MusicTime::new(1, 2, 1));
243 }
244
245 #[test]
246 fn test_event_sort() {
247 use crate::music_time::MusicTime;
248
249 let mut events = vec![
250 (MusicTime::new(2, 1, 1), vec![0]),
251 (MusicTime::new(1, 1, 1), vec![0]),
252 (MusicTime::new(4, 1, 1), vec![0]),
253 (MusicTime::new(3, 1, 1), vec![0]),
254 (MusicTime::new(3, 4, 1), vec![0]),
255 ];
256
257 events.sort_by(|a, b| a.0.cmp(&b.0));
258
259 assert_eq!(
260 events,
261 vec![
262 (MusicTime::new(1, 1, 1), vec![0]),
263 (MusicTime::new(2, 1, 1), vec![0]),
264 (MusicTime::new(3, 1, 1), vec![0]),
265 (MusicTime::new(3, 4, 1), vec![0]),
266 (MusicTime::new(4, 1, 1), vec![0]),
267 ]
268 );
269 }
270}