From 8e8fb6c54fa1404c926e4bee2905778dffaa881a Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Sat, 21 Jan 2023 13:33:33 -0500 Subject: [PATCH] Implement task.wait global --- lune.yml | 5 +++++ luneTypes.d.luau | 4 ++++ src/lib/globals/mod.rs | 10 ++++++---- src/lib/globals/task.rs | 40 ++++++++++++++++++++++++++++++++++++++++ src/lib/lib.rs | 13 ++++++++----- src/tests/task/wait.luau | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 src/lib/globals/task.rs create mode 100644 src/tests/task/wait.luau diff --git a/lune.yml b/lune.yml index 8c678c3..6d6a167 100644 --- a/lune.yml +++ b/lune.yml @@ -73,3 +73,8 @@ globals: - type: string - required: false type: table + # Task + task.wait: + args: + - required: false + type: number diff --git a/luneTypes.d.luau b/luneTypes.d.luau index e796a87..559bbbe 100644 --- a/luneTypes.d.luau +++ b/luneTypes.d.luau @@ -51,3 +51,7 @@ declare process: { stderr: string, }, } + +declare task: { + wait: (duration: number?) -> (number), +} diff --git a/src/lib/globals/mod.rs b/src/lib/globals/mod.rs index 503ea43..9842355 100644 --- a/src/lib/globals/mod.rs +++ b/src/lib/globals/mod.rs @@ -2,8 +2,10 @@ mod console; mod fs; mod net; mod process; +mod task; -pub use console::Console; -pub use fs::Fs; -pub use net::Net; -pub use process::Process; +pub use console::Console as ConsoleGlobal; +pub use fs::Fs as FsGlobal; +pub use net::Net as NetGlobal; +pub use process::Process as ProcessGlobal; +pub use task::Task as TaskGlobal; diff --git a/src/lib/globals/task.rs b/src/lib/globals/task.rs new file mode 100644 index 0000000..f7b3757 --- /dev/null +++ b/src/lib/globals/task.rs @@ -0,0 +1,40 @@ +use std::time::Duration; + +use mlua::{Function, UserData, UserDataMethods, Value, Variadic}; +use tokio::time; + +const DEFAULT_SLEEP_DURATION: f32 = 1.0 / 60.0; + +pub struct Task(); + +impl Task { + pub fn new() -> Self { + Self() + } +} + +impl Default for Task { + fn default() -> Self { + Self::new() + } +} + +impl UserData for Task { + fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_async_function("wait", |_, duration: Option| async move { + let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION); + time::sleep(Duration::from_secs_f32(secs)).await; + Ok(secs) + }); + methods.add_async_function( + "spawn", + |lua, (func, args): (Function, Variadic)| async move { + let _thread = lua + .create_thread(func)? + .into_async::<_, Variadic>>(args); + // task::spawn_local(async move { thread }); + Ok(()) + }, + ); + } +} diff --git a/src/lib/lib.rs b/src/lib/lib.rs index d9b846a..2180e2c 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -5,7 +5,7 @@ pub mod globals; pub mod utils; use crate::{ - globals::{Console, Fs, Net, Process}, + globals::{ConsoleGlobal, FsGlobal, NetGlobal, ProcessGlobal, TaskGlobal}, utils::formatting::{pretty_print_luau_error, print_label}, }; @@ -29,10 +29,12 @@ impl Lune { pub fn with_default_globals(self) -> Result { { let globals = self.lua.globals(); - globals.set("console", Console::new())?; - globals.set("fs", Fs())?; - globals.set("net", Net::new())?; - globals.set("process", Process::new(self.args.clone()))?; + globals.raw_set("console", ConsoleGlobal::new())?; + globals.raw_set("fs", FsGlobal::new())?; + globals.raw_set("net", NetGlobal::new())?; + globals.raw_set("process", ProcessGlobal::new(self.args.clone()))?; + globals.raw_set("task", TaskGlobal::new())?; + globals.set_readonly(true); } Ok(self) } @@ -107,5 +109,6 @@ mod tests { net_request_redirect: "net/request/redirect", net_json_decode: "net/json/decode", net_json_encode: "net/json/encode", + task_wait: "task/wait", } } diff --git a/src/tests/task/wait.luau b/src/tests/task/wait.luau new file mode 100644 index 0000000..333e375 --- /dev/null +++ b/src/tests/task/wait.luau @@ -0,0 +1,35 @@ +local DEFAULT = 1 / 60 +local EPSILON = 1 / 100 + +local function test(expected: number?) + local start = os.clock() + local returned = task.wait(expected) + local elapsed = (os.clock() - start) + local difference = math.abs(elapsed - returned) + if difference > EPSILON then + error( + string.format( + "Elapsed time diverged too much from argument!" + .. "\nGot argument of %.3fs and elapsed time of %.3fs" + .. "\nGot maximum difference of %.3fs and real difference of %.3fs", + expected or DEFAULT, + elapsed, + EPSILON, + difference + ) + ) + end +end + +local function measure(duration: number?) + for _ = 1, 5 do + test(duration) + end +end + +measure() +measure(1 / 100) +measure(1 / 60) +measure(1 / 30) +measure(1 / 20) +measure(1 / 10)