nodo/codelet/
task_clock.rs

1// Copyright 2023 David Weikersdorfer
2
3use crate::core::{
4    AcqtimeMarker, AppMonotonicClock, Clock, Pubtime, PubtimeMarker, SysMonotonicClock,
5};
6
7/// Task clocks used internally
8#[derive(Clone)]
9pub struct Clocks {
10    /// Application-wide mononotic clock starting when the application starts
11    pub app_mono: AppMonotonicClock<PubtimeMarker>,
12
13    /// System-wide monotonic clock (probably) starting when the system boots
14    pub sys_mono: SysMonotonicClock<AcqtimeMarker>,
15}
16
17impl Clocks {
18    pub fn new() -> Self {
19        Self {
20            app_mono: AppMonotonicClock::new(),
21            sys_mono: SysMonotonicClock::new(),
22        }
23    }
24}
25
26/// Clocks interface exposed to codelet
27#[derive(Clone)]
28pub struct TaskClocks {
29    /// Application-wide mononotic clock starting when the application starts
30    pub app_mono: AppMonotonicClock<PubtimeMarker>,
31
32    /// System-wide monotonic clock (probably) starting when the system boots
33    pub sys_mono: SysMonotonicClock<AcqtimeMarker>,
34
35    /// Codelet-specific timings
36    pub codelet: CodeletClock,
37}
38
39impl TaskClocks {
40    pub fn from(clocks: Clocks) -> Self {
41        Self {
42            app_mono: clocks.app_mono.clone(),
43            sys_mono: clocks.sys_mono.clone(),
44            codelet: CodeletClock::new(clocks.app_mono.now()),
45        }
46    }
47
48    pub(crate) fn on_codelet_start(&mut self) {
49        let now = self.app_mono.now();
50        self.codelet.last = now;
51    }
52
53    pub(crate) fn on_codelet_stop(&mut self) {}
54
55    pub(crate) fn on_codelet_step(&mut self) {
56        let now = self.app_mono.now();
57        self.codelet.update_dt(now);
58    }
59}
60
61#[derive(Clone)]
62pub struct CodeletClock {
63    last: Pubtime,
64    dt: f64,
65}
66
67impl CodeletClock {
68    pub fn new(now: Pubtime) -> Self {
69        Self { last: now, dt: 0.0 }
70    }
71
72    pub fn update_dt(&mut self, now: Pubtime) {
73        let dt = self.last.abs_diff(now).as_secs_f64();
74        self.last = now;
75        self.dt = dt;
76    }
77
78    /// Time when the current step started. `step_time` is set at the beginning of start/step/stop
79    /// functions and stays constant throughout the current step. Use `real_time` for a continuously
80    /// updating time.
81    pub fn step_time(&self) -> Pubtime {
82        self.last
83    }
84
85    /// Time elapsed in seconds since last step.
86    pub fn dt_secs_f32(&self) -> f32 {
87        self.dt as f32
88    }
89
90    /// Time elapsed in seconds since last step.
91    pub fn dt_secs_f64(&self) -> f64 {
92        self.dt
93    }
94}