Add UserDataProxy

This commit is contained in:
SeanOMik 2024-01-27 15:53:34 -05:00
parent a8db62fe08
commit 044b08a10e
3 changed files with 36 additions and 26 deletions

View File

@ -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::<Vec2>::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>
},
#[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<Self> {
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<Self> {
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<T: Userdata> Userdata for UserdataProxy<T> {
let mut other = UserdataBuilder::<T>::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(())
}

View File

@ -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)))
}
})?;

View File

@ -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<Self> {
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<Self> {
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())?, ) )