2023-01-22 19:39:57 +00:00
|
|
|
use std::time::Duration;
|
2023-01-21 18:33:33 +00:00
|
|
|
|
2023-01-22 01:11:17 +00:00
|
|
|
use mlua::{Function, Lua, Result, Table, Value};
|
2023-01-22 19:39:57 +00:00
|
|
|
use tokio::time;
|
2023-01-21 18:33:33 +00:00
|
|
|
|
2023-01-21 20:48:56 +00:00
|
|
|
use crate::utils::table_builder::ReadonlyTableBuilder;
|
|
|
|
|
2023-01-21 18:33:33 +00:00
|
|
|
const DEFAULT_SLEEP_DURATION: f32 = 1.0 / 60.0;
|
|
|
|
|
2023-01-22 01:11:17 +00:00
|
|
|
const TASK_LIB_LUAU: &str = include_str!("../luau/task.luau");
|
2023-01-21 21:40:57 +00:00
|
|
|
|
2023-01-22 01:11:17 +00:00
|
|
|
pub async fn new(lua: &Lua) -> Result<Table> {
|
|
|
|
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")?;
|
2023-01-21 20:48:56 +00:00
|
|
|
ReadonlyTableBuilder::new(lua)?
|
2023-01-22 01:11:17 +00:00
|
|
|
.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))?
|
2023-01-22 19:39:57 +00:00
|
|
|
.with_async_function("wait", wait)?
|
2023-01-21 20:48:56 +00:00
|
|
|
.build()
|
2023-01-21 18:33:33 +00:00
|
|
|
}
|
2023-01-22 01:11:17 +00:00
|
|
|
|
|
|
|
// 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
|
2023-01-22 19:39:57 +00:00
|
|
|
async fn wait(_: &Lua, duration: Option<f32>) -> Result<f32> {
|
2023-01-22 01:11:17 +00:00
|
|
|
let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION);
|
2023-01-22 19:39:57 +00:00
|
|
|
time::sleep(Duration::from_secs_f32(secs)).await;
|
2023-01-22 01:11:17 +00:00
|
|
|
Ok(secs)
|
|
|
|
}
|