1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! Contains definitions to work with arbitrary clocks
//! that handle time spans and time stamps
//! where actual passing time spans are provided externally.

use std::time::{Duration, Instant};

use crate::{span::TimeSpan, stamp::TimeStamp};

/// Result of `Clock` step.
/// Contains time stamp corresponding to "now"
/// and time span since previous step.
#[derive(Clone, Copy, Debug)]
pub struct ClockStep {
    /// TimeStamp corresponding to "now".
    pub now: TimeStamp,
    pub step: TimeSpan,
}

/// Time measuring device.
/// Uses system monotonic clock counter
/// and yields `ClockStep`s for each step.
#[derive(Clone)] // Not Copy to avoid accidental copying.
pub struct Clock {
    start: Instant,
    now: TimeStamp,
}

impl Default for Clock {
    #[inline(always)]
    fn default() -> Self {
        Self::new()
    }
}

impl Clock {
    /// Returns new `Clock` instance.
    #[inline(always)]
    pub fn new() -> Self {
        Clock {
            start: Instant::now(),
            now: TimeStamp::start(),
        }
    }

    /// Returns time stamp corresponding to "now" of the last step.
    pub fn now(&self) -> TimeStamp {
        self.now
    }

    /// Advances the clock and returns `ClockStep` result
    /// with new time stamp and time span since previous step.
    pub fn step(&mut self) -> ClockStep {
        let from_start = self.start.elapsed();
        let now = TimeStamp::from_observed_duration(from_start);
        let step = now - self.now;
        self.now = now;

        ClockStep {
            now: self.now,
            step,
        }
    }

    /// Returns `Instant` corresponding to given `TimeStamp`.
    pub fn stamp_instant(&self, stamp: TimeStamp) -> Instant {
        self.start + Duration::from_nanos(stamp.nanos_since_start())
    }
}