Implement lua types for usize, make userdata field setter and getters return results
ci/woodpecker/push/debug Pipeline was successful Details

This commit is contained in:
SeanOMik 2024-02-19 17:57:19 -05:00
parent 9b542fb523
commit d32c138e99
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
4 changed files with 104 additions and 57 deletions

View File

@ -107,6 +107,7 @@ impl_as_lua_number!(u8);
impl_as_lua_number!(u16);
impl_as_lua_number!(u32);
impl_as_lua_number!(u64);
impl_as_lua_number!(usize);
impl_as_lua_number!(f32);
impl_as_lua_number!(f64);
@ -141,4 +142,29 @@ impl<'a> PushToLuaStack<'a> for &str {
Ok(())
}
}
impl<'a> AsLua<'a> for bool {
fn as_lua(self, _lua: &'a State) -> crate::Result<Value<'a>> {
Ok(Value::Boolean(self))
}
}
impl<'a> FromLua<'a> for bool {
fn from_lua(_lua: &State, val: Value) -> crate::Result<Self> {
match val {
Value::Boolean(v) => Ok(v),
_ => Err(Error::type_mismatch(
"Boolean",
&val.type_name(),
)),
}
}
}
impl<'a> PushToLuaStack<'a> for bool {
unsafe fn push_to_lua_stack(&self, state: &'a State) -> crate::Result<()> {
let v = self.as_lua(state)?;
v.push_to_lua_stack(state)
}
}

View File

@ -10,10 +10,16 @@ pub struct Vec2 {
impl Userdata for Vec2 {
fn build<'a>(_state: &State, builder: &mut UserdataBuilder<'a, Vec2>) -> crate::Result<()> {
builder
.field_getter("x", |_, this| this.x)
.field_getter("y", |_, this| this.y)
.field_setter("x", |_, this, x: f32| this.x = x)
.field_setter("y", |_, this, y: f32| this.y = y)
.field_getter("x", |_, this| Ok(this.x))
.field_getter("y", |_, this| Ok(this.y))
.field_setter("x", |_, this, x: f32| {
this.x = x;
Ok(())
})
.field_setter("y", |_, this, y: f32| {
this.y = y;
Ok(())
})
.function("new", |lua, (x, y)| lua.create_userdata(Vec2 { x, y }))
// method test
.method("add", |lua, lhs: &Vec2, (rhs,): (Ref<Vec2>,)| {

View File

@ -8,6 +8,7 @@ pub type UserdataMutGetterFn<'a> = Arc<OnceCell<Box<dyn Fn(AnyUserdata<'a>) -> c
pub struct UserdataBuilder<'a, T> {
pub(crate) name: String,
pub(crate) field_consts: HashMap<String, UserdataFn<'a>>,
pub(crate) field_getters: HashMap<String, UserdataFn<'a>>,
pub(crate) field_setters: HashMap<String, UserdataFn<'a>>,
pub(crate) functions: HashMap<String, UserdataFn<'a>>,
@ -23,6 +24,7 @@ impl<'a, T: Userdata> UserdataBuilder<'a, T> {
pub fn new() -> Self {
Self {
name: T::name(),
field_consts: HashMap::new(),
field_getters: HashMap::new(),
field_setters: HashMap::new(),
functions: HashMap::new(),
@ -33,13 +35,14 @@ impl<'a, T: Userdata> UserdataBuilder<'a, T> {
}
}
pub fn field_getter<F, R>(&mut self, name: &str, f: F) -> &mut Self
pub fn field<R>(&mut self, name: &str, f: R) -> &mut Self
where
F: Fn(&'a State, &T) -> R + 'static,
//F: Fn(&'a State) -> R + 'static,
R: AsLua<'a>,
T: Userdata + 'static
//T: Userdata + 'static
{
let wrapped = self.wrapped_getter.clone();
todo!()
/* let wrapped = self.wrapped_getter.clone();
let wrapped: Arc<OnceCell<Box<dyn Fn(AnyUserdata<'_>) -> Result<*const (), crate::Error>>>> = unsafe { mem::transmute(wrapped) };
let ud_name = self.name.clone();
@ -68,12 +71,50 @@ impl<'a, T: Userdata> UserdataBuilder<'a, T> {
};
self.field_getters.insert(name.to_string(), Box::new(wrap));
self */
}
pub fn field_getter<F, R>(&mut self, name: &str, f: F) -> &mut Self
where
F: Fn(&'a State, &T) -> crate::Result<R> + 'static,
R: AsLua<'a>,
T: Userdata + 'static
{
let wrapped = self.wrapped_getter.clone();
let wrapped: Arc<OnceCell<Box<dyn Fn(AnyUserdata<'_>) -> Result<*const (), crate::Error>>>> = unsafe { mem::transmute(wrapped) };
let ud_name = self.name.clone();
let fn_name = name.to_string();
let wrap = move |lua: &'a State, mut val: ValueVec<'a>| {
let val = val.pop_front().unwrap();
let this = val.as_userdata().unwrap(); // if this panics, its a bug
if let Some(getter) = wrapped.get() {
let this_ptr = Self::result_to_bad_arg(
getter(this.clone()),
&ud_name,
&fn_name,
1,
Some("self")
)?;
let this_ptr = this_ptr.cast::<T>();
let this = unsafe { &*this_ptr };
f(lua, this)?.as_lua(lua)
} else {
let this = this.as_ref::<T>()?;
f(lua, &*this)?.as_lua(lua)
}
};
self.field_getters.insert(name.to_string(), Box::new(wrap));
self
}
pub fn field_setter<F, V>(&mut self, name: &str, f: F) -> &mut Self
where
F: Fn(&'a State, &mut T, V) -> () + 'static,
F: Fn(&'a State, &mut T, V) -> crate::Result<()> + 'static,
V: FromLua<'a>,
T: Userdata + 'static
{
@ -101,11 +142,11 @@ impl<'a, T: Userdata> UserdataBuilder<'a, T> {
let this_ptr = this_ptr.cast::<T>();
let this = unsafe { this_ptr.as_mut().unwrap() };
f(lua, this, v_arg).as_lua(lua)
f(lua, this, v_arg)?.as_lua(lua)
} else {
let mut this = this.as_mut::<T>()?;
f(lua, this.deref_mut(), v_arg).as_lua(lua)
f(lua, this.deref_mut(), v_arg)?.as_lua(lua)
}
};
self.field_setters.insert(name.to_string(), Box::new(wrap));

View File

@ -417,23 +417,6 @@ impl<'a> IntoLuaVec<'a> for ValueVec<'a> {
}
}
/* impl<'a> FromLua<'a> for ValueVec<'a> {
fn from_lua(_lua: &'a State, val: Value<'a>) -> crate::Result<Self> {
match val {
Value::Variable(v) => Ok(v),
_ => {
Ok(ValueVec::from(val))
}
}
}
} */
/* impl<'a> FromLuaVec<'a> for ValueVec<'a> {
fn from_lua_value_vec(_state: &'a State, values: ValueVec<'a>) -> crate::Result<Self> {
Ok(values)
}
} */
impl<'a> PushToLuaStack<'a> for ValueVec<'a> {
unsafe fn push_to_lua_stack(&self, state: &'a State) -> crate::Result<()> {
for v in self.iter() {
@ -465,13 +448,6 @@ macro_rules! impl_from_lua_vec_for_from_lua {
Some(1)
}
}
/* impl<'a> IntoLuaVec<'a> for $type<'a> {
fn into_lua_value_vec(self, state: &'a State) -> crate::Result<ValueVec<'a>> {
Ok(ValueVec::from(self.as_lua(state)?))
}
} */
};
($type: tt) => {
impl<'a> FromLuaVec<'a> for $type {
@ -490,16 +466,11 @@ macro_rules! impl_from_lua_vec_for_from_lua {
Some(1)
}
}
/* impl<'a> IntoLuaVec<'a> for $type {
fn into_lua_value_vec(self, state: &'a State) -> crate::Result<ValueVec<'a>> {
Ok(ValueVec::from(self.as_lua(state)?))
}
} */
};
}
impl_from_lua_vec_for_from_lua!(i64);
impl_from_lua_vec_for_from_lua!(usize);
impl_from_lua_vec_for_from_lua!(u64);
impl_from_lua_vec_for_from_lua!(i16);
impl_from_lua_vec_for_from_lua!(u16);
@ -516,16 +487,6 @@ impl_from_lua_vec_for_from_lua!(Value, 'a);
impl_from_lua_vec_for_from_lua!(Function, 'a);
impl_from_lua_vec_for_from_lua!(AnyUserdata, 'a);
/* impl<'a, T: FromLua<'a>> FromLuaVec<'a> for T {
fn from_lua_value_vec(state: &'a State, mut values: ValueVec<'a>) -> crate::Result<Self> {
if let Some(v) = values.pop_front() {
Ok(T::from_lua(state, v)?)
} else {
Err(Error::Nil)
}
}
} */
impl<'a, T: AsLua<'a>> IntoLuaVec<'a> for T {
fn into_lua_value_vec(self, state: &'a State) -> crate::Result<ValueVec<'a>> {
let mut v = ValueVec::new();
@ -607,12 +568,6 @@ impl<'a> FromLuaVec<'a> for () {
}
}
/* impl<'a> IntoLuaVec<'a> for () {
fn into_lua_value_vec(self, _state: &'a State) -> crate::Result<ValueVec<'a>> {
Ok(ValueVec::new())
}
} */
macro_rules! impl_from_lua_vec_tuple {
( $count: expr, $last: tt, $( $name: tt ),+ ) => (
#[allow(non_snake_case)]
@ -709,3 +664,22 @@ macro_rules! impl_from_lua_vec_tuple {
// hopefully 16 is more than enough
// if you have 16 function results, and need more than 16, you NEED help
impl_from_lua_vec_tuple! { 16, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16 }
impl<'a, T: AsLua<'a>, const N: usize> AsLua<'a> for [T; N] {
fn as_lua(self, lua: &'a State) -> crate::Result<Value<'a>> {
let table = lua.create_table()?;
for (idx, t) in self.into_iter().enumerate() {
table.set(idx + 1, t)?;
}
Ok(Value::Table(table))
}
}
// TODO: Find out a way to implement this
/* impl<'a, T: FromLua> FromLuaVec<'a> for T {
fn from_lua_value_vec(state: &'a State, values: ValueVec<'a>) -> crate::Result<Self> {
todo!()
}
} */