exocore-core 0.1.26

Core of Exocore (Distributed applications framework)
Documentation
use std::{sync::atomic::AtomicU64, time::Duration};

use wasm_timer::Instant;

pub struct AtomicInstant {
    reference: Instant,
    delta: AtomicU64,
}

impl AtomicInstant {
    pub fn new() -> Self {
        Self {
            reference: Instant::now(),
            delta: AtomicU64::new(0),
        }
    }

    pub fn get(&self) -> Instant {
        self.reference + Duration::from_nanos(self.delta.load(std::sync::atomic::Ordering::Relaxed))
    }

    pub fn elapsed(&self) -> Duration {
        Instant::now() - self.get()
    }

    pub fn update(&self, now: Instant) {
        let delta = now - self.reference;
        self.delta.store(
            delta.as_nanos() as u64,
            std::sync::atomic::Ordering::Relaxed,
        );
    }

    pub fn update_now(&self) {
        self.update(Instant::now())
    }
}

impl Default for AtomicInstant {
    fn default() -> Self {
        Self::new()
    }
}

impl From<Instant> for AtomicInstant {
    fn from(instant: Instant) -> Self {
        AtomicInstant {
            reference: instant,
            delta: AtomicU64::new(0),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::thread::sleep;

    use super::*;

    #[test]
    fn test_atomic_instant() {
        let ai = AtomicInstant::new();

        sleep(Duration::from_millis(100));
        let elapsed = ai.elapsed();
        assert!(
            elapsed >= Duration::from_millis(100),
            "elapsed: {elapsed:?}"
        );

        ai.update_now();
        let elapsed = ai.elapsed();
        assert!(elapsed < Duration::from_millis(100), "elapsed: {elapsed:?}");
    }
}