Port task library to new crate

This commit is contained in:
Filip Tibell 2024-04-21 15:32:32 +02:00
parent 34e1165013
commit a5e349c54a
No known key found for this signature in database
3 changed files with 97 additions and 1 deletions

25
Cargo.lock generated
View file

@ -1507,7 +1507,7 @@ dependencies = [
"itertools",
"lz4_flex",
"mlua",
"mlua-luau-scheduler",
"mlua-luau-scheduler 0.0.2",
"once_cell",
"os_str_bytes",
"path-clean",
@ -1592,6 +1592,12 @@ version = "0.8.3"
[[package]]
name = "lune-std-task"
version = "0.8.3"
dependencies = [
"lune-utils",
"mlua",
"mlua-luau-scheduler 0.0.1",
"tokio",
]
[[package]]
name = "lune-utils"
@ -1698,6 +1704,23 @@ dependencies = [
"serde-value",
]
[[package]]
name = "mlua-luau-scheduler"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c7ba4c0a49d3549cbb152c72cb447a0e733de8f1b70bb276a010e13addbd72b"
dependencies = [
"async-executor",
"blocking",
"concurrent-queue",
"derive_more",
"event-listener 4.0.3",
"futures-lite",
"mlua",
"rustc-hash",
"tracing",
]
[[package]]
name = "mlua-luau-scheduler"
version = "0.0.2"

View file

@ -9,3 +9,11 @@ path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
mlua = "0.9.7"
mlua-luau-scheduler = "0.0.1"
tokio = { version = "1", features = ["time"] }
lune-utils = { version = "0.8.3", path = "../lune-utils" }

View file

@ -1 +1,66 @@
#![allow(clippy::cargo_common_metadata)]
use std::time::Duration;
use mlua::prelude::*;
use mlua_luau_scheduler::Functions;
use tokio::time::{sleep, Instant};
use lune_utils::TableBuilder;
/**
Creates the `task` standard library module.
# Errors
Errors when out of memory, or if default Lua globals are missing.
*/
pub fn module(lua: &Lua) -> LuaResult<LuaTable<'_>> {
let fns = Functions::new(lua)?;
// Create wait & delay functions
let task_wait = lua.create_async_function(wait)?;
let task_delay_env = TableBuilder::new(lua)?
.with_value("select", lua.globals().get::<_, LuaFunction>("select")?)?
.with_value("spawn", fns.spawn.clone())?
.with_value("defer", fns.defer.clone())?
.with_value("wait", task_wait.clone())?
.build_readonly()?;
let task_delay = lua
.load(DELAY_IMPL_LUA)
.set_name("task.delay")
.set_environment(task_delay_env)
.into_function()?;
// Overwrite resume & wrap functions on the coroutine global
// with ones that are compatible with our scheduler
let co = lua.globals().get::<_, LuaTable>("coroutine")?;
co.set("resume", fns.resume.clone())?;
co.set("wrap", fns.wrap.clone())?;
TableBuilder::new(lua)?
.with_value("cancel", fns.cancel)?
.with_value("defer", fns.defer)?
.with_value("delay", task_delay)?
.with_value("spawn", fns.spawn)?
.with_value("wait", task_wait)?
.build_readonly()
}
const DELAY_IMPL_LUA: &str = r"
return defer(function(...)
wait(select(1, ...))
spawn(select(2, ...))
end, ...)
";
async fn wait(_: &Lua, secs: Option<f64>) -> LuaResult<f64> {
let duration = Duration::from_secs_f64(secs.unwrap_or_default());
let before = Instant::now();
sleep(duration).await;
let after = Instant::now();
Ok((after - before).as_secs_f64())
}