feat: Allow for multiple callbacks inside of an ActionCallback

This also results in the conversion being performed when the
ActionCallback is instantiated instead of when it is called, this should
make it easier to catch errors.
This commit is contained in:
2025-09-08 02:11:05 +02:00
parent e880efe4cf
commit 3be11b0c6a
2 changed files with 31 additions and 6 deletions

View File

@@ -1,11 +1,12 @@
use std::marker::PhantomData;
use futures::future::try_join_all;
use mlua::{FromLua, IntoLua, LuaSerdeExt};
use serde::Serialize;
#[derive(Debug, Clone)]
struct Internal {
value: mlua::Value,
callbacks: Vec<mlua::Function>,
lua: mlua::Lua,
}
@@ -28,9 +29,28 @@ impl<T, S> Default for ActionCallback<T, S> {
impl<T, S> FromLua for ActionCallback<T, S> {
fn from_lua(value: mlua::Value, lua: &mlua::Lua) -> mlua::Result<Self> {
let callbacks = match value {
mlua::Value::Function(f) => vec![f],
mlua::Value::Table(table) => table
.pairs::<mlua::Value, mlua::Function>()
.map(|pair| {
let (_, f) = pair?;
Ok::<_, mlua::Error>(f)
})
.try_collect()?,
_ => {
return Err(mlua::Error::FromLuaConversionError {
from: value.type_name(),
to: "ActionCallback".into(),
message: Some("expected function or table of functions".into()),
});
}
};
Ok(ActionCallback {
internal: Some(Internal {
value,
callbacks,
lua: lua.clone(),
}),
_this: PhantomData::<T>,
@@ -52,10 +72,14 @@ where
let state = internal.lua.to_value(state).unwrap();
match &internal.value {
mlua::Value::Function(f) => f.call_async::<()>((this.clone(), state)).await.unwrap(),
_ => todo!("Only functions are currently supported"),
}
try_join_all(
internal
.callbacks
.iter()
.map(async |f| f.call_async::<()>((this.clone(), state.clone())).await),
)
.await
.unwrap();
}
pub fn is_set(&self) -> bool {

View File

@@ -1,4 +1,5 @@
#![allow(incomplete_features)]
#![feature(iterator_try_collect)]
pub mod action_callback;
pub mod config;