mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
Handle arguments for lua functions in a better way
This commit is contained in:
parent
66a5a009e2
commit
d62fb39a93
3 changed files with 115 additions and 14 deletions
|
@ -14,6 +14,7 @@ noita_api_macro::generate_components!();
|
||||||
|
|
||||||
pub mod raw {
|
pub mod raw {
|
||||||
use super::{Color, ComponentID, EntityID, Obj};
|
use super::{Color, ComponentID, EntityID, Obj};
|
||||||
|
use crate::lua::LuaPutValue;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::lua::LuaState;
|
use crate::lua::LuaState;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod lua_bindings;
|
pub mod lua_bindings;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
ffi::{c_char, c_int, CStr},
|
ffi::{c_char, c_int, CStr},
|
||||||
mem, slice,
|
mem, slice,
|
||||||
|
@ -10,6 +11,8 @@ use std::{
|
||||||
use eyre::{bail, Context, OptionExt};
|
use eyre::{bail, Context, OptionExt};
|
||||||
use lua_bindings::{lua_CFunction, lua_State, Lua51, LUA_GLOBALSINDEX};
|
use lua_bindings::{lua_CFunction, lua_State, Lua51, LUA_GLOBALSINDEX};
|
||||||
|
|
||||||
|
use crate::{Color, ComponentID, EntityID, Obj};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static CURRENT_LUA_STATE: Cell<Option<LuaState>> = Cell::default();
|
static CURRENT_LUA_STATE: Cell<Option<LuaState>> = Cell::default();
|
||||||
}
|
}
|
||||||
|
@ -121,6 +124,7 @@ impl LuaState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used for types that can be returned from functions that were defined in rust to lua.
|
||||||
pub trait LuaFnRet {
|
pub trait LuaFnRet {
|
||||||
fn do_return(self, lua: LuaState) -> c_int;
|
fn do_return(self, lua: LuaState) -> c_int;
|
||||||
}
|
}
|
||||||
|
@ -150,3 +154,93 @@ impl<R: LuaFnRet> LuaFnRet for eyre::Result<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait for arguments that can be put on lua stack.
|
||||||
|
pub(crate) trait LuaPutValue {
|
||||||
|
fn put(&self, lua: LuaState);
|
||||||
|
fn is_non_empty(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for i32 {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
lua.push_integer(*self as isize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for isize {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
lua.push_integer(*self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for u32 {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
lua.push_integer(unsafe { mem::transmute::<_, i32>(*self) as isize });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for f64 {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
lua.push_number(*self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for bool {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
lua.push_bool(*self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for Cow<'_, str> {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
lua.push_string(self.as_ref());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for str {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
lua.push_string(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for EntityID {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
self.0.put(lua);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for ComponentID {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
self.0.put(lua);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for Color {
|
||||||
|
fn put(&self, _lua: LuaState) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaPutValue for Obj {
|
||||||
|
fn put(&self, _lua: LuaState) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: LuaPutValue> LuaPutValue for Option<T> {
|
||||||
|
fn put(&self, lua: LuaState) {
|
||||||
|
match self {
|
||||||
|
Some(val) => val.put(lua),
|
||||||
|
None => lua.push_nil(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_non_empty(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Some(val) => val.is_non_empty(),
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -228,19 +228,23 @@ fn generate_code_for_api_fn(api_fn: ApiFn) -> proc_macro2::TokenStream {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let put_args = api_fn.args.iter().map(|arg| {
|
let put_args_pre = api_fn.args.iter().enumerate().map(|(i, arg)| {
|
||||||
let optional = arg.default.is_some();
|
|
||||||
let arg_name = format_ident!("{}", arg.name);
|
let arg_name = format_ident!("{}", arg.name);
|
||||||
let arg_push = arg.typ.generate_lua_push(arg_name.clone());
|
let i = i as i32;
|
||||||
if optional {
|
quote! {
|
||||||
quote! {
|
if LuaPutValue::is_non_empty(&#arg_name) {
|
||||||
match #arg_name {
|
last_non_empty = #i;
|
||||||
Some(#arg_name) => #arg_push,
|
}
|
||||||
None => lua.push_nil(),
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
let put_args = api_fn.args.iter().enumerate().map(|(i, arg)| {
|
||||||
|
let arg_name = format_ident!("{}", arg.name);
|
||||||
|
let i = i as i32;
|
||||||
|
quote! {
|
||||||
|
if #i <= last_non_empty {
|
||||||
|
LuaPutValue::put(&#arg_name, lua);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
arg_push
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -266,7 +270,6 @@ fn generate_code_for_api_fn(api_fn: ApiFn) -> proc_macro2::TokenStream {
|
||||||
|
|
||||||
let fn_name_c = name_to_c_literal(api_fn.fn_name);
|
let fn_name_c = name_to_c_literal(api_fn.fn_name);
|
||||||
|
|
||||||
let arg_count = api_fn.args.len() as i32;
|
|
||||||
let ret_count = api_fn.rets.len() as i32;
|
let ret_count = api_fn.rets.len() as i32;
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -275,9 +278,12 @@ fn generate_code_for_api_fn(api_fn: ApiFn) -> proc_macro2::TokenStream {
|
||||||
let lua = LuaState::current()?;
|
let lua = LuaState::current()?;
|
||||||
|
|
||||||
lua.get_global(#fn_name_c);
|
lua.get_global(#fn_name_c);
|
||||||
#(#put_args;)*
|
|
||||||
|
|
||||||
lua.call(#arg_count, #ret_count);
|
let mut last_non_empty: i32 = -1;
|
||||||
|
#(#put_args_pre)*
|
||||||
|
#(#put_args)*
|
||||||
|
|
||||||
|
lua.call(last_non_empty+1, #ret_count);
|
||||||
|
|
||||||
let ret = Ok(#ret_expr);
|
let ret = Ok(#ret_expr);
|
||||||
lua.pop_last_n(#ret_count);
|
lua.pop_last_n(#ret_count);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue