pub type TimeStamp = i64;
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SceneDuration {
Finite(TimeStamp),
Indefinite,
}
impl SceneDuration {
pub fn end(&self) -> Option<TimeStamp> {
match self {
SceneDuration::Finite(t) => Some(*t),
SceneDuration::Indefinite => None,
}
}
pub fn contains(&self, t: TimeStamp) -> bool {
t >= 0
&& match self {
SceneDuration::Finite(end) => t < *end,
SceneDuration::Indefinite => true,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Lifetime {
pub start: TimeStamp,
pub end: Option<TimeStamp>,
}
impl Lifetime {
pub fn is_live_at(&self, t: TimeStamp) -> bool {
t >= self.start && self.end.map_or(true, |end| t < end)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn finite_scene_bounds() {
let d = SceneDuration::Finite(100);
assert!(d.contains(0));
assert!(d.contains(99));
assert!(!d.contains(100));
assert!(!d.contains(-1));
assert_eq!(d.end(), Some(100));
}
#[test]
fn indefinite_scene_forever() {
let d = SceneDuration::Indefinite;
assert!(d.contains(0));
assert!(d.contains(i64::MAX));
assert_eq!(d.end(), None);
}
#[test]
fn lifetime_default_is_always_live_after_zero() {
let lt = Lifetime::default();
assert!(lt.is_live_at(0));
assert!(lt.is_live_at(i64::MAX));
assert!(!lt.is_live_at(-1));
}
#[test]
fn lifetime_finite_range() {
let lt = Lifetime {
start: 10,
end: Some(20),
};
assert!(!lt.is_live_at(9));
assert!(lt.is_live_at(10));
assert!(lt.is_live_at(19));
assert!(!lt.is_live_at(20));
}
}