use std::time::Duration;
use mlua::{Function, Lua, Result, Table, Value};
use tokio::time;
use crate::utils::table_builder::ReadonlyTableBuilder;
const DEFAULT_SLEEP_DURATION: f32 = 1.0 / 60.0;
const TASK_LIB_LUAU: &str = include_str!("../luau/task.luau");
pub async fn new(lua: &Lua) -> Result
{
let task_lib: Table = lua
.load(TASK_LIB_LUAU)
.set_name("task")?
.eval_async()
.await?;
// FUTURE: Properly implementing the task library in async rust is
// very complicated but should be done at some point, for now we will
// fall back to implementing only task.wait and doing the rest in lua
let task_cancel: Function = task_lib.raw_get("cancel")?;
let task_defer: Function = task_lib.raw_get("defer")?;
let task_delay: Function = task_lib.raw_get("delay")?;
let task_spawn: Function = task_lib.raw_get("spawn")?;
ReadonlyTableBuilder::new(lua)?
.with_value("cancel", Value::Function(task_cancel))?
.with_value("defer", Value::Function(task_defer))?
.with_value("delay", Value::Function(task_delay))?
.with_value("spawn", Value::Function(task_spawn))?
.with_async_function("wait", wait)?
.build()
}
// FIXME: It does seem possible to properly make an async wait
// function with mlua right now, something breaks when using
// async wait functions inside of coroutines
async fn wait(_: &Lua, duration: Option) -> Result {
let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION);
time::sleep(Duration::from_secs_f32(secs)).await;
Ok(secs)
}