Implement task.wait global

This commit is contained in:
Filip Tibell 2023-01-21 13:33:33 -05:00
parent 2e5f70dea8
commit 8e8fb6c54f
No known key found for this signature in database
6 changed files with 98 additions and 9 deletions

View file

@ -73,3 +73,8 @@ globals:
- type: string - type: string
- required: false - required: false
type: table type: table
# Task
task.wait:
args:
- required: false
type: number

View file

@ -51,3 +51,7 @@ declare process: {
stderr: string, stderr: string,
}, },
} }
declare task: {
wait: (duration: number?) -> (number),
}

View file

@ -2,8 +2,10 @@ mod console;
mod fs; mod fs;
mod net; mod net;
mod process; mod process;
mod task;
pub use console::Console; pub use console::Console as ConsoleGlobal;
pub use fs::Fs; pub use fs::Fs as FsGlobal;
pub use net::Net; pub use net::Net as NetGlobal;
pub use process::Process; pub use process::Process as ProcessGlobal;
pub use task::Task as TaskGlobal;

40
src/lib/globals/task.rs Normal file
View file

@ -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<f32>| 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<Value>)| async move {
let _thread = lua
.create_thread(func)?
.into_async::<_, Variadic<Value<'lua>>>(args);
// task::spawn_local(async move { thread });
Ok(())
},
);
}
}

View file

@ -5,7 +5,7 @@ pub mod globals;
pub mod utils; pub mod utils;
use crate::{ use crate::{
globals::{Console, Fs, Net, Process}, globals::{ConsoleGlobal, FsGlobal, NetGlobal, ProcessGlobal, TaskGlobal},
utils::formatting::{pretty_print_luau_error, print_label}, utils::formatting::{pretty_print_luau_error, print_label},
}; };
@ -29,10 +29,12 @@ impl Lune {
pub fn with_default_globals(self) -> Result<Self> { pub fn with_default_globals(self) -> Result<Self> {
{ {
let globals = self.lua.globals(); let globals = self.lua.globals();
globals.set("console", Console::new())?; globals.raw_set("console", ConsoleGlobal::new())?;
globals.set("fs", Fs())?; globals.raw_set("fs", FsGlobal::new())?;
globals.set("net", Net::new())?; globals.raw_set("net", NetGlobal::new())?;
globals.set("process", Process::new(self.args.clone()))?; globals.raw_set("process", ProcessGlobal::new(self.args.clone()))?;
globals.raw_set("task", TaskGlobal::new())?;
globals.set_readonly(true);
} }
Ok(self) Ok(self)
} }
@ -107,5 +109,6 @@ mod tests {
net_request_redirect: "net/request/redirect", net_request_redirect: "net/request/redirect",
net_json_decode: "net/json/decode", net_json_decode: "net/json/decode",
net_json_encode: "net/json/encode", net_json_encode: "net/json/encode",
task_wait: "task/wait",
} }
} }

35
src/tests/task/wait.luau Normal file
View file

@ -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)