Implement lua types for usize, make userdata field setter and getters return results
ci/woodpecker/push/debug Pipeline was successful
Details
ci/woodpecker/push/debug Pipeline was successful
Details
This commit is contained in:
parent
9b542fb523
commit
d32c138e99
26
src/lib.rs
26
src/lib.rs
|
@ -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)
|
||||
}
|
||||
}
|
14
src/tests.rs
14
src/tests.rs
|
@ -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>,)| {
|
||||
|
|
|
@ -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));
|
||||
|
|
66
src/value.rs
66
src/value.rs
|
@ -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!()
|
||||
}
|
||||
} */
|
Loading…
Reference in New Issue