1use crate::error::RuntimeError;
2use std::time::Duration;
3
4use constant::{MAX_DELAY_SEC, MAX_FUNC_SIZE, MAX_PARAMS_SIZE};
5
6mod constant {
7 pub const MAX_DELAY_SEC: u64 = 60 * 60 * 24 * 365;
8 pub const MAX_PARAMS_SIZE: usize = 1024 * 1024;
9 pub const MAX_FUNC_SIZE: usize = 1024;
10}
11
12#[link(wasm_import_module = "env")]
13extern "C" {
14 fn timer_set_delay(
15 delay: i32,
16 func_ptr: *const u8,
17 func_len: i32,
18 params_ptr: *const u8,
19 params_len: i32,
20 ) -> i32;
21
22 fn now_timestamp() -> u64;
23}
24
25pub fn now() -> u64 {
26 unsafe { now_timestamp() }
27}
28
29pub fn _set_timer(ts: Duration, func: &[u8], params: &[u8]) -> Result<(), RuntimeError> {
30 if params.len() > MAX_PARAMS_SIZE {
31 return Err(RuntimeError::TimerError(
32 "params size exceeds maximum allowed size".to_string(),
33 ));
34 }
35 if ts.as_secs() > MAX_DELAY_SEC {
36 return Err(RuntimeError::TimerError(
37 "delay exceeds maximum allowed size".to_string(),
38 ));
39 }
40 if func.len() > MAX_FUNC_SIZE {
41 return Err(RuntimeError::TimerError(
42 "func size exceeds maximum allowed size".to_string(),
43 ));
44 }
45 let status = unsafe {
46 timer_set_delay(
47 ts.as_secs() as i32,
48 func.as_ptr(),
49 func.len() as i32,
50 params.as_ptr(),
51 params.len() as i32,
52 )
53 };
54 if status != 0 {
55 Err(RuntimeError::TimerError("timer queue is full".to_string()))
56 } else {
57 Ok(())
58 }
59}
60
61#[macro_export]
62macro_rules! set_timer {
63 ($duration:expr, $func_call:ident, $($param:expr,)*) => {{
64 let __duration: std::time::Duration = $duration;
65 let __func_name_bytes = stringify!($func_call);
66 let __func_bytes = __func_name_bytes.as_bytes();
67 let __param = ($($param,)*);
68 let __params_bytes = ::vrs_core_sdk::codec::Encode::encode(&__param);
69 ::vrs_core_sdk::timer::_set_timer(__duration, __func_bytes, __params_bytes.as_slice())
70 }};
71 ($duration:expr, $func_call:ident, $($param:expr),*) => {{
72 let __duration: std::time::Duration = $duration;
73 let __func_name_bytes = stringify!($func_call);
74 let __func_bytes = __func_name_bytes.as_bytes();
75 let __param = ($($param,)*);
76 let __params_bytes = ::vrs_core_sdk::codec::Encode::encode(&__param);
77 ::vrs_core_sdk::timer::_set_timer(__duration, __func_bytes, __params_bytes.as_slice())
78 }};
79 ($duration:expr, $func_call:ident) => {{
80 let __duration: std::time::Duration = $duration;
81 let __func_name_bytes = stringify!($func_call);
82 let __func_bytes = __func_name_bytes.as_bytes();
83 let __params_bytes = ::vrs_core_sdk::codec::Encode::encode(&());
84 ::vrs_core_sdk::timer::_set_timer(__duration, __func_bytes, __params_bytes.as_slice())
85 }};
86}