use core::{ ops::{Add, AddAssign, Sub, SubAssign}, time::Duration, }; use serde::{Deserialize, Serialize}; use crate::ScriptContext; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] #[repr(transparent)] #[serde(transparent)] pub struct SystemTime(std::time::SystemTime); #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] #[repr(transparent)] #[serde(transparent)] pub struct Instant(u128); impl ScriptContext<'_> { pub fn delta_time(&self) -> Duration { puffin::profile_function!(); Duration::from_nanos_u128(self.0.time.delta_time().as_nanos()) } } impl SystemTime { pub const UNIX_EPOCH: Self = Self(std::time::SystemTime::UNIX_EPOCH); pub fn now(context: &ScriptContext) -> Self { puffin::profile_function!(); Self(context.0.time.system_now()) } pub fn duration_since(self, earlier: SystemTime) -> Option { puffin::profile_function!(); self.0.duration_since(earlier.0).ok() } pub fn checked_add(self, duration: Duration) -> Option { Some(Self(self.0.checked_add(duration)?)) } pub fn checked_sub(self, duration: Duration) -> Option { Some(Self(self.0.checked_sub(duration)?)) } } impl Add for SystemTime { type Output = Self; fn add(self, rhs: Duration) -> Self::Output { self.checked_add(rhs).unwrap() } } impl AddAssign for SystemTime { fn add_assign(&mut self, rhs: Duration) { *self = self.add(rhs); } } impl Sub for SystemTime { type Output = Self; fn sub(self, rhs: Duration) -> Self::Output { self.checked_sub(rhs).unwrap() } } impl SubAssign for SystemTime { fn sub_assign(&mut self, rhs: Duration) { *self = self.sub(rhs) } } impl Instant { pub fn now(context: &ScriptContext) -> Self { puffin::profile_function!(); Self(context.0.time.monotonic_now().as_nanos()) } pub fn duration_since(self, earlier: Instant) -> Option { if earlier > self { return None; } Some(Duration::from_nanos_u128(self.0 - earlier.0)) } pub fn elapsed(self, context: &ScriptContext) -> Duration { Self::now(context) .duration_since(self) .unwrap_or(Duration::ZERO) } pub fn checked_add(self, duration: Duration) -> Option { Some(Self(self.0.checked_add(duration.as_nanos())?)) } pub fn checked_sub(self, duration: Duration) -> Option { Some(Self(self.0.checked_sub(duration.as_nanos())?)) } } impl Add for Instant { type Output = Self; fn add(self, rhs: Duration) -> Self::Output { self.checked_add(rhs).unwrap() } } impl AddAssign for Instant { fn add_assign(&mut self, rhs: Duration) { *self = self.add(rhs); } } impl Sub for Instant { type Output = Self; fn sub(self, rhs: Duration) -> Self::Output { self.checked_sub(rhs).unwrap() } } impl SubAssign for Instant { fn sub_assign(&mut self, rhs: Duration) { *self = self.sub(rhs) } }