oxideav_scene/
duration.rs1pub type TimeStamp = i64;
10
11#[non_exhaustive]
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum SceneDuration {
15 Finite(TimeStamp),
18
19 Indefinite,
24}
25
26impl SceneDuration {
27 pub fn end(&self) -> Option<TimeStamp> {
29 match self {
30 SceneDuration::Finite(t) => Some(*t),
31 SceneDuration::Indefinite => None,
32 }
33 }
34
35 pub fn contains(&self, t: TimeStamp) -> bool {
37 t >= 0
38 && match self {
39 SceneDuration::Finite(end) => t < *end,
40 SceneDuration::Indefinite => true,
41 }
42 }
43}
44
45#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
50pub struct Lifetime {
51 pub start: TimeStamp,
52 pub end: Option<TimeStamp>,
53}
54
55impl Lifetime {
56 pub fn is_live_at(&self, t: TimeStamp) -> bool {
58 t >= self.start && self.end.map_or(true, |end| t < end)
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn finite_scene_bounds() {
68 let d = SceneDuration::Finite(100);
69 assert!(d.contains(0));
70 assert!(d.contains(99));
71 assert!(!d.contains(100));
72 assert!(!d.contains(-1));
73 assert_eq!(d.end(), Some(100));
74 }
75
76 #[test]
77 fn indefinite_scene_forever() {
78 let d = SceneDuration::Indefinite;
79 assert!(d.contains(0));
80 assert!(d.contains(i64::MAX));
81 assert_eq!(d.end(), None);
82 }
83
84 #[test]
85 fn lifetime_default_is_always_live_after_zero() {
86 let lt = Lifetime::default();
87 assert!(lt.is_live_at(0));
88 assert!(lt.is_live_at(i64::MAX));
89 assert!(!lt.is_live_at(-1));
90 }
91
92 #[test]
93 fn lifetime_finite_range() {
94 let lt = Lifetime {
95 start: 10,
96 end: Some(20),
97 };
98 assert!(!lt.is_live_at(9));
99 assert!(lt.is_live_at(10));
100 assert!(lt.is_live_at(19));
101 assert!(!lt.is_live_at(20));
102 }
103}