kira/clock/
clock_speed.rs

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
use crate::tween::{Tweenable, Value};

/// The rate that a [clock](crate::clock) ticks at.
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ClockSpeed {
	/// The clock ticks every x seconds.
	SecondsPerTick(f64),
	/// The clock ticks x times per second.
	TicksPerSecond(f64),
	/// The clock ticks x times per minute.
	TicksPerMinute(f64),
}

impl ClockSpeed {
	/// Returns the [`ClockSpeed`] as a number of seconds between each tick.
	#[must_use]
	pub fn as_seconds_per_tick(&self) -> f64 {
		match self {
			ClockSpeed::SecondsPerTick(seconds_per_tick) => *seconds_per_tick,
			ClockSpeed::TicksPerSecond(ticks_per_second) => 1.0 / *ticks_per_second,
			ClockSpeed::TicksPerMinute(ticks_per_minute) => 60.0 / *ticks_per_minute,
		}
	}

	/// Returns the [`ClockSpeed`] as a number of ticks per second.
	#[must_use]
	pub fn as_ticks_per_second(&self) -> f64 {
		match self {
			ClockSpeed::SecondsPerTick(seconds_per_tick) => 1.0 / *seconds_per_tick,
			ClockSpeed::TicksPerSecond(ticks_per_second) => *ticks_per_second,
			ClockSpeed::TicksPerMinute(ticks_per_minute) => *ticks_per_minute / 60.0,
		}
	}

	/// Returns the [`ClockSpeed`] as a number of ticks per minute.
	#[must_use]
	pub fn as_ticks_per_minute(&self) -> f64 {
		match self {
			ClockSpeed::SecondsPerTick(seconds_per_tick) => 60.0 / *seconds_per_tick,
			ClockSpeed::TicksPerSecond(ticks_per_second) => *ticks_per_second * 60.0,
			ClockSpeed::TicksPerMinute(ticks_per_minute) => *ticks_per_minute,
		}
	}
}

impl Tweenable for ClockSpeed {
	fn interpolate(a: Self, b: Self, amount: f64) -> Self {
		match b {
			ClockSpeed::SecondsPerTick(b) => ClockSpeed::SecondsPerTick(Tweenable::interpolate(
				a.as_seconds_per_tick(),
				b,
				amount,
			)),
			ClockSpeed::TicksPerSecond(b) => ClockSpeed::TicksPerSecond(Tweenable::interpolate(
				a.as_ticks_per_second(),
				b,
				amount,
			)),
			ClockSpeed::TicksPerMinute(b) => ClockSpeed::TicksPerMinute(Tweenable::interpolate(
				a.as_ticks_per_minute(),
				b,
				amount,
			)),
		}
	}
}

impl From<ClockSpeed> for Value<ClockSpeed> {
	fn from(clock_speed: ClockSpeed) -> Self {
		Value::Fixed(clock_speed)
	}
}

#[cfg(test)]
#[test]
#[allow(clippy::float_cmp)]
fn test() {
	const SECONDS_PER_TICK: f64 = 0.5;
	const TICKS_PER_SECOND: f64 = 2.0;
	const TICKS_PER_MINUTE: f64 = 120.0;

	assert_eq!(
		ClockSpeed::SecondsPerTick(SECONDS_PER_TICK).as_seconds_per_tick(),
		SECONDS_PER_TICK
	);
	assert_eq!(
		ClockSpeed::SecondsPerTick(SECONDS_PER_TICK).as_ticks_per_second(),
		TICKS_PER_SECOND
	);
	assert_eq!(
		ClockSpeed::SecondsPerTick(SECONDS_PER_TICK).as_ticks_per_minute(),
		TICKS_PER_MINUTE
	);

	assert_eq!(
		ClockSpeed::TicksPerSecond(TICKS_PER_SECOND).as_seconds_per_tick(),
		SECONDS_PER_TICK
	);
	assert_eq!(
		ClockSpeed::TicksPerSecond(TICKS_PER_SECOND).as_ticks_per_second(),
		TICKS_PER_SECOND
	);
	assert_eq!(
		ClockSpeed::TicksPerSecond(TICKS_PER_SECOND).as_ticks_per_minute(),
		TICKS_PER_MINUTE
	);

	assert_eq!(
		ClockSpeed::TicksPerMinute(TICKS_PER_MINUTE).as_seconds_per_tick(),
		SECONDS_PER_TICK
	);
	assert_eq!(
		ClockSpeed::TicksPerMinute(TICKS_PER_MINUTE).as_ticks_per_second(),
		TICKS_PER_SECOND
	);
	assert_eq!(
		ClockSpeed::TicksPerMinute(TICKS_PER_MINUTE).as_ticks_per_minute(),
		TICKS_PER_MINUTE
	);
}