use oden_js::{module::native::NativeModuleBuilder, ContextRef}; use std::cell::RefCell; use std::sync::Arc; use std::time::{Duration, Instant}; struct TimeImpl { start: Instant, last_frame_time: Instant, frame_time: Instant, } impl TimeImpl { fn new() -> Self { let now = Instant::now(); TimeImpl { start: now, frame_time: now, last_frame_time: now - Duration::from_millis(15), } } fn since_last_frame(&self) -> f64 { (self.frame_time - self.last_frame_time).as_secs_f64() } fn since_start(&self) -> f64 { (self.frame_time - self.start).as_secs_f64() } fn set_frame_time(&mut self, now: Instant) { self.last_frame_time = self.frame_time; self.frame_time = now; } } pub struct TimeAPI { time: Arc>, } impl TimeAPI { pub fn define(ctx: &ContextRef) -> oden_js::Result { let time = Arc::new(RefCell::new(TimeImpl::new())); let mut builder = NativeModuleBuilder::new(ctx); { let time = time.clone(); builder.export( "since_last_frame", ctx.new_fn(move |_ctx: &ContextRef| time.borrow().since_last_frame())?, )?; } { let time = time.clone(); builder.export( "since_start", ctx.new_fn(move |_ctx: &ContextRef| time.borrow().since_start())?, )?; } builder.build("time-core")?; Ok(TimeAPI { time }) } pub fn set_frame_time(&mut self, now: Instant) { self.time.borrow_mut().set_frame_time(now); } }