mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
More robust task.spawn implementation
This commit is contained in:
parent
ecf5c9db44
commit
d7404679c7
1 changed files with 47 additions and 14 deletions
|
@ -9,12 +9,58 @@ use crate::lune::{scheduler::Scheduler, util::TableBuilder};
|
||||||
mod tof;
|
mod tof;
|
||||||
use tof::LuaThreadOrFunction;
|
use tof::LuaThreadOrFunction;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The spawn function needs special treatment,
|
||||||
|
we need to yield right away to allow the
|
||||||
|
spawned task to run until first yield
|
||||||
|
|
||||||
|
1. Schedule this current thread at the front
|
||||||
|
2. Schedule given thread/function at the front,
|
||||||
|
the previous schedule now comes right after
|
||||||
|
3. Give control over to the scheduler, which will
|
||||||
|
resume the above tasks in order when its ready
|
||||||
|
*/
|
||||||
|
const SPAWN_IMPL_LUA: &str = r#"
|
||||||
|
push(currentThread())
|
||||||
|
local thread = push(...)
|
||||||
|
yield()
|
||||||
|
return thread
|
||||||
|
"#;
|
||||||
|
|
||||||
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable<'_>> {
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable<'_>> {
|
||||||
|
let coroutine_running = lua
|
||||||
|
.globals()
|
||||||
|
.get::<_, LuaTable>("coroutine")?
|
||||||
|
.get::<_, LuaFunction>("running")?;
|
||||||
|
let coroutine_yield = lua
|
||||||
|
.globals()
|
||||||
|
.get::<_, LuaTable>("coroutine")?
|
||||||
|
.get::<_, LuaFunction>("yield")?;
|
||||||
|
let push_front =
|
||||||
|
lua.create_function(|lua, (tof, args): (LuaThreadOrFunction, LuaMultiValue)| {
|
||||||
|
let thread = tof.into_thread(lua)?;
|
||||||
|
let sched = lua
|
||||||
|
.app_data_ref::<&Scheduler>()
|
||||||
|
.expect("Lua struct is missing scheduler");
|
||||||
|
sched.push_front(thread.clone(), args)?;
|
||||||
|
Ok(thread)
|
||||||
|
})?;
|
||||||
|
let task_spawn_env = TableBuilder::new(lua)?
|
||||||
|
.with_value("currentThread", coroutine_running)?
|
||||||
|
.with_value("yield", coroutine_yield)?
|
||||||
|
.with_value("push", push_front)?
|
||||||
|
.build_readonly()?;
|
||||||
|
let task_spawn = lua
|
||||||
|
.load(SPAWN_IMPL_LUA)
|
||||||
|
.set_name("task.spawn")
|
||||||
|
.set_environment(task_spawn_env)
|
||||||
|
.into_function()?;
|
||||||
|
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_function("cancel", task_cancel)?
|
.with_function("cancel", task_cancel)?
|
||||||
.with_function("defer", task_defer)?
|
.with_function("defer", task_defer)?
|
||||||
.with_function("delay", task_delay)?
|
.with_function("delay", task_delay)?
|
||||||
.with_function("spawn", task_spawn)?
|
.with_value("spawn", task_spawn)?
|
||||||
.with_async_function("wait", task_wait)?
|
.with_async_function("wait", task_wait)?
|
||||||
.build_readonly()
|
.build_readonly()
|
||||||
}
|
}
|
||||||
|
@ -69,19 +115,6 @@ where
|
||||||
Ok(thread)
|
Ok(thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn task_spawn<'lua>(
|
|
||||||
lua: &'lua Lua,
|
|
||||||
(tof, args): (LuaThreadOrFunction<'lua>, LuaMultiValue<'_>),
|
|
||||||
) -> LuaResult<LuaThread<'lua>> {
|
|
||||||
let thread = tof.into_thread(lua)?;
|
|
||||||
let resume = lua
|
|
||||||
.globals()
|
|
||||||
.get::<_, LuaTable>("coroutine")?
|
|
||||||
.get::<_, LuaFunction>("resume")?;
|
|
||||||
resume.call((thread.clone(), args))?;
|
|
||||||
Ok(thread)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn task_wait(_: &Lua, secs: Option<f64>) -> LuaResult<f64> {
|
async fn task_wait(_: &Lua, secs: Option<f64>) -> LuaResult<f64> {
|
||||||
let duration = Duration::from_secs_f64(secs.unwrap_or_default());
|
let duration = Duration::from_secs_f64(secs.unwrap_or_default());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue