dcso3/
timer.rs

1/*
2Copyright 2024 Eric Stokes.
3
4This file is part of dcso3.
5
6dcso3 is free software: you can redistribute it and/or modify it under
7the terms of the MIT License.
8
9dcso3 is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE.
12*/
13
14use crate::{as_tbl, cvt_err, record_perf, wrap_f, wrapped_table, LuaEnv, MizLua, Time};
15use anyhow::Result;
16use mlua::{prelude::*, Value};
17use serde_derive::Serialize;
18use std::ops::Deref;
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
21pub struct FunId(i64);
22
23impl<'lua> FromLua<'lua> for FunId {
24    fn from_lua(value: Value<'lua>, _lua: &'lua Lua) -> LuaResult<Self> {
25        match value {
26            Value::Integer(i) => Ok(FunId(i)),
27            _ => Err(cvt_err("FunId")),
28        }
29    }
30}
31
32impl<'lua> IntoLua<'lua> for FunId {
33    fn into_lua(self, _lua: &'lua Lua) -> LuaResult<Value<'lua>> {
34        Ok(Value::Integer(self.0))
35    }
36}
37
38wrapped_table!(Timer, None);
39
40impl<'lua> Timer<'lua> {
41    pub fn singleton(lua: MizLua<'lua>) -> Result<Self> {
42        Ok(lua.inner().globals().raw_get("timer")?)
43    }
44
45    pub fn get_time(&self) -> Result<Time> {
46        Ok(record_perf!(
47            timer_get_time,
48            self.t.call_function("getTime", ())?
49        ))
50    }
51
52    pub fn get_abs_time(&self) -> Result<Time> {
53        Ok(record_perf!(
54            timer_get_abs_time,
55            self.t.call_function("getAbsTime", ())?
56        ))
57    }
58
59    pub fn get_time0(&self) -> Result<Time> {
60        Ok(record_perf!(
61            timer_get_time0,
62            self.t.call_function("getTime0", ())?
63        ))
64    }
65
66    pub fn schedule_function<T, F>(&self, when: Time, arg: T, f: F) -> Result<FunId>
67    where
68        F: Fn(MizLua, T, Time) -> Result<Option<Time>> + 'static,
69        T: IntoLua<'lua> + FromLua<'lua>,
70    {
71        let f = self
72            .lua
73            .create_function(move |lua, (arg, time): (T, Time)| {
74                wrap_f("scheduled function", MizLua(lua), |lua| f(lua, arg, time))
75            })?;
76        Ok(record_perf!(
77            timer_schedule_function,
78            self.t.call_function("scheduleFunction", (f, arg, when))?
79        ))
80    }
81
82    pub fn remove_function(&self, id: FunId) -> Result<()> {
83        Ok(record_perf!(
84            timer_remove_function,
85            self.t.call_function("removeFunction", id)?
86        ))
87    }
88
89    pub fn set_function_time(&self, id: FunId, when: f64) -> Result<()> {
90        Ok(record_perf!(
91            timer_remove_function,
92            self.t.call_function("removeFunction", (id, when))?
93        ))
94    }
95}