scripting: fix math type wrapper macro for lua. Expose math types as userdata through LuaProxy trait

This commit is contained in:
SeanOMik 2024-02-19 17:57:48 -05:00
parent ea958f9f18
commit e6b4e83dee
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
10 changed files with 145 additions and 291 deletions

View File

@ -1,5 +1,3 @@
print("Hello World")
--[[ function on_init() --[[ function on_init()
print("Lua script was initialized!") print("Lua script was initialized!")
end end
@ -13,27 +11,11 @@ function on_pre_update()
end ]] end ]]
function on_update() function on_update()
--print("Lua's update function was called")
--[[ world:view(
---@param t Transform
function (t)
print("Found entity at a really cool place: " .. tostring(t))
t.translation:move_by(0, 0.001, 0)
return t
end,
Transform
) ]]
---@type number ---@type number
local dt = world:resource(DeltaTime) local dt = world:resource(DeltaTime)
--print("DeltaTime was " .. tostring(dt) .. "s")
world:view(function (t) world:view(function (t)
--print("Found entity at a really cool place: " .. tostring(t)) t:translate(0, 0.5 * dt, 0)
--t.translation = t.translation + (Vec3.new(0, 0.5, 0) * dt:get())
t.translation:move_by(0, 0.5 * dt, 0)
return t return t
end, Transform) end, Transform)

View File

@ -342,7 +342,7 @@ impl Game {
.with(fmt::layer().with_writer(stdout_layer)) .with(fmt::layer().with_writer(stdout_layer))
.with(filter::Targets::new() .with(filter::Targets::new()
// done by prefix, so it includes all lyra subpackages // done by prefix, so it includes all lyra subpackages
.with_target("lyra", Level::TRACE) .with_target("lyra", Level::DEBUG)
.with_target("wgpu", Level::WARN) .with_target("wgpu", Level::WARN)
.with_default(Level::INFO)) .with_default(Level::INFO))
.init(); .init();

View File

@ -85,6 +85,13 @@ impl Transform {
pub fn rotate_z(&mut self, angle: Angle) { pub fn rotate_z(&mut self, angle: Angle) {
self.rotate(Quat::from_rotation_z(angle.to_radians())) self.rotate(Quat::from_rotation_z(angle.to_radians()))
} }
pub fn translate(&mut self, x: f32, y: f32, z: f32) {
let trans = &mut self.translation;
trans.x += x;
trans.y += y;
trans.z += z;
}
/// Performs a linear interpolation between `self` and `rhs` based on the value `alpha`. /// Performs a linear interpolation between `self` and `rhs` based on the value `alpha`.
/// ///

@ -1 +1 @@
Subproject commit 9b542fb523a3dc5d2eb77b246136111ad8bc4dd2 Subproject commit d32c138e996ec2fe17b7a5f7c0d3ff1562e446f0

View File

@ -140,7 +140,7 @@ impl MetaMethod {
let body = Self::get_method_body(&self.ident, other); let body = Self::get_method_body(&self.ident, other);
quote! { quote! {
methods.add_meta_method(mlua::MetaMethod::#mt_ident, |_, this, (v,): (#wrapper_ident,)| { builder.meta_method(elua::MetaMethod::#mt_ident, |_, this, (v,): (#wrapper_ident,)| {
#body #body
}); });
} }
@ -149,12 +149,12 @@ impl MetaMethod {
let body = Self::get_body_for_arg(&self.ident, first, quote!(v)); let body = Self::get_body_for_arg(&self.ident, first, quote!(v));
quote! { quote! {
methods.add_meta_method(mlua::MetaMethod::#mt_ident, |_, this, (v,): (#first,)| { builder.meta_method(elua::MetaMethod::#mt_ident, |_, this, (v,): (#first,)| {
#body #body
}); });
} }
} else { } else {
// an optional match arm that matches mlua::Value:Number // an optional match arm that matches elua::Value:Number
let number_arm = { let number_arm = {
let num_ident = self.mods.iter().find(|i| { let num_ident = self.mods.iter().find(|i| {
let is = i.to_string(); let is = i.to_string();
@ -171,7 +171,7 @@ impl MetaMethod {
let body = Self::get_body_for_arg(&self.ident, num_ident, quote!(n as #num_ident)); let body = Self::get_body_for_arg(&self.ident, num_ident, quote!(n as #num_ident));
quote! { quote! {
mlua::Value::Number(n) => { elua::Value::Number(n) => {
#body #body
}, },
} }
@ -187,7 +187,7 @@ impl MetaMethod {
let body = Self::get_method_body(&self.ident, quote!(other.0)); let body = Self::get_method_body(&self.ident, quote!(other.0));
quote! { quote! {
if let Ok(other) = ud.borrow::<#i>() { if let Ok(other) = ud.as_ref::<#i>() {
#body #body
} }
} }
@ -195,30 +195,30 @@ impl MetaMethod {
}); });
quote! { quote! {
mlua::Value::UserData(ud) => { elua::Value::Userdata(ud) => {
#(#if_statements else)* #(#if_statements else)*
// this is the body of the else statement // this is the body of the else statement
{ {
// try to get the name of the userdata for the error message // try to get the name of the userdata for the error message
if let Ok(mt) = ud.get_metatable() { if let Ok(mt) = ud.get_metatable() {
if let Ok(name) = mt.get::<String>("__name") { if let Ok(name) = mt.get::<_, String>("__name") {
return Err(mlua::Error::BadArgument { return Err(elua::Error::BadArgument {
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)), func: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
pos: 2, arg_index: 2,
name: Some("rhs".to_string()), arg_name: Some("rhs".to_string()),
cause: Arc::new(mlua::Error::RuntimeError( error: Arc::new(elua::Error::Runtime(
format!("cannot multiply with unknown userdata named {}", name) format!("cannot multiply with unknown userdata named {}", name)
)) ))
}); });
} }
} }
Err(mlua::Error::BadArgument { Err(elua::Error::BadArgument {
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)), func: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
pos: 2, arg_index: 2,
name: Some("rhs".to_string()), arg_name: Some("rhs".to_string()),
cause: Arc::new( error: Arc::new(
mlua::Error::runtime("cannot multiply with unknown userdata") elua::Error::runtime("cannot multiply with unknown userdata")
) )
}) })
} }
@ -227,16 +227,16 @@ impl MetaMethod {
}; };
quote! { quote! {
methods.add_meta_method(mlua::MetaMethod::#mt_ident, |_, this, (v,): (mlua::Value,)| { builder.meta_method(elua::MetaMethod::#mt_ident, |_, this, (v,): (elua::Value,)| {
match v { match v {
#number_arm #number_arm
#userdata_arm #userdata_arm
_ => Err(mlua::Error::BadArgument { _ => Err(elua::Error::BadArgument {
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)), func: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
pos: 2, arg_index: 2,
name: Some("rhs".to_string()), arg_name: Some("rhs".to_string()),
cause: Arc::new( error: Arc::new(
mlua::Error::RuntimeError(format!("cannot multiply with {}", v.type_name())) elua::Error::Runtime(format!("cannot multiply with {}", v.type_name()))
) )
}) })
} }
@ -293,8 +293,8 @@ impl VecWrapper {
if axis_type_name.contains("b") { if axis_type_name.contains("b") {
return quote! { return quote! {
fields.add_field("FALSE", #wrapper_ident(#wrapped_path::FALSE)); builder.field("FALSE", #wrapper_ident(#wrapped_path::FALSE));
fields.add_field("TRUE", #wrapper_ident(#wrapped_path::TRUE)); builder.field("TRUE", #wrapper_ident(#wrapped_path::TRUE));
}; };
} }
@ -331,7 +331,7 @@ impl VecWrapper {
let const_name = cnst.to_string(); let const_name = cnst.to_string();
quote! { quote! {
fields.add_field(#const_name, #wrapper_ident(#wrapped_path::#cnst)); builder.field(#const_name, #wrapper_ident(#wrapped_path::#cnst));
} }
}); });
@ -356,17 +356,17 @@ impl VecWrapper {
optional_methods.push( optional_methods.push(
quote! { quote! {
methods.add_method("clamp_length", builder.method("clamp_length",
|_, this, (min, max): (#type_id, #type_id)| { |_, this, (min, max): (#type_id, #type_id)| {
Ok(#wrapper_ident(this.clamp_length(min, max))) Ok(#wrapper_ident(this.clamp_length(min, max)))
}); });
methods.add_method("abs_diff_eq", builder.method("abs_diff_eq",
|_, this, (rhs, max_abs_diff): (#wrapper_ident, #type_id)| { |_, this, (rhs, max_abs_diff): (#wrapper_ident, #type_id)| {
Ok(this.abs_diff_eq(rhs.0, max_abs_diff)) Ok(this.abs_diff_eq(rhs.0, max_abs_diff))
}); });
methods.add_method("ceil", builder.method("ceil",
|_, this, (): ()| { |_, this, (): ()| {
Ok(#wrapper_ident(this.ceil())) Ok(#wrapper_ident(this.ceil()))
}); });
@ -376,7 +376,7 @@ impl VecWrapper {
if vec_size != 4 { if vec_size != 4 {
optional_methods.push( optional_methods.push(
quote! { quote! {
methods.add_method("angle_between", builder.method("angle_between",
|_, this, (rhs,): (#wrapper_ident,)| { |_, this, (rhs,): (#wrapper_ident,)| {
Ok(this.angle_between(rhs.0)) Ok(this.angle_between(rhs.0))
}); });
@ -388,7 +388,7 @@ impl VecWrapper {
if !axis_type_name.contains("u") { if !axis_type_name.contains("u") {
optional_methods.push( optional_methods.push(
quote! { quote! {
methods.add_method("abs", builder.method("abs",
|_, this, (): ()| { |_, this, (): ()| {
Ok(#wrapper_ident(this.abs())) Ok(#wrapper_ident(this.abs()))
}); });
@ -400,19 +400,19 @@ impl VecWrapper {
quote! { quote! {
methods.add_method("clamp", builder.method("clamp",
|_, this, (min, max): (#wrapper_ident, #wrapper_ident)| { |_, this, (min, max): (#wrapper_ident, #wrapper_ident)| {
Ok(#wrapper_ident(this.clamp(min.0, max.0))) Ok(#wrapper_ident(this.clamp(min.0, max.0)))
}); });
// TODO: Not all Vecs have this // TODO: Not all Vecs have this
/* methods.add_method("clamp_length", /* builder.method("clamp_length",
|_, this, (min, max): (f32, f32)| { |_, this, (min, max): (f32, f32)| {
Ok(#wrapper_ident(this.clamp_length(min, max))) Ok(#wrapper_ident(this.clamp_length(min, max)))
}); */ }); */
methods.add_method("to_array", builder.method("to_array",
|_, this, (): ()| { |_, this, (): ()| {
Ok(this.to_array()) Ok(this.to_array())
}); });
@ -570,10 +570,10 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
let field_get_set_pairs = input.field_idents.iter().map(|i| { let field_get_set_pairs = input.field_idents.iter().map(|i| {
let is = i.to_string(); let is = i.to_string();
quote! { quote! {
fields.add_field_method_get(#is, |_, this| { builder.field_getter(#is, |_, this| {
Ok(this.#i) Ok(this.#i)
}); });
fields.add_field_method_set(#is, |_, this, #i| { builder.field_setter(#is, |_, this, #i| {
this.#i = #i; this.#i = #i;
Ok(()) Ok(())
}); });
@ -591,7 +591,7 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
if !input.skip_new_fn { if !input.skip_new_fn {
quote! { quote! {
methods.add_function("new", |_, ( #(#idents_c),* )| { builder.function("new", |_, ( #(#idents_c),* )| {
Ok(#wrapper_typename(#path::new( #(#idents),* ))) Ok(#wrapper_typename(#path::new( #(#idents),* )))
}); });
} }
@ -631,33 +631,35 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
} }
} }
impl<'lua> mlua::FromLua<'lua> for #wrapper_typename { impl<'lua> elua::FromLua<'lua> for #wrapper_typename {
fn from_lua(value: mlua::Value<'lua>, _lua: &'lua mlua::Lua) -> mlua::Result<Self> { fn from_lua(_lua: &'lua elua::State, value: elua::Value<'lua>) -> elua::Result<Self> {
match value { match value {
mlua::Value::UserData(ud) => Ok(*ud.borrow::<Self>()?), elua::Value::Userdata(ud) => Ok(*ud.as_ref::<Self>()?),
_ => 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()),
} }
} }
} }
impl mlua::UserData for #wrapper_typename { impl elua::Userdata for #wrapper_typename {
fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn name() -> String {
stringify!(#type_name).to_string()
}
fn build<'a>(_: &elua::State, builder: &mut elua::UserdataBuilder<'a, Self>) -> elua::Result<()> {
#(#field_get_set_pairs)* #(#field_get_set_pairs)*
#matrix_wrapper_fields #matrix_wrapper_fields
#vec_wrapper_fields #vec_wrapper_fields
#custom_fields #custom_fields
}
fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
#new_fn_idents #new_fn_idents
methods.add_method(#FN_NAME_INTERNAL_REFLECT, |_, this, ()| { builder.method(#FN_NAME_INTERNAL_REFLECT, |_, this, ()| {
Ok(crate::ScriptBorrow::from_component::<#path>(Some(this.0.clone()))) Ok(crate::ScriptBorrow::from_component::<#path>(Some(this.0.clone())))
}); });
methods.add_function(#FN_NAME_INTERNAL_REFLECT_TYPE, |_, ()| { builder.function(#FN_NAME_INTERNAL_REFLECT_TYPE, |_, ()| {
Ok(crate::ScriptBorrow::from_component::<#path>(None)) Ok(crate::ScriptBorrow::from_component::<#path>(None))
}); });
@ -667,6 +669,8 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
#vec_wrapper_methods #vec_wrapper_methods
#custom_methods #custom_methods
Ok(())
} }
} }
@ -677,5 +681,20 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
t t
} }
} }
impl<'a> elua::FromLuaVec<'a> for #wrapper_typename {
fn from_lua_value_vec(state: &'a elua::State, mut values: elua::ValueVec<'a>) -> elua::Result<Self> {
use elua::FromLua;
if let Some(val) = values.pop_front() {
#wrapper_typename::from_lua(state, val)
} else {
Err(elua::Error::IncorrectArgCount {
arg_expected: 1,
arg_count: values.len() as i32,
})
}
}
}
}) })
} }

View File

@ -1,6 +1,5 @@
use elua::TableProxy;
use lyra_ecs::World; use lyra_ecs::World;
use lyra_game::math::{Quat, Transform, Vec3}; use crate::lua::wrappers::{LuaQuat, LuaTransform, LuaVec3};
use crate::ScriptData; use crate::ScriptData;
use crate::lua::RegisterLuaType; use crate::lua::RegisterLuaType;
@ -13,31 +12,21 @@ impl ScriptApiProvider for LyraMathApiProvider {
type ScriptContext = LuaContext; type ScriptContext = LuaContext;
fn prepare_world(&mut self, world: &mut World) { fn prepare_world(&mut self, world: &mut World) {
// TODO world.register_lua_wrapper::<LuaVec3>();
/* world.register_lua_wrapper::<LuaVec3>(); world.register_lua_wrapper::<LuaQuat>();
world.register_lua_wrapper::<LuaTransform>(); */ world.register_lua_wrapper::<LuaTransform>();
world.register_lua_table_proxy::<LuaVec3, Vec3>();
world.register_lua_table_proxy::<LuaQuat, Quat>();
world.register_lua_table_proxy::<LuaTransform, Transform>();
} }
fn expose_api(&mut self, _data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> { fn expose_api(&mut self, _data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
let ctx = ctx.lock().unwrap(); let ctx = ctx.lock().unwrap();
let bytes = include_bytes!("../../../scripts/lua/math/vec3.lua"); /* let bytes = include_bytes!("../../../scripts/lua/math/transform.lua");
ctx.load("lyra/math/vec2.lua", bytes.as_slice())?.execute(())?; ctx.load("lyra/math/transform.lua", bytes.as_slice())?.execute(())?; */
let bytes = include_bytes!("../../../scripts/lua/math/quat.lua"); let globals = ctx.globals()?;
ctx.load("lyra/math/quat.lua", bytes.as_slice())?.execute(())?; globals.set("Vec3", ctx.create_proxy::<LuaVec3>()?)?;
globals.set("Quat", ctx.create_proxy::<LuaQuat>()?)?;
let bytes = include_bytes!("../../../scripts/lua/math/transform.lua"); globals.set("Transform", ctx.create_proxy::<LuaTransform>()?)?;
ctx.load("lyra/math/transform.lua", bytes.as_slice())?.execute(())?;
// TODO
//let globals = ctx.globals()?;
//globals.set("Vec3", elua::Proxy::<LuaVec3>::from(LuaVec3(Vec3::ZERO)))?;
//globals.set("Vec3", ctx.create_proxy::<LuaVec3>()?)?;
//globals.set("Transform", ctx.create_proxy::<LuaTransform>()?)?;
Ok(()) Ok(())
} }
@ -49,156 +38,4 @@ impl ScriptApiProvider for LyraMathApiProvider {
fn update_script_environment(&mut self, _: crate::ScriptWorldPtr, _: &crate::ScriptData, _: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> { fn update_script_environment(&mut self, _: crate::ScriptWorldPtr, _: &crate::ScriptData, _: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
Ok(()) Ok(())
} }
} }
#[derive(Clone, Copy)]
struct LuaVec3(Vec3);
impl TableProxy for LuaVec3 {
fn from_table<'a>(_: &'a elua::State, table: elua::Table<'a>) -> elua::Result<Self> {
let x: f32 = table.get("x")?;
let y: f32 = table.get("y")?;
let z: f32 = table.get("z")?;
Ok(LuaVec3(Vec3 {
x,
y,
z,
}))
}
fn as_table<'a>(&self, state: &'a elua::State) -> elua::Result<elua::Table<'a>> {
let globals = state.globals()?;
let vec3: elua::Table = globals.get("Vec3")?;
let new_fn: elua::Function = vec3.get("new")?;
new_fn.exec((vec3, self.0.x, self.0.y, self.0.z))
}
fn table_name() -> String {
"Vec3".to_string()
}
}
#[derive(Clone, Copy)]
struct LuaQuat(Quat);
impl TableProxy for LuaQuat {
fn from_table<'a>(_: &'a elua::State, table: elua::Table<'a>) -> elua::Result<Self> {
let x: f32 = table.get("x")?;
let y: f32 = table.get("y")?;
let z: f32 = table.get("z")?;
let w: f32 = table.get("w")?;
Ok(LuaQuat(Quat::from_xyzw(x, y, z, w)))
}
fn as_table<'a>(&self, state: &'a elua::State) -> elua::Result<elua::Table<'a>> {
let globals = state.globals()?;
let quat: elua::Table = globals.get("Quat")?;
let new_fn: elua::Function = quat.get("new")?;
new_fn.exec((quat, self.0.x, self.0.y, self.0.z, self.0.w))
}
fn table_name() -> String {
"Quat".to_string()
}
}
#[derive(Clone, Copy)]
struct LuaTransform(Transform);
impl TableProxy for LuaTransform {
fn from_table<'a>(lua: &'a elua::State, table: elua::Table<'a>) -> elua::Result<Self> {
let translation: elua::Table = table.get("translation")?;
let rotation: elua::Table = table.get("rotation")?;
let scale: elua::Table = table.get("scale")?;
let translation = LuaVec3::from_table(lua, translation)?;
let rotation = LuaQuat::from_table(lua, rotation)?;
let scale = LuaVec3::from_table(lua, scale)?;
Ok(LuaTransform(Transform::new(translation.0, rotation.0, scale.0)))
}
fn as_table<'a>(&self, state: &'a elua::State) -> elua::Result<elua::Table<'a>> {
let globals = state.globals()?;
let transform: elua::Table = globals.get("Transform")?;
let new_fn: elua::Function = transform.get("new")?;
let translation = LuaVec3(self.0.translation).as_table(state)?;
let rotation = LuaQuat(self.0.rotation).as_table(state)?;
let scale = LuaVec3(self.0.scale).as_table(state)?;
new_fn.exec((transform, translation, rotation, scale))
}
fn table_name() -> String {
"Transform".to_string()
}
}
/* #[derive(Clone, Copy, PartialEq, Debug, lyra_reflect::Reflect)]
pub struct LuaVec3(#[reflect(skip)] math::Vec3);
impl From<math::Vec3> for LuaVec3 {
fn from(value: math::Vec3) -> Self {
Self(value)
}
}
impl<'lua> mlua::IntoLua<'lua> for LuaVec3 {
fn into_lua(self, lua: &'lua mlua::prelude::Lua) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
let globals = lua.globals();
let v3 = globals.get::<_, mlua::Table>("Vec3")?;
let v3_new = v3.get::<_, mlua::Function>("new")?;
v3_new.call::<_, mlua::Table>((v3, self.0.x, self.0.y, self.0.z))
.and_then(|t| t.into_lua(lua))
}
}
#[derive(Clone, Copy, PartialEq, Debug, lyra_reflect::Reflect)]
pub struct LuaQuat(#[reflect(skip)] math::Quat);
impl From<math::Quat> for LuaQuat {
fn from(value: math::Quat) -> Self {
Self(value)
}
}
impl<'lua> mlua::IntoLua<'lua> for LuaQuat {
fn into_lua(self, lua: &'lua mlua::prelude::Lua) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
let globals = lua.globals();
let q = globals.get::<_, mlua::Table>("Quat")?;
let q_new = q.get::<_, mlua::Function>("new")?;
q_new.call::<_, mlua::Table>((q, self.0.x, self.0.y, self.0.z, self.0.w))
.and_then(|t| t.into_lua(lua))
}
}
#[derive(Clone, Copy, Debug, lyra_reflect::Reflect)]
pub struct LuaTransform(#[reflect(skip)] math::Transform);
impl From<math::Transform> for LuaTransform {
fn from(value: math::Transform) -> Self {
Self(value)
}
}
impl<'lua> mlua::IntoLua<'lua> for LuaTransform {
fn into_lua(self, lua: &'lua mlua::prelude::Lua) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
let globals = lua.globals();
let translation = LuaVec3(self.0.translation).into_lua(lua)?;
let rot = LuaQuat(self.0.rotation).into_lua(lua)?;
let scale = LuaVec3(self.0.scale).into_lua(lua)?;
let transf = globals.get::<_, mlua::Table>("Transform")?;
let transf_new = transf.get::<_, mlua::Function>("new")?;
transf_new.call::<_, mlua::Table>((transf, translation, rot, scale))
.and_then(|t| t.into_lua(lua))
}
} */

View File

@ -1,6 +1,6 @@
use std::sync::Mutex; use std::sync::Mutex;
use elua::{AsLua, StdLibrary}; use elua::{AsLua, StdLibraries};
use crate::{ScriptHost, ScriptError, ScriptWorldPtr, ScriptEntity}; use crate::{ScriptHost, ScriptError, ScriptWorldPtr, ScriptEntity};
@ -25,12 +25,10 @@ impl ScriptHost for LuaHost {
fn load_script(&mut self, script: &[u8], script_data: &crate::ScriptData, providers: &mut crate::ScriptApiProviders<Self>) -> Result<Self::ScriptContext, crate::ScriptError> { fn load_script(&mut self, script: &[u8], script_data: &crate::ScriptData, providers: &mut crate::ScriptApiProviders<Self>) -> Result<Self::ScriptContext, crate::ScriptError> {
let mut ctx = Mutex::new({ let mut ctx = Mutex::new({
let s = elua::State::new(); let s = elua::State::new();
s.expose_libraries(&[StdLibrary::Debug, StdLibrary::Package]); s.expose_libraries(StdLibraries::all());
s s
}); });
//Mutex::new(elua::State::new_with_libraries(StdLibraries::all()));
for provider in providers.apis.iter_mut() { for provider in providers.apis.iter_mut() {
provider.expose_api(script_data, &mut ctx)?; provider.expose_api(script_data, &mut ctx)?;
} }

View File

@ -75,7 +75,8 @@ impl elua::Userdata for ScriptWorldPtr {
elua::Value::Table(t) => { elua::Value::Table(t) => {
let name: String = t.get(elua::MetaMethod::Name)?; let name: String = t.get(elua::MetaMethod::Name)?;
let lookup = world.get_resource::<LuaTableProxyLookup>(); let lookup = world.try_get_resource::<LuaTableProxyLookup>()
.ok_or(elua::Error::runtime("Unable to lookup table proxy, none were ever registered!"))?;
let info = lookup.comp_info_from_name.get(&name) let info = lookup.comp_info_from_name.get(&name)
.ok_or_else(|| .ok_or_else(||
elua::Error::BadArgument { elua::Error::BadArgument {

View File

@ -19,7 +19,7 @@ use crate as lyra_scripting;
Mod(LuaVec2, f32), Mod(LuaVec2, f32),
Eq, Unm, ToString Eq, Unm, ToString
) )
); ); */
wrap_math_vec_copy!( wrap_math_vec_copy!(
math::Vec3, math::Vec3,
derives(PartialEq), derives(PartialEq),
@ -32,7 +32,7 @@ wrap_math_vec_copy!(
Mod(LuaVec3, f32), Mod(LuaVec3, f32),
Eq, Unm, ToString Eq, Unm, ToString
) )
); */ );
// ================================================= // =================================================
@ -396,7 +396,7 @@ wrap_math_vec_copy!(
/* wrap_math_vec_copy!( wrap_math_vec_copy!(
math::Quat, math::Quat,
derives(PartialEq), derives(PartialEq),
no_new, no_new,
@ -409,55 +409,55 @@ wrap_math_vec_copy!(
Div(f32), Div(f32),
), ),
custom_methods { custom_methods {
methods.add_function("new", |_, (x, y, z, w)| { builder.function("new", |_, (x, y, z, w)| {
Ok(Self(math::Quat::from_xyzw(x, y, z, w))) Ok(Self(math::Quat::from_xyzw(x, y, z, w)))
}); });
methods.add_function("from_rotation_x", |_, (rad,)| { builder.function("from_rotation_x", |_, (rad,)| {
let q = math::Quat::from_rotation_x(rad); let q = math::Quat::from_rotation_x(rad);
Ok(Self(q)) Ok(Self(q))
}); });
methods.add_function("from_rotation_y", |_, (rad,)| { builder.function("from_rotation_y", |_, (rad,)| {
let q = math::Quat::from_rotation_y(rad); let q = math::Quat::from_rotation_y(rad);
Ok(Self(q)) Ok(Self(q))
}); });
methods.add_function("from_rotation_z", |_, (rad,)| { builder.function("from_rotation_z", |_, (rad,)| {
let q = math::Quat::from_rotation_z(rad); let q = math::Quat::from_rotation_z(rad);
Ok(Self(q)) Ok(Self(q))
}); });
methods.add_method("dot", |_, this, (rhs,): (Self,)| { builder.method("dot", |_, this, (rhs,): (Self,)| {
Ok(this.dot(rhs.0)) Ok(this.dot(rhs.0))
}); });
methods.add_method("length", |_, this, ()| { builder.method("length", |_, this, ()| {
Ok(this.length()) Ok(this.length())
}); });
methods.add_method("length_squared", |_, this, ()| { builder.method("length_squared", |_, this, ()| {
Ok(this.length_squared()) Ok(this.length_squared())
}); });
methods.add_method("normalize", |_, this, ()| { builder.method("normalize", |_, this, ()| {
Ok(Self(this.normalize())) Ok(Self(this.normalize()))
}); });
methods.add_method("mult_quat", |_, this, (rhs,): (Self,)| { builder.method("mult_quat", |_, this, (rhs,): (Self,)| {
Ok(Self(this.0 * rhs.0)) Ok(Self(this.0 * rhs.0))
}); });
methods.add_method("mult_vec3", |_, this, (rhs,): (LuaVec3,)| { builder.method("mult_vec3", |_, this, (rhs,): (LuaVec3,)| {
Ok(LuaVec3(this.0 * rhs.0)) Ok(LuaVec3(this.0 * rhs.0))
}); });
// manually implemented here since it doesn't return `Self` // manually implemented here since it doesn't return `Self`
methods.add_meta_method(mlua::MetaMethod::Mul, |_, this, (rhs,): (LuaVec3,)| { builder.meta_method(elua::MetaMethod::Mul, |_, this, (rhs,): (LuaVec3,)| {
Ok(LuaVec3(this.0 * rhs.0)) Ok(LuaVec3(this.0 * rhs.0))
}); });
methods.add_method("lerp", |_, this, (rhs, alpha): (Self, f32)| { builder.method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
Ok(Self(this.lerp(*rhs, alpha))) Ok(Self(this.lerp(*rhs, alpha)))
}); });
} }
@ -469,111 +469,119 @@ wrap_math_vec_copy!(
no_new, no_new,
metamethods(ToString, Eq), metamethods(ToString, Eq),
custom_fields { custom_fields {
fields.add_field_method_get("translation", |_, this| { builder.field_getter("translation", |_, this| {
Ok(LuaVec3(this.translation)) Ok(LuaVec3(this.translation))
}); });
fields.add_field_method_set("translation", |_, this, v: LuaVec3| { builder.field_setter("translation", |_, this, v: LuaVec3| {
this.translation = *v; this.translation = *v;
Ok(()) Ok(())
}); });
fields.add_field_method_get("rotation", |_, this| { builder.field_getter("rotation", |_, this| {
Ok(LuaQuat(this.rotation)) Ok(LuaQuat(this.rotation))
}); });
fields.add_field_method_set("rotation", |_, this, v: LuaQuat| { builder.field_setter("rotation", |_, this, v: LuaQuat| {
this.rotation = *v; this.rotation = *v;
Ok(()) Ok(())
}); });
fields.add_field_method_get("scale", |_, this| { builder.field_getter("scale", |_, this| {
Ok(LuaVec3(this.scale)) Ok(LuaVec3(this.scale))
}); });
fields.add_field_method_set("scale", |_, this, v: LuaVec3| { builder.field_setter("scale", |_, this, v: LuaVec3| {
this.scale = *v; this.scale = *v;
Ok(()) Ok(())
}); });
}, },
custom_methods { custom_methods {
methods.add_function("default", |_, ()| { builder.function("default", |_, ()| {
Ok(Self(math::Transform::default())) Ok(Self(math::Transform::default()))
}); });
methods.add_function("new", |_, (pos, rot, scale): (LuaVec3, LuaQuat, LuaVec3)| { builder.function("new", |_, (pos, rot, scale): (LuaVec3, LuaQuat, LuaVec3)| {
Ok(Self(math::Transform::new(*pos, *rot, *scale))) Ok(Self(math::Transform::new(*pos, *rot, *scale)))
}); });
methods.add_function("from_translation", |_, (pos,): (LuaVec3,)| { builder.function("from_translation", |_, (pos,): (LuaVec3,)| {
Ok(Self(math::Transform::from_translation(*pos))) Ok(Self(math::Transform::from_translation(*pos)))
}); });
methods.add_function("from_xyz", |_, (x, y, z)| { builder.function("from_xyz", |_, (x, y, z)| {
Ok(Self(math::Transform::from_xyz(x, y, z))) Ok(Self(math::Transform::from_xyz(x, y, z)))
}); });
methods.add_method("forward", |_, this, ()| { builder.method("clone", |_, this, ()| {
Ok(this.clone())
});
builder.method("forward", |_, this, ()| {
Ok(LuaVec3(this.forward())) Ok(LuaVec3(this.forward()))
}); });
methods.add_method("left", |_, this, ()| { builder.method("left", |_, this, ()| {
Ok(LuaVec3(this.left())) Ok(LuaVec3(this.left()))
}); });
methods.add_method("up", |_, this, ()| { builder.method("up", |_, this, ()| {
Ok(LuaVec3(this.up())) Ok(LuaVec3(this.up()))
}); });
methods.add_method_mut("rotate", |_, this, (quat,): (LuaQuat,)| { builder.method_mut("rotate", |_, this, (quat,): (LuaQuat,)| {
this.rotate(*quat); this.rotate(*quat);
Ok(()) Ok(())
}); });
methods.add_method_mut("rotate_x", |_, this, (deg,): (f32,)| { builder.method_mut("rotate_x", |_, this, (deg,): (f32,)| {
this.rotate_x(math::Angle::Degrees(deg)); this.rotate_x(math::Angle::Degrees(deg));
Ok(()) Ok(())
}); });
methods.add_method_mut("rotate_y", |_, this, (deg,): (f32,)| { builder.method_mut("rotate_y", |_, this, (deg,): (f32,)| {
this.rotate_y(math::Angle::Degrees(deg)); this.rotate_y(math::Angle::Degrees(deg));
Ok(()) Ok(())
}); });
methods.add_method_mut("rotate_z", |_, this, (deg,): (f32,)| { builder.method_mut("rotate_z", |_, this, (deg,): (f32,)| {
this.rotate_z(math::Angle::Degrees(deg)); this.rotate_z(math::Angle::Degrees(deg));
Ok(()) Ok(())
}); });
methods.add_method_mut("rotate_x_rad", |_, this, (rad,): (f32,)| { builder.method_mut("rotate_x_rad", |_, this, (rad,): (f32,)| {
this.rotate_x(math::Angle::Radians(rad)); this.rotate_x(math::Angle::Radians(rad));
Ok(()) Ok(())
}); });
methods.add_method_mut("rotate_y_rad", |_, this, (rad,): (f32,)| { builder.method_mut("rotate_y_rad", |_, this, (rad,): (f32,)| {
this.rotate_y(math::Angle::Radians(rad)); this.rotate_y(math::Angle::Radians(rad));
Ok(()) Ok(())
}); });
methods.add_method_mut("rotate_z_rad", |_, this, (rad,): (f32,)| { builder.method_mut("rotate_z_rad", |_, this, (rad,): (f32,)| {
this.rotate_z(math::Angle::Radians(rad)); this.rotate_z(math::Angle::Radians(rad));
Ok(()) Ok(())
}); });
methods.add_method("lerp", |_, this, (rhs, alpha): (Self, f32)| { builder.method_mut("translate", |_, this, (x, y, z): (f32, f32, f32)| {
this.translate(x, y, z);
Ok(())
});
builder.method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
Ok(Self(this.lerp(*rhs, alpha))) Ok(Self(this.lerp(*rhs, alpha)))
}); });
// rotate a transform // rotate a transform
methods.add_meta_method(mlua::MetaMethod::Mul, |_, this, (quat,): (LuaQuat,)| { builder.meta_method(elua::MetaMethod::Mul, |_, this, (quat,): (LuaQuat,)| {
let mut t = *this; let mut t = *this;
t.rotation *= *quat; t.rotation *= *quat;
Ok(t) Ok(t)
}); });
// move a transform // move a transform
methods.add_meta_method(mlua::MetaMethod::Add, |_, this, (pos,): (LuaVec3,)| { builder.meta_method(elua::MetaMethod::Add, |_, this, (pos,): (LuaVec3,)| {
let mut t = *this; let mut t = *this;
t.translation += *pos; t.translation += *pos;
Ok(t) Ok(t)
}); });
} }
); );
*/

View File

@ -12,9 +12,11 @@ mkShell rec {
heaptrack heaptrack
mold mold
udev udev
lua5_4_compat
]; ];
buildInputs = [ buildInputs = [
udev alsa-lib vulkan-loader udev alsa-lib libGL gcc
vulkan-loader vulkan-headers vulkan-tools
xorg.libX11 xorg.libXcursor xorg.libXi xorg.libXrandr # To use the x11 feature xorg.libX11 xorg.libXcursor xorg.libXi xorg.libXrandr # To use the x11 feature
libxkbcommon wayland # To use the wayland feature libxkbcommon wayland # To use the wayland feature
]; ];