From 044b08a10e8258bfaf34bf4a7709f4d332ca1dac Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sat, 27 Jan 2024 15:53:34 -0500 Subject: [PATCH] Add UserDataProxy --- src/main.rs | 47 +++++++++++++++++++++++++---------------------- src/state.rs | 5 +++-- src/value.rs | 10 ++++++++-- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/main.rs b/src/main.rs index 92f08a8..077f25b 100755 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,8 @@ fn main() -> Result<()> { let f = lua.create_function(a)?; globals.set("native_test", f)?; - let ud = lua.create_userdata("Vec2", Vec2 { x: 0.0, y: 0.0})?; + //let ud = lua.create_userdata("Vec2", Vec2 { x: 0.0, y: 0.0})?; + let ud = lua.create_userdata("Vec2", UserdataProxy::::new())?; globals.set("Vec2", ud)?; let tbl = lua.create_table()?; @@ -90,7 +91,7 @@ fn main() -> Result<()> { print("Vec2: " .. dump_table(Vec2)) print("Meta Vec2: " .. dump_table(getmetatable(Vec2))) - print("Vec2 is (" .. Vec2.x .. ", " .. Vec2.y .. ")") + --print("Vec2 is (" .. Vec2.x .. ", " .. Vec2.y .. ")") local v1 = Vec2.new(50, 50) print("v1 is (" .. v1.x .. ", " .. v1.y .. ")") @@ -172,6 +173,11 @@ pub enum Error { /// the error that describes what was wrong for this argument error: Arc }, + #[error("Incorrect number of arguments, expected {arg_expected}, got {arg_count}")] + IncorrectArgCount { + arg_expected: i32, + arg_count: i32, + }, #[error("There is already a registry entry with the key {0}")] RegistryConflict(String) } @@ -189,7 +195,7 @@ impl Error { /// /// This method never returns pub unsafe fn throw_lua(self, lua: *mut lua::lua_State) -> ! { - let msg = format!("{}", self); + let msg = format!("{}\0", self); let msg_c = msg.as_ptr() as *const i8; lua::luaL_error(lua, msg_c); unreachable!(); @@ -268,18 +274,6 @@ impl<'a> PushToLuaStack<'a> for String { } } -/* impl<'a> FromLuaStack<'a> for String { - unsafe fn from_lua_stack(state: &'a State) -> Result { - let s = state.state_ptr(); - - let cstr = lua::lua_tostring(s, -1); - lua::lua_pop(s, 1); - - let cstr = CStr::from_ptr(cstr); - Ok(cstr.to_str().unwrap().to_string()) - } -} */ - impl<'a> FromLua<'a> for String { fn from_lua(_lua: &State, val: Value) -> crate::Result { val.as_string().cloned() @@ -315,6 +309,18 @@ impl Userdata for Vec2 { .function("new", |lua, (x, y)| { lua.create_userdata("Vec2", Vec2 { x, y, }) }) + + // method test + .method("add", |lua, lhs: &Vec2, (rhs,): (&Vec2,)| { + let lx = lhs.x; + let ly = lhs.y; + + let rx = rhs.x; + let ry = rhs.y; + + lua.create_userdata("Vec2", Vec2 { x: lx + rx, y: ly + ry, }) + }) + .meta_method(MetaMethod::Add, |lua, lhs: &Vec2, (rhs,): (&Vec2,)| { let lx = lhs.x; let ly = lhs.y; @@ -349,14 +355,11 @@ impl Userdata for UserdataProxy { let mut other = UserdataBuilder::::new(); T::build(&mut other)?; - builder.name(&other.name.unwrap()); + let name = format!("{}Proxy", other.name.unwrap()); + builder.name = Some(name); - /* for (lbl, getters) in other.field_getters.into_iter() { - let wrap = |state: &State, data: &Self| { - Ok(()) - }; - builder.field_getter(&lbl, wrap); - } */ + // only the functions need to be added since they're the only thing usable from a proxy + builder.functions = other.functions; Ok(()) } diff --git a/src/state.rs b/src/state.rs index c8be57b..7ebd956 100755 --- a/src/state.rs +++ b/src/state.rs @@ -323,6 +323,7 @@ impl State { let lua_func = self.create_function(move |lua: &State, vals: ValueVec| { func(lua, vals) })?; + // Safety: This will be alive for as long as the lua state is alive let lua_func: Function<'_> = unsafe { mem::transmute(lua_func) }; fns_table.insert(func_name, lua_func); @@ -332,7 +333,7 @@ impl State { // dont create an index function if there are no getters, // or if an index metamethod was defined - if !getters.is_empty() || !builder.meta_methods.contains_key("__index") { + if (!getters.is_empty() || !fns_table.is_empty()) || !builder.meta_methods.contains_key("__index") { let index_fn = self.create_function(move |lua: &State, (ud, key): (AnyUserdata, String)| { if let Some(getter) = getters.get(&key) { let r = getter(lua, ValueVec::from(Value::Userdata(ud)))?; @@ -360,7 +361,7 @@ impl State { Ok(Value::None) } else { - Ok(Value::Nil) + Err(Error::Runtime(format!("attempt to assign a nil field, {}", key))) } })?; diff --git a/src/value.rs b/src/value.rs index 9a1f5a9..92950b6 100755 --- a/src/value.rs +++ b/src/value.rs @@ -238,7 +238,10 @@ macro_rules! impl_from_lua_vec_tuple { fn from_lua_value_vec(state: &'a State, mut values: ValueVec<'a>) -> crate::Result { if values.len() != $count { - panic!("Not same length"); // TODO + return Err(crate::Error::IncorrectArgCount { + arg_expected: $count, + arg_count: values.len() as i32, + }); } let f = $first::from_lua(state, values.pop_front().unwrap())?; @@ -256,7 +259,10 @@ macro_rules! impl_from_lua_vec_tuple { impl<'a, $only: FromLua<'a>> FromLuaVec<'a> for ($only,) { fn from_lua_value_vec(state: &'a State, mut values: ValueVec<'a>) -> crate::Result { if values.len() != 1 { - panic!("Not same length"); // TODO + return Err(crate::Error::IncorrectArgCount { + arg_expected: 1, + arg_count: $count, + }); } Ok( ( $only::from_lua(state, values.pop_front().unwrap())?, ) )