diff options
Diffstat (limited to 'src/time.rs')
| -rw-r--r-- | src/time.rs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/time.rs b/src/time.rs new file mode 100644 index 0000000..35e1a86 --- /dev/null +++ b/src/time.rs @@ -0,0 +1,142 @@ +use core::{ + ops::{Add, AddAssign, Sub, SubAssign}, + time::Duration, +}; + +use serde::{Deserialize, Serialize}; + +use crate::ScriptContext; + +mod tortuise { + + #[link(wasm_import_module = "tortuise")] + unsafe extern "C" { + pub safe fn system_now(context: u64) -> u64; + pub safe fn monotonic_now(context: u64) -> u64; + pub safe fn delta_time(context: u64) -> u64; + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +#[repr(transparent)] +#[serde(transparent)] +pub struct SystemTime(u128); + +#[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 { + Duration::from_nanos(tortuise::delta_time(self.0)) + } +} + +impl SystemTime { + pub const UNIX_EPOCH: Self = Self(0); + + pub fn now(context: &ScriptContext) -> Self { + Self(tortuise::system_now(context.0) as u128) + } + + pub fn duration_since(self, earlier: SystemTime) -> Option<Duration> { + if self < earlier { + return None; + } + + Some(Duration::from_nanos_u128(self.0 - earlier.0)) + } + + pub fn checked_add(self, duration: Duration) -> Option<Self> { + Some(Self(self.0.checked_add(duration.as_nanos())?)) + } + + pub fn checked_sub(self, duration: Duration) -> Option<Self> { + Some(Self(self.0.checked_sub(duration.as_nanos())?)) + } +} + +impl Add<Duration> for SystemTime { + type Output = Self; + + fn add(self, rhs: Duration) -> Self::Output { + self.checked_add(rhs).unwrap() + } +} + +impl AddAssign<Duration> for SystemTime { + fn add_assign(&mut self, rhs: Duration) { + *self = self.add(rhs); + } +} + +impl Sub<Duration> for SystemTime { + type Output = Self; + + fn sub(self, rhs: Duration) -> Self::Output { + self.checked_sub(rhs).unwrap() + } +} + +impl SubAssign<Duration> for SystemTime { + fn sub_assign(&mut self, rhs: Duration) { + *self = self.sub(rhs) + } +} + +impl Instant { + pub fn now(context: &ScriptContext) -> Self { + Self(tortuise::monotonic_now(context.0) as u128) + } + + pub fn duration_since(self, earlier: Instant) -> Option<Duration> { + 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<Self> { + Some(Self(self.0.checked_add(duration.as_nanos())?)) + } + + pub fn checked_sub(self, duration: Duration) -> Option<Self> { + Some(Self(self.0.checked_sub(duration.as_nanos())?)) + } +} + +impl Add<Duration> for Instant { + type Output = Self; + + fn add(self, rhs: Duration) -> Self::Output { + self.checked_add(rhs).unwrap() + } +} + +impl AddAssign<Duration> for Instant { + fn add_assign(&mut self, rhs: Duration) { + *self = self.add(rhs); + } +} + +impl Sub<Duration> for Instant { + type Output = Self; + + fn sub(self, rhs: Duration) -> Self::Output { + self.checked_sub(rhs).unwrap() + } +} + +impl SubAssign<Duration> for Instant { + fn sub_assign(&mut self, rhs: Duration) { + *self = self.sub(rhs) + } +} |
