Fix #19: Lua crashes when spawning entities in optimized builds #27
|
@ -2062,22 +2062,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mlua"
|
name = "mlua"
|
||||||
version = "0.9.9"
|
version = "0.10.0-beta.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/mlua-rs/mlua?rev=4dddf3c18d4590f7c92214fa592c3faca3d2c812#4dddf3c18d4590f7c92214fa592c3faca3d2c812"
|
||||||
checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"mlua-sys",
|
"mlua-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"once_cell",
|
"parking_lot",
|
||||||
"rustc-hash 2.0.0",
|
"rustc-hash 2.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mlua-sys"
|
name = "mlua-sys"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/mlua-rs/mlua?rev=4dddf3c18d4590f7c92214fa592c3faca3d2c812#4dddf3c18d4590f7c92214fa592c3faca3d2c812"
|
||||||
checksum = "ebe026d6bd1583a9cf9080e189030ddaea7e6f5f0deb366a8e26f8a26c4135b8"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
---Return the userdata's name from its metatable
|
---Return the userdata's name from its metatable.
|
||||||
|
---
|
||||||
|
---Returns nil if the userdata doesn't have a metatable.
|
||||||
---@param val userdata
|
---@param val userdata
|
||||||
---@return string
|
---@return string|nil
|
||||||
function udname(val)
|
function udname(val)
|
||||||
local tbl = getmetatable(val)
|
local tbl = debug.getmetatable(val)
|
||||||
if type(tbl) == "boolean" then
|
|
||||||
error("what, got a boolean??: " .. tostring(tbl), 1)
|
if tbl == nil then
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return tbl.__name
|
return tbl.__name
|
||||||
|
@ -15,14 +18,14 @@ function on_init()
|
||||||
local cube = world:request_res("../assets/cube-texture-embedded.gltf")
|
local cube = world:request_res("../assets/cube-texture-embedded.gltf")
|
||||||
print("Loaded textured cube (" .. udname(cube) .. ")")
|
print("Loaded textured cube (" .. udname(cube) .. ")")
|
||||||
|
|
||||||
--[[ cube:wait_until_loaded()
|
cube:wait_until_loaded()
|
||||||
local scenes = cube:scenes()
|
local scenes = cube:scenes()
|
||||||
local cube_scene = scenes[1]
|
local cube_scene = scenes[1]
|
||||||
|
|
||||||
local pos = Transform.from_translation(Vec3.new(0, 0, -8.0))
|
local pos = Transform.from_translation(Vec3.new(0, 0, -8.0))
|
||||||
|
|
||||||
local e = world:spawn(pos, cube_scene)
|
local e = world:spawn(pos, cube_scene)
|
||||||
print("spawned entity " .. tostring(e)) ]]
|
print("spawned entity " .. tostring(e))
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[ function on_first()
|
--[[ function on_first()
|
||||||
|
|
|
@ -22,7 +22,9 @@ tracing = "0.1.37"
|
||||||
atomic_refcell = "0.1.13"
|
atomic_refcell = "0.1.13"
|
||||||
|
|
||||||
# enabled with lua feature
|
# enabled with lua feature
|
||||||
mlua = { version = "0.9.9", features = ["lua54", "send"], optional = true } # luajit maybe?
|
#
|
||||||
|
#mlua = { version = "0.9.9", features = ["lua54", "send"], optional = true } # luajit maybe?
|
||||||
|
mlua = { git = "https://github.com/mlua-rs/mlua", rev = "4dddf3c18d4590f7c92214fa592c3faca3d2c812", features = ["lua54", "send"], optional = true } # luajit maybe?
|
||||||
#elua = { path = "./elua", optional = true }
|
#elua = { path = "./elua", optional = true }
|
||||||
itertools = "0.12.0"
|
itertools = "0.12.0"
|
||||||
paste = "1.0.14"
|
paste = "1.0.14"
|
||||||
|
|
|
@ -187,7 +187,7 @@ pub(crate) fn lua_wrap_handle_impl(input: proc_macro::TokenStream) -> proc_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mlua::UserData for #wrapper_name {
|
impl mlua::UserData for #wrapper_name {
|
||||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("path", |_, this| Ok(this.path()));
|
fields.add_field_method_get("path", |_, this| Ok(this.path()));
|
||||||
fields.add_field_method_get("version", |_, this| Ok(this.version()));
|
fields.add_field_method_get("version", |_, this| Ok(this.version()));
|
||||||
fields.add_field_method_get("uuid", |_, this| Ok(this.uuid().to_string()));
|
fields.add_field_method_get("uuid", |_, this| Ok(this.uuid().to_string()));
|
||||||
|
@ -204,7 +204,7 @@ pub(crate) fn lua_wrap_handle_impl(input: proc_macro::TokenStream) -> proc_macro
|
||||||
#(#custom_getters)*
|
#(#custom_getters)*
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_method("is_watched", |_, this, ()| {
|
methods.add_method("is_watched", |_, this, ()| {
|
||||||
Ok(this.is_watched())
|
Ok(this.is_watched())
|
||||||
});
|
});
|
||||||
|
@ -234,8 +234,8 @@ pub(crate) fn lua_wrap_handle_impl(input: proc_macro::TokenStream) -> proc_macro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> mlua::FromLua<'a> for #wrapper_name {
|
impl mlua::FromLua for #wrapper_name {
|
||||||
fn from_lua(val: mlua::Value<'a>, _: &'a mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
let tyname = val.type_name();
|
let tyname = val.type_name();
|
||||||
let ud = val.as_userdata()
|
let ud = val.as_userdata()
|
||||||
.ok_or(mlua::Error::external(crate::lua::Error::type_mismatch(#ud_name, &tyname)))?;
|
.ok_or(mlua::Error::external(crate::lua::Error::type_mismatch(#ud_name, &tyname)))?;
|
||||||
|
|
|
@ -480,8 +480,8 @@ pub fn wrap_lua_struct_impl(input: proc_macro::TokenStream) -> proc_macro::Token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> mlua::FromLua<'lua> for #wrapper_typename {
|
impl mlua::FromLua for #wrapper_typename {
|
||||||
fn from_lua(value: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
match value {
|
match value {
|
||||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||||
_ => panic!("Attempt to get {} from a {} value", stringify!(#wrapper_typename), value.type_name()),
|
_ => panic!("Attempt to get {} from a {} value", stringify!(#wrapper_typename), value.type_name()),
|
||||||
|
@ -490,11 +490,11 @@ pub fn wrap_lua_struct_impl(input: proc_macro::TokenStream) -> proc_macro::Token
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mlua::UserData for #wrapper_typename {
|
impl mlua::UserData for #wrapper_typename {
|
||||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||||
#(#field_get_set_pairs)*
|
#(#field_get_set_pairs)*
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
#lua_reflects
|
#lua_reflects
|
||||||
|
|
||||||
#new_func_tokens
|
#new_func_tokens
|
||||||
|
|
|
@ -9,16 +9,16 @@ use super::ReflectLuaProxy;
|
||||||
use crate::ScriptWorldPtr;
|
use crate::ScriptWorldPtr;
|
||||||
|
|
||||||
#[cfg(feature = "lua")]
|
#[cfg(feature = "lua")]
|
||||||
pub struct ReflectedItem<'a> {
|
pub struct ReflectedItem {
|
||||||
//pub proxy: &'a ReflectLuaProxy,
|
//pub proxy: &'a ReflectLuaProxy,
|
||||||
pub comp_ptr: NonNull<u8>,
|
pub comp_ptr: NonNull<u8>,
|
||||||
pub comp_val: mlua::Value<'a>,
|
pub comp_val: mlua::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "lua")]
|
#[cfg(feature = "lua")]
|
||||||
pub struct ReflectedRow<'a> {
|
pub struct ReflectedRow {
|
||||||
pub entity: Entity,
|
pub entity: Entity,
|
||||||
pub row: Vec<ReflectedItem<'a>>,
|
pub row: Vec<ReflectedItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ReflectedIterator {
|
pub struct ReflectedIterator {
|
||||||
|
@ -29,7 +29,7 @@ pub struct ReflectedIterator {
|
||||||
|
|
||||||
impl ReflectedIterator {
|
impl ReflectedIterator {
|
||||||
#[cfg(feature = "lua")]
|
#[cfg(feature = "lua")]
|
||||||
pub fn next_lua<'a>(&mut self, lua: &'a mlua::Lua) -> Option<ReflectedRow<'a>> {
|
pub fn next_lua<'a>(&mut self, lua: &'a mlua::Lua) -> Option<ReflectedRow> {
|
||||||
use mlua::IntoLua;
|
use mlua::IntoLua;
|
||||||
|
|
||||||
let world = self.world.read();
|
let world = self.world.read();
|
||||||
|
|
|
@ -2,7 +2,7 @@ pub mod dynamic_iter;
|
||||||
pub use dynamic_iter::*;
|
pub use dynamic_iter::*;
|
||||||
|
|
||||||
pub mod world;
|
pub mod world;
|
||||||
use mlua::AnyUserDataExt;
|
use mlua::ObjectLike;
|
||||||
pub use world::*;
|
pub use world::*;
|
||||||
|
|
||||||
pub mod script;
|
pub mod script;
|
||||||
|
@ -113,24 +113,24 @@ pub trait RegisterLuaType {
|
||||||
/// Register a type to Lua that **is not wrapped**.
|
/// Register a type to Lua that **is not wrapped**.
|
||||||
fn register_lua_type<'a, T>(&mut self)
|
fn register_lua_type<'a, T>(&mut self)
|
||||||
where
|
where
|
||||||
T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData;
|
T: Reflect + LuaProxy + Clone + mlua::FromLua + mlua::UserData;
|
||||||
|
|
||||||
/// Registers a type to Lua that is wrapped another type.
|
/// Registers a type to Lua that is wrapped another type.
|
||||||
/// This would be used for something like `UserdataRef<T>`.
|
/// This would be used for something like `UserdataRef<T>`.
|
||||||
fn register_lua_wrapper<'a, W>(&mut self)
|
fn register_lua_wrapper<'a, W>(&mut self)
|
||||||
where
|
where
|
||||||
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData;
|
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua + mlua::UserData;
|
||||||
|
|
||||||
/// Registers a type to Lua that can be converted into and from Lua types.
|
/// Registers a type to Lua that can be converted into and from Lua types.
|
||||||
fn register_lua_convert<T>(&mut self)
|
fn register_lua_convert<T>(&mut self)
|
||||||
where
|
where
|
||||||
T: Clone + for<'a> mlua::FromLua<'a> + for<'a> mlua::IntoLua<'a> + LuaWrapper + 'static;
|
T: Clone + mlua::FromLua + mlua::IntoLua + LuaWrapper + 'static;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegisterLuaType for World {
|
impl RegisterLuaType for World {
|
||||||
fn register_lua_type<'a, T>(&mut self)
|
fn register_lua_type<'a, T>(&mut self)
|
||||||
where
|
where
|
||||||
T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData
|
T: Reflect + LuaProxy + Clone + mlua::FromLua + mlua::UserData
|
||||||
{
|
{
|
||||||
let mut registry = self.get_resource_mut::<TypeRegistry>().unwrap();
|
let mut registry = self.get_resource_mut::<TypeRegistry>().unwrap();
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ impl RegisterLuaType for World {
|
||||||
|
|
||||||
fn register_lua_wrapper<'a, W>(&mut self)
|
fn register_lua_wrapper<'a, W>(&mut self)
|
||||||
where
|
where
|
||||||
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData
|
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua + mlua::UserData
|
||||||
{
|
{
|
||||||
let mut registry = self.get_resource_mut::<TypeRegistry>().unwrap();
|
let mut registry = self.get_resource_mut::<TypeRegistry>().unwrap();
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ impl RegisterLuaType for World {
|
||||||
|
|
||||||
fn register_lua_convert<T>(&mut self)
|
fn register_lua_convert<T>(&mut self)
|
||||||
where
|
where
|
||||||
T: Clone + for<'a> mlua::FromLua<'a> + for<'a> mlua::IntoLua<'a> + LuaWrapper + 'static,
|
T: Clone + mlua::FromLua + mlua::IntoLua + LuaWrapper + 'static,
|
||||||
{
|
{
|
||||||
let mut registry = self.get_resource_mut::<TypeRegistry>().unwrap();
|
let mut registry = self.get_resource_mut::<TypeRegistry>().unwrap();
|
||||||
|
|
||||||
|
@ -161,8 +161,8 @@ impl RegisterLuaType for World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> mlua::FromLua<'lua> for ScriptBorrow {
|
impl mlua::FromLua for ScriptBorrow {
|
||||||
fn from_lua(value: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
match value {
|
match value {
|
||||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -176,6 +176,6 @@ impl mlua::UserData for ScriptBorrow {
|
||||||
|
|
||||||
/// Helper function used for reflecting userdata as a ScriptBorrow
|
/// Helper function used for reflecting userdata as a ScriptBorrow
|
||||||
pub fn reflect_user_data(ud: &mlua::AnyUserData) -> ScriptBorrow {
|
pub fn reflect_user_data(ud: &mlua::AnyUserData) -> ScriptBorrow {
|
||||||
ud.call_method::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())
|
ud.call_method::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())
|
||||||
.expect("Type does not implement internal reflect method properly")
|
.expect("Type does not implement internal reflect method properly")
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::{Arc, Mutex};
|
use std::{ops::Deref, sync::{Arc, Mutex}};
|
||||||
|
|
||||||
use mlua::AnyUserDataExt;
|
use mlua::{AnyUserData, ObjectLike};
|
||||||
use tracing::{debug, debug_span};
|
use tracing::{debug, debug_span};
|
||||||
|
|
||||||
use crate::{ScriptApiProvider, ScriptData};
|
use crate::{ScriptApiProvider, ScriptData};
|
||||||
|
@ -58,9 +58,9 @@ impl ScriptApiProvider for UtilityApiProvider {
|
||||||
},
|
},
|
||||||
mlua::Value::UserData(ud) => {
|
mlua::Value::UserData(ud) => {
|
||||||
if let Ok(tos) =
|
if let Ok(tos) =
|
||||||
ud.get::<_, mlua::Function>(mlua::MetaMethod::ToString.name())
|
ud.get::<mlua::Function>(mlua::MetaMethod::ToString.name())
|
||||||
{
|
{
|
||||||
tos.call::<_, String>(())?
|
tos.call::<String>(())?
|
||||||
} else {
|
} else {
|
||||||
return Err(mlua::Error::runtime(
|
return Err(mlua::Error::runtime(
|
||||||
"UserData does not implement MetaMethod '__tostring'",
|
"UserData does not implement MetaMethod '__tostring'",
|
||||||
|
@ -73,7 +73,7 @@ impl ScriptApiProvider for UtilityApiProvider {
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
mlua::Value::Error(error) => {
|
mlua::Value::Error(error) => {
|
||||||
return Err(error.clone());
|
return Err(error.deref().clone());
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
@ -123,8 +123,8 @@ impl ScriptApiProvider for UtilityApiProvider {
|
||||||
formatted = format!("{}{}", formatted, text);
|
formatted = format!("{}{}", formatted, text);
|
||||||
|
|
||||||
lua.globals()
|
lua.globals()
|
||||||
.get::<_, mlua::Function>("print")?
|
.get::<mlua::Function>("print")?
|
||||||
.call::<_, ()>(formatted)?;
|
.call::<()>(formatted)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
@ -141,9 +141,24 @@ impl ScriptApiProvider for UtilityApiProvider {
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
// a custom implementation of `getmetatable` is required since mlua protects __metatable,
|
||||||
|
// making it impossible to get the metatable of userdata.
|
||||||
|
let getmetatable_func = ctx.create_function(|lua, ud: AnyUserData| {
|
||||||
|
// the userdata is left on the stack from `lua_getmetatable`, so that needs to be
|
||||||
|
// included in the returns
|
||||||
|
let (_ud, table): (mlua::AnyUserData, mlua::Table) = unsafe {
|
||||||
|
lua.exec_raw(ud, |state| {
|
||||||
|
mlua::ffi::lua_getmetatable(state, -1);
|
||||||
|
})
|
||||||
|
}?;
|
||||||
|
|
||||||
|
Ok(table)
|
||||||
|
})?;
|
||||||
|
|
||||||
let globals = ctx.globals();
|
let globals = ctx.globals();
|
||||||
globals.set("printf", printf_func)?;
|
globals.set("printf", printf_func)?;
|
||||||
globals.set("print", print_func)?;
|
globals.set("print", print_func)?;
|
||||||
|
globals.set("getmetatable2", getmetatable_func)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{any::TypeId, collections::HashMap, ptr::NonNull};
|
use std::{any::TypeId, collections::HashMap, ptr::NonNull};
|
||||||
|
|
||||||
use mlua::{AnyUserDataExt, IntoLua};
|
use mlua::{ObjectLike, IntoLua};
|
||||||
use lyra_ecs::{ComponentInfo, DynamicBundle};
|
use lyra_ecs::{ComponentInfo, DynamicBundle};
|
||||||
use lyra_reflect::Reflect;
|
use lyra_reflect::Reflect;
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@ pub trait LuaWrapper {
|
||||||
|
|
||||||
/// A trait that used to convert something into lua, or to set something to a value from lua.
|
/// A trait that used to convert something into lua, or to set something to a value from lua.
|
||||||
pub trait LuaProxy {
|
pub trait LuaProxy {
|
||||||
fn as_lua_value<'lua>(
|
fn as_lua_value(
|
||||||
lua: &'lua mlua::Lua,
|
lua: &mlua::Lua,
|
||||||
this: &dyn Reflect,
|
this: &dyn Reflect,
|
||||||
) -> mlua::Result<mlua::Value<'lua>>;
|
) -> mlua::Result<mlua::Value>;
|
||||||
|
|
||||||
fn apply(
|
fn apply(
|
||||||
lua: &mlua::Lua,
|
lua: &mlua::Lua,
|
||||||
|
@ -29,12 +29,12 @@ pub trait LuaProxy {
|
||||||
|
|
||||||
impl<'a, T> LuaProxy for T
|
impl<'a, T> LuaProxy for T
|
||||||
where
|
where
|
||||||
T: Reflect + Clone + mlua::FromLua<'a> + mlua::UserData
|
T: Reflect + Clone + mlua::FromLua + mlua::UserData
|
||||||
{
|
{
|
||||||
fn as_lua_value<'lua>(
|
fn as_lua_value(
|
||||||
lua: &'lua mlua::Lua,
|
lua: &mlua::Lua,
|
||||||
this: &dyn Reflect,
|
this: &dyn Reflect,
|
||||||
) -> mlua::Result<mlua::Value<'lua>> {
|
) -> mlua::Result<mlua::Value> {
|
||||||
let this = this.as_any().downcast_ref::<T>().unwrap();
|
let this = this.as_any().downcast_ref::<T>().unwrap();
|
||||||
lua.create_userdata(this.clone())
|
lua.create_userdata(this.clone())
|
||||||
.and_then(|ud| ud.into_lua(lua))
|
.and_then(|ud| ud.into_lua(lua))
|
||||||
|
@ -67,11 +67,11 @@ pub struct LuaTableProxyLookup {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ReflectLuaProxy {
|
pub struct ReflectLuaProxy {
|
||||||
pub fn_as_lua:
|
pub fn_as_lua:
|
||||||
for<'a> fn(lua: &'a mlua::Lua, this_ptr: NonNull<()>) -> mlua::Result<mlua::Value<'a>>,
|
for<'a> fn(lua: &'a mlua::Lua, this_ptr: NonNull<()>) -> mlua::Result<mlua::Value>,
|
||||||
pub fn_apply: for<'a> fn(
|
pub fn_apply: for<'a> fn(
|
||||||
lua: &'a mlua::Lua,
|
lua: &'a mlua::Lua,
|
||||||
this_ptr: NonNull<()>,
|
this_ptr: NonNull<()>,
|
||||||
value: &'a mlua::Value<'a>,
|
value: &'a mlua::Value,
|
||||||
) -> mlua::Result<()>,
|
) -> mlua::Result<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ impl ReflectLuaProxy {
|
||||||
/// Create from a type that implements FromLua and AsLua
|
/// Create from a type that implements FromLua and AsLua
|
||||||
pub fn from_as_and_from_lua<T>() -> Self
|
pub fn from_as_and_from_lua<T>() -> Self
|
||||||
where
|
where
|
||||||
T: for<'a> mlua::FromLua<'a> + for<'a> mlua::IntoLua<'a> + Clone
|
T: mlua::FromLua + mlua::IntoLua + Clone
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
fn_as_lua: |lua, this| -> mlua::Result<mlua::Value> {
|
fn_as_lua: |lua, this| -> mlua::Result<mlua::Value> {
|
||||||
|
@ -115,8 +115,8 @@ impl ReflectLuaProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> mlua::FromLua<'lua> for ScriptDynamicBundle {
|
impl mlua::FromLua for ScriptDynamicBundle {
|
||||||
fn from_lua(val: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
match val {
|
match val {
|
||||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||||
mlua::Value::Nil => Err(Error::Nil.into()),
|
mlua::Value::Nil => Err(Error::Nil.into()),
|
||||||
|
@ -126,10 +126,10 @@ impl<'lua> mlua::FromLua<'lua> for ScriptDynamicBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mlua::UserData for ScriptDynamicBundle {
|
impl mlua::UserData for ScriptDynamicBundle {
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_function("new", |_, ()| Ok(ScriptDynamicBundle(DynamicBundle::new())));
|
methods.add_function("new", |_, ()| Ok(ScriptDynamicBundle(DynamicBundle::new())));
|
||||||
methods.add_method_mut("push", |_, this, comp: mlua::AnyUserData| {
|
methods.add_method_mut("push", |_, this, comp: mlua::AnyUserData| {
|
||||||
let script_brw = comp.call_method::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?;
|
let script_brw = comp.call_method::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?;
|
||||||
let reflect = script_brw.reflect_branch.as_component_unchecked();
|
let reflect = script_brw.reflect_branch.as_component_unchecked();
|
||||||
|
|
||||||
let refl_data = script_brw.data.unwrap();
|
let refl_data = script_brw.data.unwrap();
|
||||||
|
|
|
@ -11,8 +11,8 @@ fn try_call_lua_function(lua: &mlua::Lua, fn_name: &str) -> Result<(), ScriptErr
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
|
||||||
if globals.contains_key(fn_name)? {
|
if globals.contains_key(fn_name)? {
|
||||||
let lua_fn = globals.get::<_, mlua::Function>(fn_name)?;
|
let lua_fn = globals.get::<mlua::Function>(fn_name)?;
|
||||||
lua_fn.call::<_, ()>(())
|
lua_fn.call::<()>(())
|
||||||
.map_err(ScriptError::from)?;
|
.map_err(ScriptError::from)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ impl ScriptHost for LuaHost {
|
||||||
let mut ctx = Mutex::new({
|
let mut ctx = Mutex::new({
|
||||||
// unsafe is required to allow the debug module
|
// unsafe is required to allow the debug module
|
||||||
let s = unsafe { mlua::Lua::unsafe_new() };
|
let s = unsafe { mlua::Lua::unsafe_new() };
|
||||||
s.load_from_std_lib(StdLib::ALL)?;
|
s.load_std_libs(StdLib::ALL)?;
|
||||||
s
|
s
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@ use lyra_ecs::{
|
||||||
};
|
};
|
||||||
use lyra_reflect::{ReflectWorldExt, RegisteredType, TypeRegistry};
|
use lyra_reflect::{ReflectWorldExt, RegisteredType, TypeRegistry};
|
||||||
use lyra_resource::ResourceManager;
|
use lyra_resource::ResourceManager;
|
||||||
use mlua::{AnyUserDataExt, IntoLua};
|
use mlua::{IntoLua, ObjectLike};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
reflect_user_data, wrappers::LuaResHandleToComponent, Error, LuaTableProxyLookup, ReflectLuaProxy, ReflectedIterator, FN_NAME_INTERNAL_AS_COMPONENT, FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE
|
reflect_user_data, wrappers::LuaResHandleToComponent, Error, LuaTableProxyLookup, ReflectLuaProxy, ReflectedIterator, FN_NAME_INTERNAL_AS_COMPONENT, FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'lua> mlua::FromLua<'lua> for ScriptEntity {
|
impl mlua::FromLua for ScriptEntity {
|
||||||
fn from_lua(value: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
match value {
|
match value {
|
||||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||||
mlua::Value::Nil => Err(mlua::Error::external(Error::type_mismatch("ScriptEntity", "Nil"))),
|
mlua::Value::Nil => Err(mlua::Error::external(Error::type_mismatch("ScriptEntity", "Nil"))),
|
||||||
|
@ -24,7 +24,7 @@ impl<'lua> mlua::FromLua<'lua> for ScriptEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mlua::UserData for ScriptEntity {
|
impl mlua::UserData for ScriptEntity {
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_meta_method(mlua::MetaMethod::ToString, |_, this, ()| {
|
methods.add_meta_method(mlua::MetaMethod::ToString, |_, this, ()| {
|
||||||
Ok(format!("{:?}", this.0))
|
Ok(format!("{:?}", this.0))
|
||||||
});
|
});
|
||||||
|
@ -37,8 +37,8 @@ pub enum WorldError {
|
||||||
LuaInvalidUsage(String),
|
LuaInvalidUsage(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> mlua::FromLua<'lua> for ScriptWorldPtr {
|
impl mlua::FromLua for ScriptWorldPtr {
|
||||||
fn from_lua(val: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
match val {
|
match val {
|
||||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||||
mlua::Value::Nil => Err(mlua::Error::external(Error::type_mismatch("ScriptWorldPtr", "Nil"))),
|
mlua::Value::Nil => Err(mlua::Error::external(Error::type_mismatch("ScriptWorldPtr", "Nil"))),
|
||||||
|
@ -48,7 +48,7 @@ impl<'lua> mlua::FromLua<'lua> for ScriptWorldPtr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mlua::UserData for ScriptWorldPtr {
|
impl mlua::UserData for ScriptWorldPtr {
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_method_mut("spawn", |_, this, vals: mlua::MultiValue| {
|
methods.add_method_mut("spawn", |_, this, vals: mlua::MultiValue| {
|
||||||
let mut world = this.write();
|
let mut world = this.write();
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let comp_borrow = {
|
let comp_borrow = {
|
||||||
if let Ok(as_comp) = ud.get::<_, mlua::Function>(FN_NAME_INTERNAL_AS_COMPONENT)
|
if let Ok(as_comp) = ud.get::<mlua::Function>(FN_NAME_INTERNAL_AS_COMPONENT)
|
||||||
{
|
{
|
||||||
let ud = match as_comp.call(ud.clone())? {
|
let ud = match as_comp.call(ud.clone())? {
|
||||||
mlua::Value::UserData(ud) => ud,
|
mlua::Value::UserData(ud) => ud,
|
||||||
|
@ -72,9 +72,9 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
ud.call_method::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?
|
ud.call_method::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?
|
||||||
} else {
|
} else {
|
||||||
ud.call_method::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?
|
ud.call_method::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
}
|
}
|
||||||
mlua::Value::UserData(ud) => {
|
mlua::Value::UserData(ud) => {
|
||||||
let reflect = ud
|
let reflect = ud
|
||||||
.call_function::<_, ScriptBorrow>(
|
.call_function::<ScriptBorrow>(
|
||||||
FN_NAME_INTERNAL_REFLECT_TYPE,
|
FN_NAME_INTERNAL_REFLECT_TYPE,
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
|
@ -164,14 +164,13 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
let mut has_ticked = false;
|
let mut has_ticked = false;
|
||||||
|
|
||||||
while let Some(row) = reflected_iter.next_lua(lua) {
|
while let Some(row) = reflected_iter.next_lua(lua) {
|
||||||
let r = row
|
let r = row.row.into_iter()
|
||||||
.row
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| (r.comp_val, r.comp_ptr.cast::<()>()))
|
.map(|r| (r.comp_val, r.comp_ptr.cast::<()>()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let (values, ptrs) =
|
let (values, ptrs) =
|
||||||
itertools::multiunzip::<(Vec<mlua::Value>, Vec<NonNull<()>>), _>(r);
|
itertools::multiunzip::<(Vec<mlua::Value>, Vec<NonNull<()>>), _>(r);
|
||||||
let mult_val = mlua::MultiValue::from_vec(values);
|
let mult_val = mlua::MultiValue::from_iter(values.into_iter());
|
||||||
let res: mlua::MultiValue = system.call(mult_val)?;
|
let res: mlua::MultiValue = system.call(mult_val)?;
|
||||||
|
|
||||||
// if values were returned, find the type in the type registry, and apply the new values
|
// if values were returned, find the type in the type registry, and apply the new values
|
||||||
|
@ -236,11 +235,11 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
methods.add_method_mut("resource", |lua, this, (ty,): (mlua::Value,)| {
|
methods.add_method_mut("resource", |lua, this, (ty,): (mlua::Value,)| {
|
||||||
let reflect = match ty {
|
let reflect = match ty {
|
||||||
mlua::Value::UserData(ud) => ud
|
mlua::Value::UserData(ud) => ud
|
||||||
.call_function::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT_TYPE, ())
|
.call_function::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT_TYPE, ())
|
||||||
.expect("Type does not implement 'reflect_type' properly"),
|
.expect("Type does not implement 'reflect_type' properly"),
|
||||||
mlua::Value::Table(t) => {
|
mlua::Value::Table(t) => {
|
||||||
let f: mlua::Function = t.get(FN_NAME_INTERNAL_REFLECT_TYPE)?;
|
let f: mlua::Function = t.get(FN_NAME_INTERNAL_REFLECT_TYPE)?;
|
||||||
f.call::<_, ScriptBorrow>(())
|
f.call::<ScriptBorrow>(())
|
||||||
.expect("Type does not implement 'reflect_type' properly")
|
.expect("Type does not implement 'reflect_type' properly")
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -248,7 +247,7 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/* let reflect = ty
|
/* let reflect = ty
|
||||||
.execute_function::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT_TYPE, ())
|
.execute_function::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT_TYPE, ())
|
||||||
.expect("Type does not implement 'reflect_type' properly"); */
|
.expect("Type does not implement 'reflect_type' properly"); */
|
||||||
|
|
||||||
let mut world = this.write();
|
let mut world = this.write();
|
||||||
|
@ -270,11 +269,11 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
methods.add_method_mut("add_resource", |_, this, res: mlua::Value| {
|
methods.add_method_mut("add_resource", |_, this, res: mlua::Value| {
|
||||||
let reflect = match res {
|
let reflect = match res {
|
||||||
mlua::Value::UserData(ud) => ud
|
mlua::Value::UserData(ud) => ud
|
||||||
.call_method::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())
|
.call_method::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())
|
||||||
.expect("Type does not implement 'reflect_type' properly"),
|
.expect("Type does not implement 'reflect_type' properly"),
|
||||||
mlua::Value::Table(t) => {
|
mlua::Value::Table(t) => {
|
||||||
let f: mlua::Function = t.get(FN_NAME_INTERNAL_REFLECT)?;
|
let f: mlua::Function = t.get(FN_NAME_INTERNAL_REFLECT)?;
|
||||||
f.call::<_, ScriptBorrow>(())
|
f.call::<ScriptBorrow>(())
|
||||||
.expect("Type does not implement 'reflect_type' properly")
|
.expect("Type does not implement 'reflect_type' properly")
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -56,7 +56,7 @@ impl From<UntypedResHandle> for LuaResHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mlua::UserData for LuaResHandle {
|
impl mlua::UserData for LuaResHandle {
|
||||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("path", |_, this| Ok(this.path()));
|
fields.add_field_method_get("path", |_, this| Ok(this.path()));
|
||||||
fields.add_field_method_get("version", |_, this| Ok(this.version()));
|
fields.add_field_method_get("version", |_, this| Ok(this.version()));
|
||||||
fields.add_field_method_get("uuid", |_, this| Ok(this.uuid().to_string()));
|
fields.add_field_method_get("uuid", |_, this| Ok(this.uuid().to_string()));
|
||||||
|
@ -71,7 +71,7 @@ impl mlua::UserData for LuaResHandle {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_method("is_watched", |_, this, ()| {
|
methods.add_method("is_watched", |_, this, ()| {
|
||||||
Ok(this.is_watched())
|
Ok(this.is_watched())
|
||||||
});
|
});
|
||||||
|
@ -100,8 +100,8 @@ impl mlua::UserData for LuaResHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> mlua::FromLua<'a> for LuaResHandle {
|
impl mlua::FromLua for LuaResHandle {
|
||||||
fn from_lua(val: mlua::Value<'a>, _: &'a mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
let tyname = val.type_name();
|
let tyname = val.type_name();
|
||||||
let ud = val.as_userdata()
|
let ud = val.as_userdata()
|
||||||
.ok_or(mlua::Error::external(Error::type_mismatch("Handle", &tyname)))?;
|
.ok_or(mlua::Error::external(Error::type_mismatch("Handle", &tyname)))?;
|
||||||
|
|
|
@ -21,14 +21,14 @@ impl std::ops::DerefMut for LuaDeltaTime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> mlua::FromLua<'lua> for LuaDeltaTime {
|
impl mlua::FromLua for LuaDeltaTime {
|
||||||
fn from_lua(_: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(_: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> mlua::IntoLua<'lua> for LuaDeltaTime {
|
impl mlua::IntoLua for LuaDeltaTime {
|
||||||
fn into_lua(self, _: &'lua mlua::Lua) -> mlua::Result<mlua::Value<'lua>> {
|
fn into_lua(self, _: &mlua::Lua) -> mlua::Result<mlua::Value> {
|
||||||
Ok(mlua::Value::Number(*self.0 as f64))
|
Ok(mlua::Value::Number(*self.0 as f64))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,12 @@ pub struct LuaActionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mlua::UserData for LuaActionHandler {
|
impl mlua::UserData for LuaActionHandler {
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_function("new", |_, table: mlua::Table| {
|
methods.add_function("new", |_, table: mlua::Table| {
|
||||||
let mut handler = ActionHandler::new();
|
let mut handler = ActionHandler::new();
|
||||||
|
|
||||||
// create the layouts and add them to the handler
|
// create the layouts and add them to the handler
|
||||||
let layouts = table.get::<_, mlua::Table>("layouts")
|
let layouts = table.get::<mlua::Table>("layouts")
|
||||||
.map_err(|_| mlua::Error::runtime("missing 'layouts' in ActionHandler table"))?;
|
.map_err(|_| mlua::Error::runtime("missing 'layouts' in ActionHandler table"))?;
|
||||||
for layout_id in layouts.sequence_values::<u32>() {
|
for layout_id in layouts.sequence_values::<u32>() {
|
||||||
let layout_id = layout_id?;
|
let layout_id = layout_id?;
|
||||||
|
@ -26,7 +26,7 @@ impl mlua::UserData for LuaActionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the actions to the handler
|
// add the actions to the handler
|
||||||
let actions = table.get::<_, mlua::Table>("actions")
|
let actions = table.get::<mlua::Table>("actions")
|
||||||
.map_err(|_| mlua::Error::runtime("missing 'actions' in ActionHandler table"))?;
|
.map_err(|_| mlua::Error::runtime("missing 'actions' in ActionHandler table"))?;
|
||||||
for pair in actions.pairs::<String, String>() {
|
for pair in actions.pairs::<String, String>() {
|
||||||
let (action_lbl, action_type) = pair?;
|
let (action_lbl, action_type) = pair?;
|
||||||
|
@ -42,17 +42,17 @@ impl mlua::UserData for LuaActionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the mappings and start processing them
|
// find the mappings and start processing them
|
||||||
let mappings= table.get::<_, mlua::Table>("mappings")
|
let mappings= table.get::<mlua::Table>("mappings")
|
||||||
.map_err(|_| mlua::Error::runtime("missing 'mappings' in ActionHandler table"))?;
|
.map_err(|_| mlua::Error::runtime("missing 'mappings' in ActionHandler table"))?;
|
||||||
for (map_id, tbl) in mappings.sequence_values::<mlua::Table>().enumerate() {
|
for (map_id, tbl) in mappings.sequence_values::<mlua::Table>().enumerate() {
|
||||||
let tbl = tbl?;
|
let tbl = tbl?;
|
||||||
|
|
||||||
let layout_id = tbl.get::<_, u32>("layout")?;
|
let layout_id = tbl.get::<u32>("layout")?;
|
||||||
let mut mapping = ActionMapping::new(LayoutId(layout_id), ActionMappingId(map_id as u32));
|
let mut mapping = ActionMapping::new(LayoutId(layout_id), ActionMappingId(map_id as u32));
|
||||||
|
|
||||||
// find the binds and start processing them
|
// find the binds and start processing them
|
||||||
// the keys are used as the action names, and then the value is an array (lua table)
|
// the keys are used as the action names, and then the value is an array (lua table)
|
||||||
let binds_tbl = tbl.get::<_, mlua::Table>("binds")
|
let binds_tbl = tbl.get::<mlua::Table>("binds")
|
||||||
.map_err(|_| mlua::Error::runtime("missing 'binds' in ActionHandler 'mappings' table"))?;
|
.map_err(|_| mlua::Error::runtime("missing 'binds' in ActionHandler 'mappings' table"))?;
|
||||||
for pair in binds_tbl.pairs::<String, mlua::Table>() {
|
for pair in binds_tbl.pairs::<String, mlua::Table>() {
|
||||||
let (action_lbl, input_binds) = pair?;
|
let (action_lbl, input_binds) = pair?;
|
||||||
|
@ -140,7 +140,7 @@ impl mlua::UserData for LuaActionHandler {
|
||||||
multi.push(name.into_lua(lua)?);
|
multi.push(name.into_lua(lua)?);
|
||||||
multi.push(val.into_lua(lua)?);
|
multi.push(val.into_lua(lua)?);
|
||||||
|
|
||||||
Ok(mlua::MultiValue::from_vec(multi))
|
Ok(mlua::MultiValue::from_iter(multi.into_iter()))
|
||||||
});
|
});
|
||||||
|
|
||||||
methods.add_method(FN_NAME_INTERNAL_REFLECT, |_, this, ()| {
|
methods.add_method(FN_NAME_INTERNAL_REFLECT, |_, this, ()| {
|
||||||
|
@ -153,8 +153,8 @@ impl mlua::UserData for LuaActionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> mlua::FromLua<'a> for LuaActionHandler {
|
impl mlua::FromLua for LuaActionHandler {
|
||||||
fn from_lua(val: mlua::Value<'a>, _: &'a mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||||
let tyname = val.type_name();
|
let tyname = val.type_name();
|
||||||
let ud = val.as_userdata()
|
let ud = val.as_userdata()
|
||||||
.ok_or(mlua::Error::external(Error::type_mismatch("ActionHandler", &tyname)))?;
|
.ok_or(mlua::Error::external(Error::type_mismatch("ActionHandler", &tyname)))?;
|
||||||
|
|
Loading…
Reference in New Issue