Compare commits
2 Commits
02f0c93aa2
...
ef2b0bf326
Author | SHA1 | Date |
---|---|---|
SeanOMik | ef2b0bf326 | |
SeanOMik | fa22a0310c |
|
@ -2062,22 +2062,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mlua"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7"
|
||||
version = "0.10.0-beta.2"
|
||||
source = "git+https://github.com/mlua-rs/mlua?rev=4dddf3c18d4590f7c92214fa592c3faca3d2c812#4dddf3c18d4590f7c92214fa592c3faca3d2c812"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"mlua-sys",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"rustc-hash 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlua-sys"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebe026d6bd1583a9cf9080e189030ddaea7e6f5f0deb366a8e26f8a26c4135b8"
|
||||
source = "git+https://github.com/mlua-rs/mlua?rev=4dddf3c18d4590f7c92214fa592c3faca3d2c812#4dddf3c18d4590f7c92214fa592c3faca3d2c812"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"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
|
||||
---@return string
|
||||
---@return string|nil
|
||||
function udname(val)
|
||||
local tbl = getmetatable(val)
|
||||
if type(tbl) == "boolean" then
|
||||
error("what, got a boolean??: " .. tostring(tbl), 1)
|
||||
local tbl = debug.getmetatable(val)
|
||||
|
||||
if tbl == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
return tbl.__name
|
||||
|
@ -15,14 +18,14 @@ function on_init()
|
|||
local cube = world:request_res("../assets/cube-texture-embedded.gltf")
|
||||
print("Loaded textured cube (" .. udname(cube) .. ")")
|
||||
|
||||
--[[ cube:wait_until_loaded()
|
||||
cube:wait_until_loaded()
|
||||
local scenes = cube:scenes()
|
||||
local cube_scene = scenes[1]
|
||||
|
||||
local pos = Transform.from_translation(Vec3.new(0, 0, -8.0))
|
||||
|
||||
local e = world:spawn(pos, cube_scene)
|
||||
print("spawned entity " .. tostring(e)) ]]
|
||||
print("spawned entity " .. tostring(e))
|
||||
end
|
||||
|
||||
--[[ function on_first()
|
||||
|
@ -48,12 +51,12 @@ function on_update()
|
|||
end, Transform) ]]
|
||||
|
||||
---@type number
|
||||
--[[ local dt = world:resource(DeltaTime)
|
||||
local dt = world:resource(DeltaTime)
|
||||
|
||||
world:view(function (t)
|
||||
t:translate(0, 0.15 * dt, 0)
|
||||
return t
|
||||
end, Transform) ]]
|
||||
end, Transform)
|
||||
end
|
||||
|
||||
--[[ function on_post_update()
|
||||
|
|
|
@ -509,7 +509,11 @@ impl World {
|
|||
/// Attempts to find a resource in the world and returns a NonNull pointer to it
|
||||
pub unsafe fn get_resource_ptr<T: ResourceObject>(&self) -> Option<NonNull<T>> {
|
||||
self.resources.get(&TypeId::of::<T>())
|
||||
.map(|d| unsafe { NonNull::new_unchecked(d.data.as_ptr() as *mut T) })
|
||||
.map(|d| unsafe {
|
||||
let data = d.data.borrow();
|
||||
let ptr = NonNull::from(&data.res);
|
||||
NonNull::new_unchecked(ptr.as_ptr() as *mut T)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn archetype_count(&self) -> usize {
|
||||
|
|
|
@ -22,7 +22,9 @@ tracing = "0.1.37"
|
|||
atomic_refcell = "0.1.13"
|
||||
|
||||
# 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 }
|
||||
itertools = "0.12.0"
|
||||
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 {
|
||||
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("version", |_, this| Ok(this.version()));
|
||||
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)*
|
||||
}
|
||||
|
||||
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, ()| {
|
||||
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 {
|
||||
fn from_lua(val: mlua::Value<'a>, _: &'a mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for #wrapper_name {
|
||||
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
let tyname = val.type_name();
|
||||
let ud = val.as_userdata()
|
||||
.ok_or(mlua::Error::external(crate::lua::Error::type_mismatch(#ud_name, &tyname)))?;
|
||||
|
|
|
@ -224,7 +224,7 @@ impl MetaMethod {
|
|||
// this is the body of the else statement
|
||||
{
|
||||
// try to get the name of the userdata for the error message
|
||||
if let Ok(mt) = ud.get_metatable() {
|
||||
if let Ok(mt) = ud.metatable() {
|
||||
if let Ok(name) = mt.get::<String>("__name") {
|
||||
return Err(mlua::Error::BadArgument {
|
||||
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
|
||||
|
@ -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 {
|
||||
fn from_lua(value: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for #wrapper_typename {
|
||||
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
match value {
|
||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||
_ => 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 {
|
||||
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)*
|
||||
}
|
||||
|
||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
#lua_reflects
|
||||
|
||||
#new_func_tokens
|
||||
|
|
|
@ -6,38 +6,36 @@ use lyra_reflect::TypeRegistry;
|
|||
#[cfg(feature = "lua")]
|
||||
use super::ReflectLuaProxy;
|
||||
|
||||
use crate::ScriptWorldPtr;
|
||||
|
||||
#[cfg(feature = "lua")]
|
||||
pub struct ReflectedItem<'a> {
|
||||
pub struct ReflectedItem {
|
||||
//pub proxy: &'a ReflectLuaProxy,
|
||||
pub comp_ptr: NonNull<u8>,
|
||||
pub comp_val: mlua::Value<'a>,
|
||||
pub comp_val: mlua::Value,
|
||||
}
|
||||
|
||||
#[cfg(feature = "lua")]
|
||||
pub struct ReflectedRow<'a> {
|
||||
pub struct ReflectedRow {
|
||||
pub entity: Entity,
|
||||
pub row: Vec<ReflectedItem<'a>>,
|
||||
pub row: Vec<ReflectedItem>,
|
||||
}
|
||||
|
||||
pub struct ReflectedIterator {
|
||||
pub world: ScriptWorldPtr,
|
||||
pub struct ReflectedIterator<'a> {
|
||||
pub world: &'a lyra_ecs::World,
|
||||
pub dyn_view: DynamicViewStateIter,
|
||||
pub reflected_components: Option<NonNull<TypeRegistry>>
|
||||
}
|
||||
|
||||
impl ReflectedIterator {
|
||||
impl<'a> ReflectedIterator<'a> {
|
||||
#[cfg(feature = "lua")]
|
||||
pub fn next_lua<'a>(&mut self, lua: &'a mlua::Lua) -> Option<ReflectedRow<'a>> {
|
||||
pub fn next_lua(&mut self, lua: &mlua::Lua) -> Option<ReflectedRow> {
|
||||
use mlua::IntoLua;
|
||||
|
||||
let world = self.world.read();
|
||||
let n = self.dyn_view.next(&world);
|
||||
//let world = self.world.read();
|
||||
let n = self.dyn_view.next(&self.world);
|
||||
|
||||
if let Some((en, row)) = n {
|
||||
if self.reflected_components.is_none() {
|
||||
self.reflected_components = world.get_resource::<TypeRegistry>()
|
||||
self.reflected_components = self.world.get_resource::<TypeRegistry>()
|
||||
.map(|r| NonNull::from(r.deref()));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ pub mod dynamic_iter;
|
|||
pub use dynamic_iter::*;
|
||||
|
||||
pub mod world;
|
||||
use mlua::AnyUserDataExt;
|
||||
use mlua::ObjectLike;
|
||||
pub use world::*;
|
||||
|
||||
pub mod script;
|
||||
|
@ -113,24 +113,24 @@ pub trait RegisterLuaType {
|
|||
/// Register a type to Lua that **is not wrapped**.
|
||||
fn register_lua_type<'a, T>(&mut self)
|
||||
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.
|
||||
/// This would be used for something like `UserdataRef<T>`.
|
||||
fn register_lua_wrapper<'a, W>(&mut self)
|
||||
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.
|
||||
fn register_lua_convert<T>(&mut self)
|
||||
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 {
|
||||
fn register_lua_type<'a, T>(&mut self)
|
||||
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();
|
||||
|
||||
|
@ -142,7 +142,7 @@ impl RegisterLuaType for World {
|
|||
|
||||
fn register_lua_wrapper<'a, W>(&mut self)
|
||||
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();
|
||||
|
||||
|
@ -152,7 +152,7 @@ impl RegisterLuaType for World {
|
|||
|
||||
fn register_lua_convert<T>(&mut self)
|
||||
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();
|
||||
|
||||
|
@ -161,8 +161,8 @@ impl RegisterLuaType for World {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for ScriptBorrow {
|
||||
fn from_lua(value: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for ScriptBorrow {
|
||||
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
match value {
|
||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||
_ => unreachable!(),
|
||||
|
@ -176,6 +176,6 @@ impl mlua::UserData for ScriptBorrow {
|
|||
|
||||
/// Helper function used for reflecting userdata as a 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")
|
||||
}
|
|
@ -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 crate::{ScriptApiProvider, ScriptData};
|
||||
|
@ -58,9 +58,9 @@ impl ScriptApiProvider for UtilityApiProvider {
|
|||
},
|
||||
mlua::Value::UserData(ud) => {
|
||||
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 {
|
||||
return Err(mlua::Error::runtime(
|
||||
"UserData does not implement MetaMethod '__tostring'",
|
||||
|
@ -73,7 +73,7 @@ impl ScriptApiProvider for UtilityApiProvider {
|
|||
));
|
||||
},
|
||||
mlua::Value::Error(error) => {
|
||||
return Err(error.clone());
|
||||
return Err(error.deref().clone());
|
||||
},
|
||||
},
|
||||
None => {
|
||||
|
@ -123,8 +123,8 @@ impl ScriptApiProvider for UtilityApiProvider {
|
|||
formatted = format!("{}{}", formatted, text);
|
||||
|
||||
lua.globals()
|
||||
.get::<_, mlua::Function>("print")?
|
||||
.call::<_, ()>(formatted)?;
|
||||
.get::<mlua::Function>("print")?
|
||||
.call::<()>(formatted)?;
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
@ -141,9 +141,24 @@ impl ScriptApiProvider for UtilityApiProvider {
|
|||
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();
|
||||
globals.set("printf", printf_func)?;
|
||||
globals.set("print", print_func)?;
|
||||
globals.set("getmetatable2", getmetatable_func)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{any::TypeId, collections::HashMap, ptr::NonNull};
|
||||
|
||||
use mlua::{AnyUserDataExt, IntoLua};
|
||||
use mlua::{ObjectLike, IntoLua};
|
||||
use lyra_ecs::{ComponentInfo, DynamicBundle};
|
||||
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.
|
||||
pub trait LuaProxy {
|
||||
fn as_lua_value<'lua>(
|
||||
lua: &'lua mlua::Lua,
|
||||
fn as_lua_value(
|
||||
lua: &mlua::Lua,
|
||||
this: &dyn Reflect,
|
||||
) -> mlua::Result<mlua::Value<'lua>>;
|
||||
) -> mlua::Result<mlua::Value>;
|
||||
|
||||
fn apply(
|
||||
lua: &mlua::Lua,
|
||||
|
@ -29,15 +29,14 @@ pub trait LuaProxy {
|
|||
|
||||
impl<'a, T> LuaProxy for T
|
||||
where
|
||||
T: Reflect + Clone + mlua::FromLua<'a> + mlua::UserData
|
||||
T: Reflect + Clone + mlua::FromLua + mlua::UserData
|
||||
{
|
||||
fn as_lua_value<'lua>(
|
||||
lua: &'lua mlua::Lua,
|
||||
fn as_lua_value(
|
||||
lua: &mlua::Lua,
|
||||
this: &dyn Reflect,
|
||||
) -> mlua::Result<mlua::Value<'lua>> {
|
||||
) -> mlua::Result<mlua::Value> {
|
||||
let this = this.as_any().downcast_ref::<T>().unwrap();
|
||||
lua.create_userdata(this.clone())
|
||||
.and_then(|ud| ud.into_lua(lua))
|
||||
this.clone().into_lua(lua)
|
||||
}
|
||||
|
||||
fn apply(
|
||||
|
@ -67,11 +66,11 @@ pub struct LuaTableProxyLookup {
|
|||
#[derive(Clone)]
|
||||
pub struct ReflectLuaProxy {
|
||||
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(
|
||||
lua: &'a mlua::Lua,
|
||||
this_ptr: NonNull<()>,
|
||||
value: &'a mlua::Value<'a>,
|
||||
value: &'a mlua::Value,
|
||||
) -> mlua::Result<()>,
|
||||
}
|
||||
|
||||
|
@ -96,7 +95,7 @@ impl ReflectLuaProxy {
|
|||
/// Create from a type that implements FromLua and AsLua
|
||||
pub fn from_as_and_from_lua<T>() -> Self
|
||||
where
|
||||
T: for<'a> mlua::FromLua<'a> + for<'a> mlua::IntoLua<'a> + Clone
|
||||
T: mlua::FromLua + mlua::IntoLua + Clone
|
||||
{
|
||||
Self {
|
||||
fn_as_lua: |lua, this| -> mlua::Result<mlua::Value> {
|
||||
|
@ -115,8 +114,8 @@ impl ReflectLuaProxy {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for ScriptDynamicBundle {
|
||||
fn from_lua(val: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for ScriptDynamicBundle {
|
||||
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
match val {
|
||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||
mlua::Value::Nil => Err(Error::Nil.into()),
|
||||
|
@ -126,10 +125,10 @@ impl<'lua> mlua::FromLua<'lua> 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_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 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();
|
||||
|
||||
if globals.contains_key(fn_name)? {
|
||||
let lua_fn = globals.get::<_, mlua::Function>(fn_name)?;
|
||||
lua_fn.call::<_, ()>(())
|
||||
let lua_fn = globals.get::<mlua::Function>(fn_name)?;
|
||||
lua_fn.call::<()>(())
|
||||
.map_err(ScriptError::from)?;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ impl ScriptHost for LuaHost {
|
|||
let mut ctx = Mutex::new({
|
||||
// unsafe is required to allow the debug module
|
||||
let s = unsafe { mlua::Lua::unsafe_new() };
|
||||
s.load_from_std_lib(StdLib::ALL)?;
|
||||
s.load_std_libs(StdLib::ALL)?;
|
||||
s
|
||||
});
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@ use lyra_ecs::{
|
|||
};
|
||||
use lyra_reflect::{ReflectWorldExt, RegisteredType, TypeRegistry};
|
||||
use lyra_resource::ResourceManager;
|
||||
use mlua::{AnyUserDataExt, IntoLua};
|
||||
use mlua::{IntoLua, ObjectLike};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for ScriptEntity {
|
||||
fn from_lua(value: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for ScriptEntity {
|
||||
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
match value {
|
||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||
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 {
|
||||
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, ()| {
|
||||
Ok(format!("{:?}", this.0))
|
||||
});
|
||||
|
@ -37,8 +37,8 @@ pub enum WorldError {
|
|||
LuaInvalidUsage(String),
|
||||
}
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for ScriptWorldPtr {
|
||||
fn from_lua(val: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for ScriptWorldPtr {
|
||||
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
match val {
|
||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||
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 {
|
||||
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| {
|
||||
let mut world = this.write();
|
||||
|
||||
|
@ -64,7 +64,7 @@ impl mlua::UserData for ScriptWorldPtr {
|
|||
})?;
|
||||
|
||||
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())? {
|
||||
mlua::Value::UserData(ud) => ud,
|
||||
|
@ -72,9 +72,9 @@ impl mlua::UserData for ScriptWorldPtr {
|
|||
_ => todo!(),
|
||||
};
|
||||
|
||||
ud.call_method::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?
|
||||
ud.call_method::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?
|
||||
} 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) => {
|
||||
let reflect = ud
|
||||
.call_function::<_, ScriptBorrow>(
|
||||
.call_function::<ScriptBorrow>(
|
||||
FN_NAME_INTERNAL_REFLECT_TYPE,
|
||||
(),
|
||||
)
|
||||
|
@ -155,32 +155,34 @@ impl mlua::UserData for ScriptWorldPtr {
|
|||
|
||||
let iter = view.into_iter();
|
||||
let mut reflected_iter = ReflectedIterator {
|
||||
world: this.clone(),
|
||||
// SAFETY: bypassing the borrow checker here to get a pointer of the world
|
||||
// is required since we mutably borrow below. Its safe to do so since
|
||||
// only the entity ticks are updated. They are accessing different things
|
||||
// from the world.
|
||||
world: unsafe { NonNull::from(&*world).as_ref() },
|
||||
dyn_view: DynamicViewStateIter::from(iter),
|
||||
reflected_components: None,
|
||||
};
|
||||
|
||||
let mut current = world.current_tick();
|
||||
let mut has_ticked = false;
|
||||
let current = world.current_tick();
|
||||
|
||||
// drop read lock and acquire the write lock.
|
||||
// dropping must be done to avoid mutex deadlock
|
||||
drop(world);
|
||||
let mut world = this.write();
|
||||
|
||||
while let Some(row) = reflected_iter.next_lua(lua) {
|
||||
let r = row
|
||||
.row
|
||||
let r = row.row.into_iter()
|
||||
.into_iter()
|
||||
.map(|r| (r.comp_val, r.comp_ptr.cast::<()>()))
|
||||
.collect::<Vec<_>>();
|
||||
let (values, ptrs) =
|
||||
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)?;
|
||||
|
||||
// if values were returned, find the type in the type registry, and apply the new values
|
||||
if res.len() <= ptrs.len() {
|
||||
// we only want to tick one time per system
|
||||
if !has_ticked {
|
||||
current = world.tick();
|
||||
has_ticked = true;
|
||||
}
|
||||
|
||||
for (comp, ptr) in res.into_iter().zip(ptrs) {
|
||||
let lua_typeid = match &comp {
|
||||
|
@ -203,7 +205,6 @@ impl mlua::UserData for ScriptWorldPtr {
|
|||
};
|
||||
|
||||
// update the component tick
|
||||
let mut world = this.write();
|
||||
let arch = world.entity_archetype_mut(row.entity).unwrap();
|
||||
let idx = arch.entity_indexes().get(&row.entity).unwrap().clone();
|
||||
let c = arch.get_column_mut(lua_typeid).unwrap();
|
||||
|
@ -236,20 +237,17 @@ impl mlua::UserData for ScriptWorldPtr {
|
|||
methods.add_method_mut("resource", |lua, this, (ty,): (mlua::Value,)| {
|
||||
let reflect = match ty {
|
||||
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"),
|
||||
mlua::Value::Table(t) => {
|
||||
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")
|
||||
}
|
||||
_ => {
|
||||
panic!("how");
|
||||
}
|
||||
};
|
||||
/* let reflect = ty
|
||||
.execute_function::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT_TYPE, ())
|
||||
.expect("Type does not implement 'reflect_type' properly"); */
|
||||
|
||||
let mut world = this.write();
|
||||
let res = reflect.reflect_branch.as_resource_unchecked();
|
||||
|
@ -270,11 +268,11 @@ impl mlua::UserData for ScriptWorldPtr {
|
|||
methods.add_method_mut("add_resource", |_, this, res: mlua::Value| {
|
||||
let reflect = match res {
|
||||
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"),
|
||||
mlua::Value::Table(t) => {
|
||||
let f: mlua::Function = t.get(FN_NAME_INTERNAL_REFLECT)?;
|
||||
f.call::<_, ScriptBorrow>(())
|
||||
f.call::<ScriptBorrow>(())
|
||||
.expect("Type does not implement 'reflect_type' properly")
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -56,7 +56,7 @@ impl From<UntypedResHandle> 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("version", |_, this| Ok(this.version()));
|
||||
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, ()| {
|
||||
Ok(this.is_watched())
|
||||
});
|
||||
|
@ -100,8 +100,8 @@ impl mlua::UserData for LuaResHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> mlua::FromLua<'a> for LuaResHandle {
|
||||
fn from_lua(val: mlua::Value<'a>, _: &'a mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for LuaResHandle {
|
||||
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
let tyname = val.type_name();
|
||||
let ud = val.as_userdata()
|
||||
.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 {
|
||||
fn from_lua(_: mlua::Value<'lua>, _: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for LuaDeltaTime {
|
||||
fn from_lua(_: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::IntoLua<'lua> for LuaDeltaTime {
|
||||
fn into_lua(self, _: &'lua mlua::Lua) -> mlua::Result<mlua::Value<'lua>> {
|
||||
impl mlua::IntoLua for LuaDeltaTime {
|
||||
fn into_lua(self, _: &mlua::Lua) -> mlua::Result<mlua::Value> {
|
||||
Ok(mlua::Value::Number(*self.0 as f64))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ pub struct 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| {
|
||||
let mut handler = ActionHandler::new();
|
||||
|
||||
// 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"))?;
|
||||
for layout_id in layouts.sequence_values::<u32>() {
|
||||
let layout_id = layout_id?;
|
||||
|
@ -26,7 +26,7 @@ impl mlua::UserData for LuaActionHandler {
|
|||
}
|
||||
|
||||
// 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"))?;
|
||||
for pair in actions.pairs::<String, String>() {
|
||||
let (action_lbl, action_type) = pair?;
|
||||
|
@ -42,17 +42,17 @@ impl mlua::UserData for LuaActionHandler {
|
|||
}
|
||||
|
||||
// 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"))?;
|
||||
for (map_id, tbl) in mappings.sequence_values::<mlua::Table>().enumerate() {
|
||||
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));
|
||||
|
||||
// find the binds and start processing them
|
||||
// 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"))?;
|
||||
for pair in binds_tbl.pairs::<String, mlua::Table>() {
|
||||
let (action_lbl, input_binds) = pair?;
|
||||
|
@ -140,7 +140,7 @@ impl mlua::UserData for LuaActionHandler {
|
|||
multi.push(name.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, ()| {
|
||||
|
@ -153,8 +153,8 @@ impl mlua::UserData for LuaActionHandler {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> mlua::FromLua<'a> for LuaActionHandler {
|
||||
fn from_lua(val: mlua::Value<'a>, _: &'a mlua::Lua) -> mlua::Result<Self> {
|
||||
impl mlua::FromLua for LuaActionHandler {
|
||||
fn from_lua(val: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
let tyname = val.type_name();
|
||||
let ud = val.as_userdata()
|
||||
.ok_or(mlua::Error::external(Error::type_mismatch("ActionHandler", &tyname)))?;
|
||||
|
|
Loading…
Reference in New Issue