mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
Allow Vec<T> in returns
This commit is contained in:
parent
0f26126ad9
commit
2c065fc4f7
6 changed files with 968 additions and 274 deletions
|
@ -26,7 +26,7 @@ impl EntityID {
|
||||||
tag: Option<Cow<'_, str>>,
|
tag: Option<Cow<'_, str>>,
|
||||||
) -> eyre::Result<Option<C>> {
|
) -> eyre::Result<Option<C>> {
|
||||||
raw::entity_get_first_component(self, C::NAME_STR.into(), tag)
|
raw::entity_get_first_component(self, C::NAME_STR.into(), tag)
|
||||||
.map(|x| x.map(Into::into))
|
.map(|x| x.flatten().map(Into::into))
|
||||||
.wrap_err_with(|| eyre!("Failed to get first component {} for {self:?}", C::NAME_STR))
|
.wrap_err_with(|| eyre!("Failed to get first component {} for {self:?}", C::NAME_STR))
|
||||||
}
|
}
|
||||||
pub fn get_first_component<C: Component>(self, tag: Option<Cow<'_, str>>) -> eyre::Result<C> {
|
pub fn get_first_component<C: Component>(self, tag: Option<Cow<'_, str>>) -> eyre::Result<C> {
|
||||||
|
|
|
@ -105,6 +105,19 @@ impl LuaState {
|
||||||
unsafe { LUA.lua_getfield(self.lua, LUA_GLOBALSINDEX, name.as_ptr()) };
|
unsafe { LUA.lua_getfield(self.lua, LUA_GLOBALSINDEX, name.as_ptr()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn objlen(&self, index: i32) -> usize {
|
||||||
|
unsafe { LUA.lua_objlen(self.lua, index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn index_table(&self, table_index: i32, index_in_table: usize) {
|
||||||
|
self.push_integer(index_in_table as isize);
|
||||||
|
if table_index < 0 {
|
||||||
|
unsafe { LUA.lua_gettable(self.lua, table_index - 1) };
|
||||||
|
} else {
|
||||||
|
unsafe { LUA.lua_gettable(self.lua, table_index) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn pop_last(&self) {
|
pub fn pop_last(&self) {
|
||||||
unsafe { LUA.lua_settop(self.lua, -2) };
|
unsafe { LUA.lua_settop(self.lua, -2) };
|
||||||
}
|
}
|
||||||
|
@ -122,6 +135,10 @@ impl LuaState {
|
||||||
// lua_error does not return.
|
// lua_error does not return.
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_nil_or_none(&self, index: i32) -> bool {
|
||||||
|
(unsafe { LUA.lua_type(self.lua, index) }) <= 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used for types that can be returned from functions that were defined in rust to lua.
|
/// Used for types that can be returned from functions that were defined in rust to lua.
|
||||||
|
@ -346,6 +363,33 @@ impl LuaGetValue for Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: LuaGetValue> LuaGetValue for Option<T> {
|
||||||
|
fn get(lua: LuaState, index: i32) -> eyre::Result<Self> {
|
||||||
|
Ok(if lua.is_nil_or_none(index) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(T::get(lua, index)?)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: LuaGetValue> LuaGetValue for Vec<T> {
|
||||||
|
fn get(lua: LuaState, index: i32) -> eyre::Result<Self> {
|
||||||
|
if T::size_on_stack() != 1 {
|
||||||
|
bail!("Encountered Vec<T> where T needs more than 1 slot on the stack. This isn't supported");
|
||||||
|
}
|
||||||
|
let len = lua.objlen(index);
|
||||||
|
let mut res = Vec::with_capacity(len);
|
||||||
|
for i in 1..=len {
|
||||||
|
lua.index_table(index, dbg!(i));
|
||||||
|
let get = T::get(lua, -1);
|
||||||
|
lua.pop_last();
|
||||||
|
res.push(get?);
|
||||||
|
}
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T0: LuaGetValue, T1: LuaGetValue> LuaGetValue for (T0, T1) {
|
impl<T0: LuaGetValue, T1: LuaGetValue> LuaGetValue for (T0, T1) {
|
||||||
fn get(lua: LuaState, index: i32) -> eyre::Result<Self>
|
fn get(lua: LuaState, index: i32) -> eyre::Result<Self>
|
||||||
where
|
where
|
||||||
|
|
|
@ -108,7 +108,24 @@ struct FnArg {
|
||||||
struct FnRet {
|
struct FnRet {
|
||||||
// name: String,
|
// name: String,
|
||||||
typ: Typ2,
|
typ: Typ2,
|
||||||
// optional: bool,
|
optional: bool,
|
||||||
|
is_vec: bool,
|
||||||
|
}
|
||||||
|
impl FnRet {
|
||||||
|
fn as_rust_type_return(&self) -> proc_macro2::TokenStream {
|
||||||
|
let mut ret = self.typ.as_rust_type_return();
|
||||||
|
if self.is_vec {
|
||||||
|
ret = quote! {
|
||||||
|
Vec<#ret>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if self.optional {
|
||||||
|
ret = quote! {
|
||||||
|
Option<#ret>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -230,9 +247,9 @@ fn generate_code_for_api_fn(api_fn: ApiFn) -> proc_macro2::TokenStream {
|
||||||
} else {
|
} else {
|
||||||
if api_fn.rets.len() == 1 {
|
if api_fn.rets.len() == 1 {
|
||||||
let ret = api_fn.rets.first().unwrap();
|
let ret = api_fn.rets.first().unwrap();
|
||||||
ret.typ.as_rust_type_return()
|
ret.as_rust_type_return()
|
||||||
} else {
|
} else {
|
||||||
let ret_types = api_fn.rets.iter().map(|ret| ret.typ.as_rust_type_return());
|
let ret_types = api_fn.rets.iter().map(|ret| ret.as_rust_type_return());
|
||||||
quote! { ( #(#ret_types),* ) }
|
quote! { ( #(#ret_types),* ) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -123,18 +123,15 @@ fn test_fn(_lua: LuaState) -> eyre::Result<()> {
|
||||||
let hp = damage_model.hp()?;
|
let hp = damage_model.hp()?;
|
||||||
damage_model.set_hp(hp - 1.0)?;
|
damage_model.set_hp(hp - 1.0)?;
|
||||||
|
|
||||||
let transform = noita_api::raw::entity_get_transform(player)?;
|
let (x, y, _, _, _) = noita_api::raw::entity_get_transform(player)?;
|
||||||
|
|
||||||
noita_api::raw::game_print(
|
noita_api::raw::game_print(
|
||||||
format!(
|
format!("Component: {:?}, Hp: {}", damage_model.0, hp * 25.0,).into(),
|
||||||
"Component: {:?}, Hp: {}, tranform: {:?}",
|
|
||||||
damage_model.0,
|
|
||||||
hp * 25.0,
|
|
||||||
transform
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let entities = noita_api::raw::entity_get_in_radius_with_tag(x, y, 300.0, "enemy".into())?;
|
||||||
|
noita_api::raw::game_print(format!("{:?}", entities).into())?;
|
||||||
|
|
||||||
// noita::api::raw::entity_set_transform(player, 0.0, 0.0, 0.0, 1.0, 1.0)?;
|
// noita::api::raw::entity_set_transform(player, 0.0, 0.0, 0.0, 1.0, 1.0)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -27,6 +27,10 @@ def maybe_map_types(name, typ):
|
||||||
typ = "bool"
|
typ = "bool"
|
||||||
if typ == "boolean":
|
if typ == "boolean":
|
||||||
typ = "bool"
|
typ = "bool"
|
||||||
|
if typ == "item_entity_id":
|
||||||
|
typ = "entity_id"
|
||||||
|
if typ == "physics_body_id":
|
||||||
|
raise ValueError(f"{typ} not supported")
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
def parse_arg(arg_s):
|
def parse_arg(arg_s):
|
||||||
|
@ -61,11 +65,16 @@ def parse_ret(ret_s):
|
||||||
|
|
||||||
if "|" in ret_s:
|
if "|" in ret_s:
|
||||||
raise ValueError("multiple return types not supported")
|
raise ValueError("multiple return types not supported")
|
||||||
if "{" in ret_s:
|
|
||||||
raise ValueError("tables in returns not supported")
|
|
||||||
if "multiple_types" in ret_s:
|
if "multiple_types" in ret_s:
|
||||||
raise ValueError("no 'multiple_types' either")
|
raise ValueError("no 'multiple_types' either")
|
||||||
|
|
||||||
|
returns_vec = False
|
||||||
|
if ret_s.startswith("{"):
|
||||||
|
ret_s = ret_s.removeprefix("{").removesuffix("}")
|
||||||
|
returns_vec = True
|
||||||
|
if "-" in ret_s:
|
||||||
|
raise ValueError("No support for key-value tables in returns")
|
||||||
|
|
||||||
typ = ret_s
|
typ = ret_s
|
||||||
name = None
|
name = None
|
||||||
if ":" in ret_s:
|
if ":" in ret_s:
|
||||||
|
@ -80,7 +89,8 @@ def parse_ret(ret_s):
|
||||||
return {
|
return {
|
||||||
"name": name,
|
"name": name,
|
||||||
"typ": typ,
|
"typ": typ,
|
||||||
"optional": optional
|
"optional": optional,
|
||||||
|
"is_vec": returns_vec,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue