Implement argument passing for task lib

This commit is contained in:
Filip Tibell 2023-01-24 12:24:57 -05:00
parent 371892fc7d
commit 113f290c59
No known key found for this signature in database
4 changed files with 75 additions and 21 deletions

View file

@ -55,19 +55,23 @@ async fn task_cancel<'a>(lua: &'a Lua, thread: LuaThread<'a>) -> LuaResult<()> {
async fn task_defer<'a>( async fn task_defer<'a>(
lua: &'a Lua, lua: &'a Lua,
(tof, _args): (LuaValue<'a>, LuaMultiValue<'a>), (tof, args): (LuaValue<'a>, LuaMultiValue<'a>),
) -> LuaResult<LuaThread<'a>> { ) -> LuaResult<LuaThread<'a>> {
// Spawn a new detached task using a lua reference that we can use inside of our task // Spawn a new detached task using a lua reference that we can use inside of our task
let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap(); let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap();
let task_thread = tof_to_thread(lua, tof)?; let task_thread = tof_to_thread(lua, tof)?;
let task_thread_key = lua.create_registry_value(task_thread)?; let task_thread_key = lua.create_registry_value(task_thread)?;
let task_args_key = lua.create_registry_value(args.into_vec())?;
let lua_thread_to_return = lua.registry_value(&task_thread_key)?; let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
run_registered_task(lua, TaskRunMode::Deferred, async move { run_registered_task(lua, TaskRunMode::Deferred, async move {
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?; let thread: LuaThread = task_lua.registry_value(&task_thread_key)?;
let argsv: Vec<LuaValue> = task_lua.registry_value(&task_args_key)?;
let args = LuaMultiValue::from_vec(argsv);
if thread.status() == LuaThreadStatus::Resumable { if thread.status() == LuaThreadStatus::Resumable {
thread.into_async::<_, LuaMultiValue>(()).await?; let _: LuaMultiValue = thread.into_async(args).await?;
} }
task_lua.remove_registry_value(task_thread_key)?; task_lua.remove_registry_value(task_thread_key)?;
task_lua.remove_registry_value(task_args_key)?;
Ok(()) Ok(())
}) })
.await?; .await?;
@ -76,20 +80,24 @@ async fn task_defer<'a>(
async fn task_delay<'a>( async fn task_delay<'a>(
lua: &'a Lua, lua: &'a Lua,
(duration, tof, _args): (Option<f32>, LuaValue<'a>, LuaMultiValue<'a>), (duration, tof, args): (Option<f32>, LuaValue<'a>, LuaMultiValue<'a>),
) -> LuaResult<LuaThread<'a>> { ) -> LuaResult<LuaThread<'a>> {
// Spawn a new detached task using a lua reference that we can use inside of our task // Spawn a new detached task using a lua reference that we can use inside of our task
let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap(); let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap();
let task_thread = tof_to_thread(lua, tof)?; let task_thread = tof_to_thread(lua, tof)?;
let task_thread_key = lua.create_registry_value(task_thread)?; let task_thread_key = lua.create_registry_value(task_thread)?;
let task_args_key = lua.create_registry_value(args.into_vec())?;
let lua_thread_to_return = lua.registry_value(&task_thread_key)?; let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
run_registered_task(lua, TaskRunMode::Deferred, async move { run_registered_task(lua, TaskRunMode::Deferred, async move {
task_wait(&task_lua, duration).await?; task_wait(&task_lua, duration).await?;
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?; let thread: LuaThread = task_lua.registry_value(&task_thread_key)?;
let argsv: Vec<LuaValue> = task_lua.registry_value(&task_args_key)?;
let args = LuaMultiValue::from_vec(argsv);
if thread.status() == LuaThreadStatus::Resumable { if thread.status() == LuaThreadStatus::Resumable {
thread.into_async::<_, LuaMultiValue>(()).await?; let _: LuaMultiValue = thread.into_async(args).await?;
} }
task_lua.remove_registry_value(task_thread_key)?; task_lua.remove_registry_value(task_thread_key)?;
task_lua.remove_registry_value(task_args_key)?;
Ok(()) Ok(())
}) })
.await?; .await?;
@ -98,19 +106,23 @@ async fn task_delay<'a>(
async fn task_spawn<'a>( async fn task_spawn<'a>(
lua: &'a Lua, lua: &'a Lua,
(tof, _args): (LuaValue<'a>, LuaMultiValue<'a>), (tof, args): (LuaValue<'a>, LuaMultiValue<'a>),
) -> LuaResult<LuaThread<'a>> { ) -> LuaResult<LuaThread<'a>> {
// Spawn a new detached task using a lua reference that we can use inside of our task // Spawn a new detached task using a lua reference that we can use inside of our task
let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap(); let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap();
let task_thread = tof_to_thread(lua, tof)?; let task_thread = tof_to_thread(lua, tof)?;
let task_thread_key = lua.create_registry_value(task_thread)?; let task_thread_key = lua.create_registry_value(task_thread)?;
let task_args_key = lua.create_registry_value(args.into_vec())?;
let lua_thread_to_return = lua.registry_value(&task_thread_key)?; let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
run_registered_task(lua, TaskRunMode::Instant, async move { run_registered_task(lua, TaskRunMode::Instant, async move {
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?; let thread: LuaThread = task_lua.registry_value(&task_thread_key)?;
let argsv: Vec<LuaValue> = task_lua.registry_value(&task_args_key)?;
let args = LuaMultiValue::from_vec(argsv);
if thread.status() == LuaThreadStatus::Resumable { if thread.status() == LuaThreadStatus::Resumable {
thread.into_async::<_, LuaMultiValue>(()).await?; let _: LuaMultiValue = thread.into_async(args).await?;
} }
task_lua.remove_registry_value(task_thread_key)?; task_lua.remove_registry_value(task_thread_key)?;
task_lua.remove_registry_value(task_args_key)?;
Ok(()) Ok(())
}) })
.await?; .await?;

View file

@ -40,10 +40,24 @@ assert(not flag2, "Defer should run after spawned threads")
-- Varargs should get passed correctly -- Varargs should get passed correctly
local function f(arg1: string, arg2: number, f2: (...any) -> ...any) local function fcheck(index: number, type: string, value: any)
assert(type(arg1) == "string", "Invalid arg 1 passed to function") if typeof(value) ~= type then
assert(type(arg2) == "number", "Invalid arg 2 passed to function") console.error(
assert(type(arg3) == "function", "Invalid arg 3 passed to function") string.format(
"Expected argument #%d to be of type %s, got %s",
index,
type,
console.format(value)
)
)
process.exit(1)
end
end
local function f(...: any)
fcheck(1, "string", select(1, ...))
fcheck(2, "number", select(2, ...))
fcheck(3, "function", select(3, ...))
end end
task.defer(f, "", 1, f) task.defer(f, "", 1, f)

View file

@ -28,10 +28,24 @@ assert(not flag2, "Delay should work with yielding (2)")
-- Varargs should get passed correctly -- Varargs should get passed correctly
local function f(arg1: string, arg2: number, f2: (...any) -> ...any) local function fcheck(index: number, type: string, value: any)
assert(type(arg1) == "string", "Invalid arg 1 passed to function") if typeof(value) ~= type then
assert(type(arg2) == "number", "Invalid arg 2 passed to function") console.error(
assert(type(arg3) == "function", "Invalid arg 3 passed to function") string.format(
"Expected argument #%d to be of type %s, got %s",
index,
type,
console.format(value)
)
)
process.exit(1)
end
end
local function f(...: any)
fcheck(1, "string", select(1, ...))
fcheck(2, "number", select(2, ...))
fcheck(3, "function", select(3, ...))
end end
task.delay(0, f, "", 1, f) task.delay(0, f, "", 1, f)

View file

@ -33,10 +33,24 @@ assert(flag3, "Spawn should run threads made from coroutine.create")
-- Varargs should get passed correctly -- Varargs should get passed correctly
local function f(arg1: string, arg2: number, f2: (...any) -> ...any) local function fcheck(index: number, type: string, value: any)
assert(type(arg1) == "string", "Invalid arg 1 passed to function") if typeof(value) ~= type then
assert(type(arg2) == "number", "Invalid arg 2 passed to function") console.error(
assert(type(arg3) == "function", "Invalid arg 3 passed to function") string.format(
"Expected argument #%d to be of type %s, got %s",
index,
type,
console.format(value)
)
)
process.exit(1)
end
end
local function f(...: any)
fcheck(1, "string", select(1, ...))
fcheck(2, "number", select(2, ...))
fcheck(3, "function", select(3, ...))
end end
task.spawn(f, "", 1, f) task.spawn(f, "", 1, f)