From e3c5839159903658a667f789963f20a31567b25c Mon Sep 17 00:00:00 2001 From: Mica White Date: Thu, 30 Jul 2026 07:34:24 -0400 Subject: Initial commit --- src/time.rs | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/time.rs (limited to 'src/time.rs') 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 { + if self < earlier { + return None; + } + + Some(Duration::from_nanos_u128(self.0 - earlier.0)) + } + + 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 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 { + Self(tortuise::monotonic_now(context.0) as u128) + } + + 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) + } +} -- cgit v1.3.1