summaryrefslogtreecommitdiff
path: root/src/time.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/time.rs')
-rw-r--r--src/time.rs142
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)
+ }
+}