livesplit_core/timing/
time.rs

1use crate::{TimeSpan, TimingMethod};
2use core::ops::{Add, AddAssign, Index, IndexMut, Sub, SubAssign};
3
4/// A time that can store a Real Time and a Game Time. Both of them are
5/// optional.
6#[derive(Copy, Clone, Default, Debug, Eq, PartialEq)]
7pub struct Time {
8    /// The Real Time value.
9    pub real_time: Option<TimeSpan>,
10    /// The Game Time value.
11    pub game_time: Option<TimeSpan>,
12}
13
14impl Time {
15    /// Creates a new Time with empty Real Time and Game Time.
16    #[inline]
17    pub const fn new() -> Self {
18        Time {
19            real_time: None,
20            game_time: None,
21        }
22    }
23
24    /// Creates a new Time where Real Time and Game Time are zero. Keep in mind
25    /// that a zero Time Span is not the same as a `None` Time Span as created
26    /// by `Time::new()`.
27    #[inline]
28    pub const fn zero() -> Self {
29        Time {
30            real_time: Some(TimeSpan::zero()),
31            game_time: Some(TimeSpan::zero()),
32        }
33    }
34
35    /// Creates a new Time based on the current one where the Real Time is
36    /// replaced by the given Time Span.
37    #[inline]
38    pub const fn with_real_time(self, real_time: Option<TimeSpan>) -> Self {
39        Time { real_time, ..self }
40    }
41
42    /// Creates a new Time based on the current one where the Game Time is
43    /// replaced by the given Time Span.
44    #[inline]
45    pub const fn with_game_time(self, game_time: Option<TimeSpan>) -> Self {
46        Time { game_time, ..self }
47    }
48
49    /// Creates a new Time based on the current one where the specified timing
50    /// method is replaced by the given Time Span.
51    #[inline]
52    pub fn with_timing_method(
53        mut self,
54        timing_method: TimingMethod,
55        time: Option<TimeSpan>,
56    ) -> Self {
57        self[timing_method] = time;
58        self
59    }
60
61    /// Applies an operation to both Timing Methods of the two times provided
62    /// and creates a new Time from the result.
63    pub fn op<F>(a: Time, b: Time, mut f: F) -> Time
64    where
65        F: FnMut(TimeSpan, TimeSpan) -> TimeSpan,
66    {
67        Time {
68            real_time: catch! { f(a.real_time?, b.real_time?) },
69            game_time: catch! { f(a.game_time?, b.game_time?) },
70        }
71    }
72}
73
74/// Represents a [`TimeSpan`](crate::TimeSpan) intended to be used for describing real time.
75pub struct RealTime(pub Option<TimeSpan>);
76
77impl From<RealTime> for Time {
78    fn from(t: RealTime) -> Time {
79        Time::new().with_real_time(t.0)
80    }
81}
82
83/// Represents a [`TimeSpan`](crate::TimeSpan) intended to be used for describing game time.
84pub struct GameTime(pub Option<TimeSpan>);
85
86impl From<GameTime> for Time {
87    fn from(t: GameTime) -> Time {
88        Time::new().with_game_time(t.0)
89    }
90}
91
92impl Add for Time {
93    type Output = Time;
94
95    fn add(self, rhs: Time) -> Self {
96        Time::op(self, rhs, Add::add)
97    }
98}
99
100impl AddAssign for Time {
101    fn add_assign(&mut self, rhs: Time) {
102        *self = *self + rhs;
103    }
104}
105
106impl Sub for Time {
107    type Output = Time;
108
109    fn sub(self, rhs: Time) -> Self {
110        Time::op(self, rhs, Sub::sub)
111    }
112}
113
114impl SubAssign for Time {
115    fn sub_assign(&mut self, rhs: Time) {
116        *self = *self - rhs;
117    }
118}
119
120impl Index<TimingMethod> for Time {
121    type Output = Option<TimeSpan>;
122
123    fn index(&self, timing_method: TimingMethod) -> &Self::Output {
124        match timing_method {
125            TimingMethod::RealTime => &self.real_time,
126            TimingMethod::GameTime => &self.game_time,
127        }
128    }
129}
130
131impl IndexMut<TimingMethod> for Time {
132    fn index_mut(&mut self, timing_method: TimingMethod) -> &mut Self::Output {
133        match timing_method {
134            TimingMethod::RealTime => &mut self.real_time,
135            TimingMethod::GameTime => &mut self.game_time,
136        }
137    }
138}