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!(u16);
|
||||||
impl_as_lua_number!(u32);
|
impl_as_lua_number!(u32);
|
||||||
impl_as_lua_number!(u64);
|
impl_as_lua_number!(u64);
|
||||||
|
impl_as_lua_number!(usize);
|
||||||
|
|
||||||
impl_as_lua_number!(f32);
|
impl_as_lua_number!(f32);
|
||||||
impl_as_lua_number!(f64);
|
impl_as_lua_number!(f64);
|
||||||
|
@ -142,3 +143,28 @@ impl<'a> PushToLuaStack<'a> for &str {
|
||||||
Ok(())
|
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 {
|
impl Userdata for Vec2 {
|
||||||
fn build<'a>(_state: &State, builder: &mut UserdataBuilder<'a, Vec2>) -> crate::Result<()> {
|
fn build<'a>(_state: &State, builder: &mut UserdataBuilder<'a, Vec2>) -> crate::Result<()> {
|
||||||
builder
|
builder
|
||||||
.field_getter("x", |_, this| this.x)
|
.field_getter("x", |_, this| Ok(this.x))
|
||||||
.field_getter("y", |_, this| this.y)
|
.field_getter("y", |_, this| Ok(this.y))
|
||||||
.field_setter("x", |_, this, x: f32| this.x = x)
|
.field_setter("x", |_, this, x: f32| {
|
||||||
.field_setter("y", |_, this, y: f32| this.y = y)
|
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 }))
|
.function("new", |lua, (x, y)| lua.create_userdata(Vec2 { x, y }))
|
||||||
// method test
|
// method test
|
||||||
.method("add", |lua, lhs: &Vec2, (rhs,): (Ref<Vec2>,)| {
|
.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 struct UserdataBuilder<'a, T> {
|
||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
|
pub(crate) field_consts: HashMap<String, UserdataFn<'a>>,
|
||||||
pub(crate) field_getters: HashMap<String, UserdataFn<'a>>,
|
pub(crate) field_getters: HashMap<String, UserdataFn<'a>>,
|
||||||
pub(crate) field_setters: HashMap<String, UserdataFn<'a>>,
|
pub(crate) field_setters: HashMap<String, UserdataFn<'a>>,
|
||||||
pub(crate) functions: 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 {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: T::name(),
|
name: T::name(),
|
||||||
|
field_consts: HashMap::new(),
|
||||||
field_getters: HashMap::new(),
|
field_getters: HashMap::new(),
|
||||||
field_setters: HashMap::new(),
|
field_setters: HashMap::new(),
|
||||||
functions: 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
|
where
|
||||||
F: Fn(&'a State, &T) -> R + 'static,
|
//F: Fn(&'a State) -> R + 'static,
|
||||||
R: AsLua<'a>,
|
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 wrapped: Arc<OnceCell<Box<dyn Fn(AnyUserdata<'_>) -> Result<*const (), crate::Error>>>> = unsafe { mem::transmute(wrapped) };
|
||||||
|
|
||||||
let ud_name = self.name.clone();
|
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.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
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn field_setter<F, V>(&mut self, name: &str, f: F) -> &mut Self
|
pub fn field_setter<F, V>(&mut self, name: &str, f: F) -> &mut Self
|
||||||
where
|
where
|
||||||
F: Fn(&'a State, &mut T, V) -> () + 'static,
|
F: Fn(&'a State, &mut T, V) -> crate::Result<()> + 'static,
|
||||||
V: FromLua<'a>,
|
V: FromLua<'a>,
|
||||||
T: Userdata + 'static
|
T: Userdata + 'static
|
||||||
{
|
{
|
||||||
|
@ -101,11 +142,11 @@ impl<'a, T: Userdata> UserdataBuilder<'a, T> {
|
||||||
let this_ptr = this_ptr.cast::<T>();
|
let this_ptr = this_ptr.cast::<T>();
|
||||||
let this = unsafe { this_ptr.as_mut().unwrap() };
|
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 {
|
} else {
|
||||||
let mut this = this.as_mut::<T>()?;
|
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));
|
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> {
|
impl<'a> PushToLuaStack<'a> for ValueVec<'a> {
|
||||||
unsafe fn push_to_lua_stack(&self, state: &'a State) -> crate::Result<()> {
|
unsafe fn push_to_lua_stack(&self, state: &'a State) -> crate::Result<()> {
|
||||||
for v in self.iter() {
|
for v in self.iter() {
|
||||||
|
@ -465,13 +448,6 @@ macro_rules! impl_from_lua_vec_for_from_lua {
|
||||||
Some(1)
|
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) => {
|
($type: tt) => {
|
||||||
impl<'a> FromLuaVec<'a> for $type {
|
impl<'a> FromLuaVec<'a> for $type {
|
||||||
|
@ -490,16 +466,11 @@ macro_rules! impl_from_lua_vec_for_from_lua {
|
||||||
Some(1)
|
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!(i64);
|
||||||
|
impl_from_lua_vec_for_from_lua!(usize);
|
||||||
impl_from_lua_vec_for_from_lua!(u64);
|
impl_from_lua_vec_for_from_lua!(u64);
|
||||||
impl_from_lua_vec_for_from_lua!(i16);
|
impl_from_lua_vec_for_from_lua!(i16);
|
||||||
impl_from_lua_vec_for_from_lua!(u16);
|
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!(Function, 'a);
|
||||||
impl_from_lua_vec_for_from_lua!(AnyUserdata, '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 {
|
impl<'a, T: AsLua<'a>> IntoLuaVec<'a> for T {
|
||||||
fn into_lua_value_vec(self, state: &'a State) -> crate::Result<ValueVec<'a>> {
|
fn into_lua_value_vec(self, state: &'a State) -> crate::Result<ValueVec<'a>> {
|
||||||
let mut v = ValueVec::new();
|
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 {
|
macro_rules! impl_from_lua_vec_tuple {
|
||||||
( $count: expr, $last: tt, $( $name: tt ),+ ) => (
|
( $count: expr, $last: tt, $( $name: tt ),+ ) => (
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -709,3 +664,22 @@ macro_rules! impl_from_lua_vec_tuple {
|
||||||
// hopefully 16 is more than enough
|
// hopefully 16 is more than enough
|
||||||
// if you have 16 function results, and need more than 16, you NEED help
|
// 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_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