WIP rust api

This commit is contained in:
IQuant 2024-11-03 16:06:41 +03:00
parent 9700b2cf48
commit 3494eb07a0
9 changed files with 342 additions and 5 deletions

97
ewext/Cargo.lock generated
View file

@ -45,6 +45,7 @@ dependencies = [
"backtrace", "backtrace",
"iced-x86", "iced-x86",
"libloading", "libloading",
"noita_api_macro",
] ]
[[package]] [[package]]
@ -53,6 +54,12 @@ version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "iced-x86" name = "iced-x86"
version = "1.21.0" version = "1.21.0"
@ -62,6 +69,12 @@ dependencies = [
"lazy_static", "lazy_static",
] ]
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@ -99,6 +112,17 @@ dependencies = [
"adler2", "adler2",
] ]
[[package]]
name = "noita_api_macro"
version = "0.1.0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"serde",
"serde_json",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.5" version = "0.36.5"
@ -108,12 +132,85 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "proc-macro2"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.24" version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "serde"
version = "1.0.214"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.214"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "2.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.6" version = "0.52.6"

View file

@ -15,3 +15,4 @@ strip = true
libloading = "0.8.5" libloading = "0.8.5"
backtrace = "0.3.74" backtrace = "0.3.74"
iced-x86 = "1.21.0" iced-x86 = "1.21.0"
noita_api_macro = {path = "noita_api_macro"}

105
ewext/noita_api_macro/Cargo.lock generated Normal file
View file

@ -0,0 +1,105 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "noita_api_macro"
version = "0.1.0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"serde",
"serde_json",
]
[[package]]
name = "proc-macro2"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "serde"
version = "1.0.214"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.214"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "2.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"

View file

@ -0,0 +1,14 @@
[package]
name = "noita_api_macro"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
heck = "0.5.0"
proc-macro2 = "1.0.89"
quote = "1.0.37"
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132"

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,96 @@
use heck::ToSnekCase;
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use serde::Deserialize;
#[derive(Deserialize)]
enum Typ {
#[serde(rename = "int")]
Int,
#[serde(rename = "uint32")]
UInt,
#[serde(rename = "float")]
Float,
#[serde(rename = "bool")]
Bool,
#[serde(rename = "std::string")]
StdString,
#[serde(rename = "vec2")]
Vec2,
#[serde(other)]
Other,
}
impl Typ {
fn as_rust_type(&self) -> proc_macro2::TokenStream {
match self {
Typ::Int => quote!(i32),
Typ::UInt => quote!(u32),
Typ::Float => quote!(f32),
Typ::Bool => quote!(bool),
Typ::StdString => todo!(),
Typ::Vec2 => todo!(),
Typ::Other => todo!(),
}
}
}
#[derive(Deserialize)]
struct Field {
field: String,
typ: Typ,
desc: String,
}
#[derive(Deserialize)]
struct Component {
name: String,
fields: Vec<Field>,
}
#[proc_macro]
pub fn generate_components(_item: TokenStream) -> TokenStream {
let components: Vec<Component> = serde_json::from_str(include_str!("components.json")).unwrap();
let res = components.into_iter().map(generate_code_for_component);
quote! {#(#res)*}.into()
}
fn convert_field_name(field_name: &str) -> String {
if field_name == "type" {
return "type_fld".to_owned();
}
if field_name == "loop" {
return "loop_fld".to_owned();
}
field_name.to_snek_case()
}
fn generate_code_for_component(com: Component) -> proc_macro2::TokenStream {
let component_name = format_ident!("{}", com.name);
let impls = com.fields.iter().filter_map(|field| {
let field_name = format_ident!("{}", convert_field_name(&field.field));
let field_doc = &field.desc;
match field.typ {
Typ::Int | Typ::UInt | Typ::Float | Typ::Bool => {
let field_type = field.typ.as_rust_type();
let set_method_name = format_ident!("set_{}", field_name);
Some(quote! {
#[doc = #field_doc]
fn #field_name(self) -> #field_type { todo!() }
fn #set_method_name(self, value: #field_type) { todo!() }
})
}
_ => None,
}
});
quote! {
#[derive(Clone, Copy, PartialEq, Eq)]
struct #component_name(u32);
impl #component_name {
#(#impls)*
}
}
}

View file

@ -1,6 +1,9 @@
use std::{ffi::c_void, mem}; use std::{ffi::c_void, mem};
pub(crate) mod ntypes; pub(crate) mod ntypes;
mod api {
noita_api_macro::generate_components!();
}
#[repr(packed)] #[repr(packed)]
pub(crate) struct NoitaPixelRun { pub(crate) struct NoitaPixelRun {

View file

@ -1,23 +1,40 @@
import shlex import shlex
import json import json
all_types = set()
renames = {
"std_string": "std::string",
}
def parse_component(component): def parse_component(component):
it = iter(component) it = iter(component)
name = next(it) c_name = next(it)
c_name = c_name.strip("\n")
if "-" in c_name or "\n" in c_name:
print(component)
exit(-1)
fields = [] fields = []
for line in it: for line in it:
line = line.strip() line = line.strip()
if line.startswith("-"): if line.startswith("-"):
continue continue
typ, name, *range_info, desc = shlex.split(line) typ, name, *range_info, desc = shlex.split(line)
name = name.strip("\n")
if name == "-":
print(f"Field of type {typ} skipped")
continue
typ = renames.get(typ, typ)
fields.append({ fields.append({
"field": name, "field": name,
"typ": typ, "typ": typ,
"desc": desc, "desc": desc,
}) })
all_types.add(typ)
#print(name, typ, desc, range_info) #print(name, typ, desc, range_info)
return { return {
"name": name, "name": c_name,
"fields": fields, "fields": fields,
} }
@ -26,7 +43,8 @@ path = "/home/quant/.local/share/Steam/steamapps/common/Noita/tools_modding/comp
components = [] components = []
current = [] current = []
for line in open(path):
for i, line in enumerate(open(path)):
if line == "\n": if line == "\n":
if current: if current:
components.append(current) components.append(current)
@ -37,5 +55,7 @@ for line in open(path):
assert not current assert not current
parsed = [parse_component(component) for component in components] parsed = [parse_component(component) for component in components]
json.dump(parsed, open("components.json", "w"), indent=None) json.dump(parsed, open("ewext/noita_api_macro/src/components.json", "w"), indent=None)
#print(*all_types, sep="\n")