From 7e8da942ad0a4035f897a3b8821b45d4c74a1dfa Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Sun, 4 Feb 2024 19:46:01 +0700 Subject: [PATCH 01/17] :construction: work in progress --- src/args.rs | 9 +++++++++ src/cli.rs | 5 ++++- src/main.rs | 4 ++++ src/show/args.rs | 14 ++++++++++++++ src/show/mod.rs | 15 +++++++++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/show/args.rs create mode 100644 src/show/mod.rs diff --git a/src/args.rs b/src/args.rs index cd762bd..bc4e3e8 100644 --- a/src/args.rs +++ b/src/args.rs @@ -55,6 +55,15 @@ pub struct PathNames { pub path: std::vec::Vec, } +#[derive(clap::Args, Debug)] +pub struct OptionalPathNames { + /// filter by widget path name(s) + /// + /// e.g. "main_canvas.Arrival.Arrival_GPS_Canvas.Arrival_GPS_Elements_Canvas" + #[arg(short, long, value_parser = parse_path_names, value_name = "NAMES")] + pub path: Option>, +} + #[derive(clap::Args, Debug)] pub struct Mode { /// optionally output as JSON, Redscript or table (default) diff --git a/src/cli.rs b/src/cli.rs index 93730d4..2723e41 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,6 @@ use clap::Parser; -use crate::{list, whereis, whois}; +use crate::{list, show, whereis, whois}; #[allow(clippy::upper_case_acronyms)] #[derive(Parser)] // requires `derive` feature @@ -14,4 +14,7 @@ pub enum CLI { /// get full path indexes from path names #[command(name = "whereis")] WhereIs(whereis::Args), + /// show a particular widget + #[command(name = "show")] + Show(show::Args), } diff --git a/src/main.rs b/src/main.rs index 473d0ff..b262e10 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,11 +5,13 @@ mod args; mod cli; mod list; mod read; +mod show; mod whereis; mod whois; use list::list; use read::read; +use show::show; use whereis::whereis; use whois::whois; @@ -19,11 +21,13 @@ fn main() { CLI::List(list::Args { ref files, .. }) => files, CLI::WhoIs(whois::Args { ref files, .. }) => files, CLI::WhereIs(whereis::Args { ref files, .. }) => files, + CLI::Show(show::Args { ref files, .. }) => files, }; let (widget, anim) = read(files); match args { CLI::List(args) => list(args, widget, anim), CLI::WhoIs(args) => whois(args, widget, anim), CLI::WhereIs(args) => whereis(args, widget, anim), + CLI::Show(args) => show(args, widget, anim), }; } diff --git a/src/show/args.rs b/src/show/args.rs new file mode 100644 index 0000000..5bc9d50 --- /dev/null +++ b/src/show/args.rs @@ -0,0 +1,14 @@ +use crate::args::{Files, OptionalPathIndexes, OptionalPathNames}; + +#[derive(clap::Args, Debug)] +#[command()] +pub struct Args { + #[command(flatten)] + pub files: Files, + + #[command(flatten)] + pub indexes: OptionalPathIndexes, + + #[command(flatten)] + pub names: OptionalPathNames, +} diff --git a/src/show/mod.rs b/src/show/mod.rs new file mode 100644 index 0000000..d9c16e7 --- /dev/null +++ b/src/show/mod.rs @@ -0,0 +1,15 @@ +mod args; +pub(crate) use args::Args; +use inkanim::{anim::InkAnimAnimationLibraryResource, widget::inkWidgetLibraryResource}; + +pub(crate) fn show( + args: Args, + _widget: inkWidgetLibraryResource, + _anim: InkAnimAnimationLibraryResource, +) { + match (args.indexes.path, args.names.path) { + (None, None) | (Some(_), Some(_)) => panic!("please specify either --indexes or --names"), + (None, Some(_names)) => todo!(), + (Some(_indexes), None) => todo!(), + } +} From 31feec37b8a87fb0ae1dd9bca13356745565c0ab Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Sun, 4 Feb 2024 20:08:24 +0700 Subject: [PATCH 02/17] :construction: work in progress --- src/args.rs | 2 +- src/show/mod.rs | 33 +++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/args.rs b/src/args.rs index bc4e3e8..c7bbc52 100644 --- a/src/args.rs +++ b/src/args.rs @@ -61,7 +61,7 @@ pub struct OptionalPathNames { /// /// e.g. "main_canvas.Arrival.Arrival_GPS_Canvas.Arrival_GPS_Elements_Canvas" #[arg(short, long, value_parser = parse_path_names, value_name = "NAMES")] - pub path: Option>, + pub names: Option>, } #[derive(clap::Args, Debug)] diff --git a/src/show/mod.rs b/src/show/mod.rs index d9c16e7..ac68a68 100644 --- a/src/show/mod.rs +++ b/src/show/mod.rs @@ -1,15 +1,40 @@ mod args; pub(crate) use args::Args; -use inkanim::{anim::InkAnimAnimationLibraryResource, widget::inkWidgetLibraryResource}; +use inkanim::{ + anim::InkAnimAnimationLibraryResource, + widget::{inkWidgetLibraryResource, ByName}, +}; pub(crate) fn show( args: Args, - _widget: inkWidgetLibraryResource, + widget: inkWidgetLibraryResource, _anim: InkAnimAnimationLibraryResource, ) { - match (args.indexes.path, args.names.path) { + match (args.indexes.path, args.names.names) { (None, None) | (Some(_), Some(_)) => panic!("please specify either --indexes or --names"), - (None, Some(_names)) => todo!(), + (None, Some(names)) => { + if names.is_empty() { + panic!("please specify the names tree"); + } + let (first, others) = names.split_at(1); + let (_, mut parent) = widget + .root_chunk() + .root_widget + .by_name(first.first().unwrap()) + .unwrap_or_else(|| { + panic!("unable to find widget in tree: {names:#?}"); + }); + let last_idx = names.len() - 1; + for (idx, name) in others.iter().enumerate() { + if parent.is_leaf() && idx < last_idx { + panic!("unable to find widget in tree: {names:#?}"); + } + (_, parent) = parent.as_compound().unwrap().by_name(name).unwrap_or_else(|| { + panic!("unable to find widget in tree: {names:#?}"); + }); + } + println!("{:#?}", parent); + } (Some(_indexes), None) => todo!(), } } From c007bac52b28384c9e4f591e1cc6ea1e87e245d4 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Tue, 6 Feb 2024 22:22:11 +0700 Subject: [PATCH 03/17] :alembic: codegen from derive types --- Cargo.lock | 105 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + macros/Cargo.toml | 19 +++++++ macros/src/lib.rs | 94 +++++++++++++++++++++++++++++++++++ src/ink/mod.rs | 41 ++++++++++++++- src/ink/widget/layout.rs | 11 +++- src/ink/widget/mod.rs | 13 +++-- src/lib.rs | 8 +++ src/show/mod.rs | 59 +++++++++++++--------- 9 files changed, 322 insertions(+), 30 deletions(-) create mode 100644 macros/Cargo.toml create mode 100644 macros/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ccff15b..4d92e79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -167,6 +167,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "const-combine" +version = "0.1.0" +source = "git+https://github.com/jac3km4/const-combine?rev=v0.1.4#1a3310b205964b72f8bb15223a4fd31285e7c1d2" + +[[package]] +name = "const-crc32" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68d13f542d70e5b339bf46f6f74704ac052cfd526c58cd87996bd1ef4615b9a0" + [[package]] name = "core-foundation-sys" version = "0.8.3" @@ -266,12 +277,23 @@ dependencies = [ "chrono", "clap", "enum_dispatch", + "inkanim-macros", + "red4ext-rs", "serde", "serde-aux", "serde_json", "term-table", ] +[[package]] +name = "inkanim-macros" +version = "0.3.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "itoa" version = "1.0.5" @@ -332,6 +354,26 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "once_cell" version = "1.17.0" @@ -356,6 +398,29 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "red4ext-rs" +version = "0.5.3" +source = "git+https://github.com/jac3km4/red4ext-rs.git?rev=2646318#26463186d9cd5a10fc296009f7eb0663efc0b55e" +dependencies = [ + "const-combine", + "red4ext-sys", + "thiserror", + "wchar", +] + +[[package]] +name = "red4ext-sys" +version = "0.5.3" +source = "git+https://github.com/jac3km4/red4ext-rs.git?rev=2646318#26463186d9cd5a10fc296009f7eb0663efc0b55e" +dependencies = [ + "const-crc32", + "cxx", + "cxx-build", + "num_enum", + "thiserror", +] + [[package]] name = "regex" version = "1.7.1" @@ -475,6 +540,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "unicode-ident" version = "1.0.6" @@ -547,6 +632,26 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +[[package]] +name = "wchar" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1ca6ea80317e76471c3aa6d47efb151ef04538960ab810845a1c854f5cd7d8c" +dependencies = [ + "wchar-impl", +] + +[[package]] +name = "wchar-impl" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "075c93156fed21f9dab57af5e81604d0fdb67432c919a8c1f78bb979f06a3d25" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 0b0535c..74cf8a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ path = "src/main.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +inkanim-macros = { path = "./macros"} enum_dispatch = "0.3.12" serde = { version = "1", features = ["derive"] } serde-aux = "4.4.0" @@ -27,4 +28,5 @@ chrono = { version = "0.4.33", default-features = false, features = [ "serde", ] } clap = { version = "4.4.18", features = ["derive"] } +red4ext-rs = { git = "https://github.com/jac3km4/red4ext-rs.git", rev = "2646318" } term-table = "1.3.2" diff --git a/macros/Cargo.toml b/macros/Cargo.toml new file mode 100644 index 0000000..3b8b8e2 --- /dev/null +++ b/macros/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "inkanim-macros" +version = "0.3.0" +edition = "2021" +authors = ["Roms1383"] +license = "MIT OR Apache-2.0" +categories = ["command-line-utilities"] +repository = "https://github.com/cyb3rpsych0s1s/inkanim" +publish = false + +[lib] +proc-macro = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +syn = "2" +proc-macro2 = "1" +quote = "1" diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 0000000..92e8b5f --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,94 @@ +use proc_macro::TokenStream; +use syn::parse_macro_input; +use quote::quote; + +#[proc_macro_derive(RedsWidget)] +pub fn derive_reds_widget(item: TokenStream) -> TokenStream { + let syn::DeriveInput{ ident, data, .. } = parse_macro_input!(item as syn::DeriveInput); + match &data { + syn::Data::Struct(data) => derive_reds_widget_for_struct(&ident, data), + syn::Data::Enum(_) | syn::Data::Union(_) => syn::Error::new(ident.span(), "RedsWidget cannot be derived neither on union nor enum") + .to_compile_error() + .into(), + } +} + +#[proc_macro_derive(RedsValue)] +pub fn derive_reds_value(item: TokenStream) -> TokenStream { + let syn::DeriveInput{ ident, data, .. } = parse_macro_input!(item as syn::DeriveInput); + match &data { + syn::Data::Enum(data) => derive_reds_value_for_enum(&ident, data), + syn::Data::Struct(data) => derive_reds_value_for_struct(&ident, data), + syn::Data::Union(_) => syn::Error::new(ident.span(), "RedsValue cannot be derived on union") + .to_compile_error() + .into(), + } +} + +/// used with Redscript inkWidget class descendants +fn derive_reds_widget_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) -> TokenStream { + let oneliners = r#struct.fields.iter().map(|x| x.ident.clone()); + quote! { + impl crate::RedsWidget for #name { + fn reds_widget(&self, instance: &str, parent: Option<&str>) -> String { + use ::red4ext_rs::conv::NativeRepr; + use crate::RedsValue; + let mut steps = vec![]; + steps.push(format!("let {} = new {}();", instance, Self::NAME)); + #( + if let Some(v) = self.#oneliners.reds_value() { + steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), v)); + } + )* + if let Some(parent) = parent { + steps.push(format!("{}.AddChild({});", parent, instance)); + } + steps.join("\n") + } + } + }.into() +} + +/// used with Redscript native struct +fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) -> TokenStream { + let fields = r#struct.fields.iter().map(|x| x.ident.clone()); + quote! { + impl crate::RedsValue for #name { + fn reds_value(&self) -> Option { + use ::red4ext_rs::conv::NativeRepr; + if self == &Self::default() { + return None; + } + Some(format!("new {}({})", Self::NAME, ::std::stringify!(#(self.#fields),*))) + } + } + }.into() +} + +/// used with Redscript enums +fn derive_reds_value_for_enum(name: &syn::Ident, r#enum: &syn::DataEnum) -> TokenStream { + let matches = r#enum.variants.iter().map(|x| { + let variant = &x.ident; + if x.fields.len() > 0 { + return syn::Error::new(variant.span(), "RedsValue can only be derived on enum with unit variants") + .to_compile_error() + .into() + } + quote!{ + #name::#variant => Some(::std::format!("{}.{}", Self::NAME, ::std::stringify!(#variant))) + } + }); + quote! { + impl crate::RedsValue for #name { + fn reds_value(&self) -> Option { + use ::red4ext_rs::conv::NativeRepr; + if self == &Self::default() { + return None; + } + match self { + #(#matches),* + } + } + } + }.into() +} \ No newline at end of file diff --git a/src/ink/mod.rs b/src/ink/mod.rs index 608c736..a545462 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -1,5 +1,6 @@ use std::path::PathBuf; +use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use serde_aux::prelude::*; @@ -77,7 +78,7 @@ pub struct File { } /// see [NativeDB](https://nativedb.red4ext.com/Vector2) -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, PartialOrd)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, PartialOrd, RedsValue)] #[serde(tag = "$type")] #[serde(rename_all = "PascalCase")] pub struct Vector2 { @@ -85,6 +86,10 @@ pub struct Vector2 { pub y: f32, } +unsafe impl red4ext_rs::prelude::NativeRepr for Vector2 { + const NAME: &'static str = "Vector2"; +} + /// see [NativeDB](https://nativedb.red4ext.com/HDRColor) #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, PartialOrd)] #[serde(tag = "$type")] @@ -180,3 +185,37 @@ impl InkAnimSequence { out } } + +#[cfg(test)] +mod tests { + use inkanim_macros::RedsWidget; + + use crate::{widget::layout::inkEHorizontalAlign, RedsWidget, Vector2}; + + #[derive(RedsWidget, Debug, Clone, Default, PartialEq)] + pub struct TestParent { + pub child: TestChild, + } + unsafe impl red4ext_rs::prelude::NativeRepr for TestParent { + const NAME: &'static str = "TestParent"; + } + #[derive(RedsWidget, Debug, Clone, Default, PartialEq)] + pub struct TestChild { + pub content_h_align: inkEHorizontalAlign, + pub size: Vector2, + } + unsafe impl red4ext_rs::prelude::NativeRepr for TestChild { + const NAME: &'static str = "TChild"; + } + #[test] + fn reds() { + let testouille = TestChild { + content_h_align: inkEHorizontalAlign::Fill, + size: Vector2 { x: 0., y: 0. }, + }; + assert_eq!(testouille.reds_widget("test", None), + r#"let test = new TChild(); +return test;"# + ); + } +} diff --git a/src/ink/widget/layout.rs b/src/ink/widget/layout.rs index 9d7a102..095d204 100644 --- a/src/ink/widget/layout.rs +++ b/src/ink/widget/layout.rs @@ -1,3 +1,4 @@ +use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use crate::Vector2; @@ -24,17 +25,23 @@ pub enum inkEAnchor { } #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, RedsValue)] pub enum inkEHorizontalAlign { + #[default] Fill = 0, Left = 1, Center = 2, Right = 3, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkEHorizontalAlign { + const NAME: &'static str = "inkEHorizontalAlign"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] pub enum inkEVerticalAlign { + #[default] Fill = 0, Top = 1, Center = 2, diff --git a/src/ink/widget/mod.rs b/src/ink/widget/mod.rs index ebedac4..9493927 100644 --- a/src/ink/widget/mod.rs +++ b/src/ink/widget/mod.rs @@ -3,11 +3,11 @@ //! All the widgets in Cybperunk 2077 UI //! are similar to the web and traditional UI frameworks. -mod font; -mod image; +pub mod font; +pub mod image; pub(crate) mod implementation; -mod layout; -mod properties; +pub mod layout; +pub mod properties; use enum_dispatch::enum_dispatch; pub use implementation::*; @@ -135,6 +135,11 @@ native_leaf_widget!(inkCircleWidget); native_leaf_widget!(inkRectangleWidget); native_leaf_widget!(inkVectorGraphicWidget); +unsafe impl red4ext_rs::prelude::NativeRepr for inkTextWidget { + const NAME: &'static str = "inkText"; + const NATIVE_NAME: &'static str = "inkTextWidget"; +} + /// any widget #[allow(clippy::enum_variant_names)] #[allow(non_camel_case_types)] diff --git a/src/lib.rs b/src/lib.rs index 898a763..0f7be70 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,10 @@ mod ink; pub use ink::*; + +pub trait RedsValue { + fn reds_value(&self) -> Option; +} + +pub trait RedsWidget { + fn reds_widget(&self, name: &str, parent: Option<&str>) -> String; +} diff --git a/src/show/mod.rs b/src/show/mod.rs index ac68a68..0f45000 100644 --- a/src/show/mod.rs +++ b/src/show/mod.rs @@ -5,6 +5,34 @@ use inkanim::{ widget::{inkWidgetLibraryResource, ByName}, }; +fn reds(widget: &inkWidgetLibraryResource, names: &[&str]) { + if names.is_empty() { + panic!("please specify the names tree"); + } + let (first, others) = names.split_at(1); + let (_, mut parent) = widget + .root_chunk() + .root_widget + .by_name(first.first().unwrap()) + .unwrap_or_else(|| { + panic!("unable to find widget in tree: {names:#?}"); + }); + let last_idx = names.len() - 1; + for (idx, name) in others.iter().enumerate() { + if parent.is_leaf() && idx < last_idx { + panic!("unable to find widget in tree: {names:#?}"); + } + (_, parent) = parent + .as_compound() + .unwrap() + .by_name(name) + .unwrap_or_else(|| { + panic!("unable to find widget in tree: {names:#?}"); + }); + } + println!("{:#?}", parent); +} + pub(crate) fn show( args: Args, widget: inkWidgetLibraryResource, @@ -12,29 +40,14 @@ pub(crate) fn show( ) { match (args.indexes.path, args.names.names) { (None, None) | (Some(_), Some(_)) => panic!("please specify either --indexes or --names"), - (None, Some(names)) => { - if names.is_empty() { - panic!("please specify the names tree"); - } - let (first, others) = names.split_at(1); - let (_, mut parent) = widget - .root_chunk() - .root_widget - .by_name(first.first().unwrap()) - .unwrap_or_else(|| { - panic!("unable to find widget in tree: {names:#?}"); - }); - let last_idx = names.len() - 1; - for (idx, name) in others.iter().enumerate() { - if parent.is_leaf() && idx < last_idx { - panic!("unable to find widget in tree: {names:#?}"); - } - (_, parent) = parent.as_compound().unwrap().by_name(name).unwrap_or_else(|| { - panic!("unable to find widget in tree: {names:#?}"); - }); - } - println!("{:#?}", parent); - } + (None, Some(names)) => reds( + &widget, + names + .iter() + .map(|x| x.as_str()) + .collect::>() + .as_slice(), + ), (Some(_indexes), None) => todo!(), } } From 68103f34f4a5e0377033258bb16434de7d63f34b Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Tue, 6 Feb 2024 22:53:20 +0700 Subject: [PATCH 04/17] :alembic: codegen from derive types --- macros/src/lib.rs | 6 +++++- src/ink/mod.rs | 51 +++++++++++++++++++++++++++++++++++------------ src/lib.rs | 16 +++++++++++++++ 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 92e8b5f..a74a956 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -59,7 +59,11 @@ fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) - if self == &Self::default() { return None; } - Some(format!("new {}({})", Self::NAME, ::std::stringify!(#(self.#fields),*))) + let mut args = Vec::::new(); + #( + args.push(self.#fields.reds_value().unwrap()); + )* + Some(format!("new {}({})", Self::NAME, args.join(", "))) } } }.into() diff --git a/src/ink/mod.rs b/src/ink/mod.rs index a545462..5e199a7 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -192,13 +192,13 @@ mod tests { use crate::{widget::layout::inkEHorizontalAlign, RedsWidget, Vector2}; - #[derive(RedsWidget, Debug, Clone, Default, PartialEq)] - pub struct TestParent { - pub child: TestChild, - } - unsafe impl red4ext_rs::prelude::NativeRepr for TestParent { - const NAME: &'static str = "TestParent"; - } + // #[derive(RedsWidget, Debug, Clone, Default, PartialEq)] + // pub struct TestParent { + // pub element: TestChild, + // } + // unsafe impl red4ext_rs::prelude::NativeRepr for TestParent { + // const NAME: &'static str = "TestParent"; + // } #[derive(RedsWidget, Debug, Clone, Default, PartialEq)] pub struct TestChild { pub content_h_align: inkEHorizontalAlign, @@ -208,14 +208,39 @@ mod tests { const NAME: &'static str = "TChild"; } #[test] - fn reds() { - let testouille = TestChild { + fn reds_default() { + let child = TestChild { content_h_align: inkEHorizontalAlign::Fill, size: Vector2 { x: 0., y: 0. }, }; - assert_eq!(testouille.reds_widget("test", None), - r#"let test = new TChild(); -return test;"# - ); + assert_eq!( + child.reds_widget("element", None), + r#"let element = new TChild();"# + ); + } + #[test] + fn reds_simple() { + let child = TestChild { + content_h_align: inkEHorizontalAlign::Center, + size: Vector2 { x: 1., y: 0.6 }, + }; + assert_eq!( + child.reds_widget("element", None), + r#"let element = new TChild(); +element.content_h_align = inkEHorizontalAlign.Center; +element.size = new Vector2(1., 0.6);"# + ); + } + #[test] + fn reds_tree() { + // let child = TestChild { + // content_h_align: inkEHorizontalAlign::Fill, + // size: Vector2 { x: 0., y: 0. }, + // }; + // let parent = TestParent { element: child }; + // assert_eq!( + // child.reds_widget("element", Some("parent")), + // r#"let element = new TChild();"# + // ); } } diff --git a/src/lib.rs b/src/lib.rs index 0f7be70..1490d11 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,12 @@ mod ink; pub use ink::*; +pub enum Reds { + Default, + OneLiner(String), + MultiStep { name: String, instantiation: String }, +} + pub trait RedsValue { fn reds_value(&self) -> Option; } @@ -8,3 +14,13 @@ pub trait RedsValue { pub trait RedsWidget { fn reds_widget(&self, name: &str, parent: Option<&str>) -> String; } + +impl RedsValue for f32 { + fn reds_value(&self) -> Option { + if self == &self.trunc() { + Some(format!("{}.", self)) + } else { + Some(format!("{}", self)) + } + } +} From feec07823fe2e980f61b79c0c076ac15d9ca7466 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Wed, 7 Feb 2024 10:25:01 +0700 Subject: [PATCH 05/17] :construction: work in progress --- src/ink/mod.rs | 36 +++++++++++++++-------- src/ink/widget/font.rs | 4 +-- src/ink/widget/image.rs | 23 ++++++++++++--- src/ink/widget/layout.rs | 43 +++++++++++++++++++++++---- src/ink/widget/mod.rs | 4 +-- src/lib.rs | 63 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 147 insertions(+), 26 deletions(-) diff --git a/src/ink/mod.rs b/src/ink/mod.rs index 5e199a7..eee9dc6 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -19,11 +19,11 @@ pub mod widget; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Name { #[serde(rename = "$type")] - r#type: String, + pub r#type: String, #[serde(rename = "$storage")] - storage: String, + pub storage: String, #[serde(rename = "$value")] - value: String, + pub value: String, } impl Name { @@ -46,12 +46,6 @@ pub struct ResourcePath { value: PathBuf, } -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(tag = "$type")] -pub enum DepotPath { - ResourcePath(ResourcePath), -} - #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct Data { @@ -101,6 +95,10 @@ pub struct HDRColor { pub red: f32, } +unsafe impl red4ext_rs::prelude::NativeRepr for HDRColor { + const NAME: &'static str = "HDRColor"; +} + /// asset handle ID #[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[serde(transparent)] @@ -118,17 +116,31 @@ pub struct InkWrapper { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CName(String); -#[derive(Debug, Clone, Serialize, Deserialize)] +unsafe impl red4ext_rs::prelude::NativeRepr for CName { + const NAME: &'static str = "CName"; +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum LocKey { ID(u32), Value(String), } /// specific translation ID -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct LocalizationString { #[serde(deserialize_with = "deserialize_lockey_from_anything")] - value: Option, + pub value: Option, +} + +impl Default for LocalizationString { + fn default() -> Self { + Self { value: None } + } +} + +unsafe impl red4ext_rs::prelude::NativeRepr for LocalizationString { + const NAME: &'static str = "LocalizationString"; } impl std::fmt::Display for InkWrapper diff --git a/src/ink/widget/font.rs b/src/ink/widget/font.rs index 802f770..3e6d482 100644 --- a/src/ink/widget/font.rs +++ b/src/ink/widget/font.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -use crate::{DepotPath, Name}; +use crate::Name; use super::Flags; @@ -8,7 +8,7 @@ use super::Flags; #[derive(Debug, Serialize, Clone, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct inkFontFamilyResource { - depot_path: DepotPath, + depot_path: Name, flags: Flags, } diff --git a/src/ink/widget/image.rs b/src/ink/widget/image.rs index 51a8ca3..82e9b23 100644 --- a/src/ink/widget/image.rs +++ b/src/ink/widget/image.rs @@ -1,6 +1,7 @@ +use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; -use crate::DepotPath; +use crate::Name; use super::Flags; @@ -8,24 +9,38 @@ use super::Flags; #[derive(Debug, Serialize, Clone, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct inkTextureAtlas { - depot_path: DepotPath, + depot_path: Name, flags: Flags, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkTextureAtlas { + const NAME: &'static str = "inkTextureAtlas"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default, RedsValue, PartialEq)] pub enum inkBrushMirrorType { + #[default] NoMirror = 0, Horizontal = 1, Vertical = 2, Both = 3, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkBrushMirrorType { + const NAME: &'static str = "inkBrushMirrorType"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default, RedsValue, PartialEq)] pub enum inkBrushTileType { + #[default] NoTile = 0, Horizontal = 1, Vertical = 2, Both = 3, } + +unsafe impl red4ext_rs::prelude::NativeRepr for inkBrushTileType { + const NAME: &'static str = "inkBrushTileType"; +} diff --git a/src/ink/widget/layout.rs b/src/ink/widget/layout.rs index 095d204..51770ae 100644 --- a/src/ink/widget/layout.rs +++ b/src/ink/widget/layout.rs @@ -4,8 +4,9 @@ use serde::{Deserialize, Serialize}; use crate::Vector2; #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] pub enum inkEAnchor { + #[default] TopLeft = 0, TopCenter = 1, TopRight = 2, @@ -24,6 +25,10 @@ pub enum inkEAnchor { Fill = 15, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkEAnchor { + const NAME: &'static str = "inkEAnchor"; +} + #[allow(non_camel_case_types)] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, RedsValue)] pub enum inkEHorizontalAlign { @@ -48,8 +53,12 @@ pub enum inkEVerticalAlign { Bottom = 3, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkEVerticalAlign { + const NAME: &'static str = "inkEVerticalAlign"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] pub struct inkUITransform { pub translation: Vector2, pub scale: Vector2, @@ -57,16 +66,25 @@ pub struct inkUITransform { pub rotation: f32, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkUITransform { + const NAME: &'static str = "inkUITransform"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] pub enum textJustificationType { + #[default] Left = 0, Center = 1, Right = 2, } +unsafe impl red4ext_rs::prelude::NativeRepr for textJustificationType { + const NAME: &'static str = "textJustificationType"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] #[serde(tag = "$type")] pub struct inkMargin { pub left: f32, @@ -75,8 +93,12 @@ pub struct inkMargin { pub bottom: f32, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkMargin { + const NAME: &'static str = "inkMargin"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] #[serde(tag = "$type", rename_all = "camelCase")] pub struct inkWidgetLayout { pub anchor: inkEAnchor, @@ -87,9 +109,18 @@ pub struct inkWidgetLayout { pub h_align: inkEHorizontalAlign, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkWidgetLayout { + const NAME: &'static str = "inkWidgetLayout"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] pub enum inkEChildOrder { + #[default] Forward = 0, Backward = 1, } + +unsafe impl red4ext_rs::prelude::NativeRepr for inkEChildOrder { + const NAME: &'static str = "inkEChildOrder"; +} diff --git a/src/ink/widget/mod.rs b/src/ink/widget/mod.rs index 9493927..f0228ef 100644 --- a/src/ink/widget/mod.rs +++ b/src/ink/widget/mod.rs @@ -15,7 +15,7 @@ pub use implementation::*; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_bool_from_anything; -use crate::{DepotPath, Name}; +use crate::Name; use self::{ font::{ @@ -203,7 +203,7 @@ pub struct inkWidgetLibraryItem { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct inkanimAnimationLibraryResource { - depot_path: DepotPath, + depot_path: Name, flags: Flags, } diff --git a/src/lib.rs b/src/lib.rs index 1490d11..0e99017 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,3 +24,66 @@ impl RedsValue for f32 { } } } + +impl RedsValue for i32 { + fn reds_value(&self) -> Option { + Some(format!("{}", self.clone())) + } +} + +impl RedsValue for u16 { + fn reds_value(&self) -> Option { + Some(format!("{}", self.clone())) + } +} + +impl RedsValue for bool { + fn reds_value(&self) -> Option { + if !self { + None + } else { + Some("true".to_string()) + } + } +} + +impl RedsValue for String { + fn reds_value(&self) -> Option { + if self.is_empty() { + None + } else { + Some(self.clone()) + } + } +} + +impl RedsValue for Name { + fn reds_value(&self) -> Option { + match ( + self.r#type.as_str(), + self.storage.as_str(), + self.value.as_str(), + ) { + ("ResourcePath", "string", "") => None, + ("ResourcePath", "string", v) => Some(format!("r\"{v}\"")), + ("CName", "string", "None") => None, + ("CName", "string", v) => Some(format!("n\"{v}\"")), + _ => unreachable!(), + } + } +} + +impl RedsValue for LocalizationString { + fn reds_value(&self) -> Option { + if let Some(ref v) = self.value { + return match v { + LocKey::ID(v) if v == &0 => None, + LocKey::ID(v) => Some(format!("LocKey#{}", v)), + LocKey::Value(v) if v.as_str() == "null" => None, + LocKey::Value(v) if v.as_str() == "None" => None, + LocKey::Value(v) => Some(format!("l\"{}\"", v)), + }; + } + None + } +} From fd4ea0dc465343150b55ba59bf449339cc47f86a Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Wed, 7 Feb 2024 11:07:02 +0700 Subject: [PATCH 06/17] :construction: work in progress : tuple and default values --- macros/src/lib.rs | 26 ++++++++++++++++++++++++-- src/ink/mod.rs | 12 +++++++++++- src/ink/widget/font.rs | 13 +++++++++++-- src/ink/widget/mod.rs | 8 +++++++- src/lib.rs | 6 ------ 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index a74a956..c8112b5 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,5 +1,5 @@ use proc_macro::TokenStream; -use syn::parse_macro_input; +use syn::{parse_macro_input, Fields}; use quote::quote; #[proc_macro_derive(RedsWidget)] @@ -51,6 +51,28 @@ fn derive_reds_widget_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) /// used with Redscript native struct fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) -> TokenStream { + let is_tuple = match r#struct.fields { + Fields::Unnamed(_) => true, + _ => false, + }; + if is_tuple { + let indexes = r#struct.fields.iter().enumerate().map(|(index, _)| syn::Index::from(index)); + return quote! { + impl crate::RedsValue for #name { + fn reds_value(&self) -> Option { + use ::red4ext_rs::conv::NativeRepr; + if self == &Self::default() { + return None; + } + let mut args = Vec::::new(); + #( + args.push(self.#indexes.reds_value().unwrap_or(self.#indexes.default())); + )* + Some(format!("new {}({})", Self::NAME, args.join(", "))) + } + } + }.into() + } let fields = r#struct.fields.iter().map(|x| x.ident.clone()); quote! { impl crate::RedsValue for #name { @@ -61,7 +83,7 @@ fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) - } let mut args = Vec::::new(); #( - args.push(self.#fields.reds_value().unwrap()); + args.push(self.#fields.reds_value().unwrap_or(self.#fields.default())); )* Some(format!("new {}({})", Self::NAME, args.join(", "))) } diff --git a/src/ink/mod.rs b/src/ink/mod.rs index eee9dc6..b891b97 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -16,7 +16,7 @@ pub mod anim; /// everything related to *.inkwidget* pub mod widget; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Name { #[serde(rename = "$type")] pub r#type: String, @@ -26,6 +26,16 @@ pub struct Name { pub value: String, } +impl Default for Name { + fn default() -> Self { + Self { + r#type: "CName".to_string(), + storage: "string".to_string(), + value: "None".to_string(), + } + } +} + impl Name { pub fn as_str(&self) -> &str { self.value.as_str() diff --git a/src/ink/widget/font.rs b/src/ink/widget/font.rs index 3e6d482..98b3a7d 100644 --- a/src/ink/widget/font.rs +++ b/src/ink/widget/font.rs @@ -1,3 +1,4 @@ +use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use crate::Name; @@ -5,17 +6,25 @@ use crate::Name; use super::Flags; #[allow(non_camel_case_types)] -#[derive(Debug, Serialize, Clone, Deserialize)] +#[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] #[serde(rename_all = "PascalCase")] pub struct inkFontFamilyResource { depot_path: Name, flags: Flags, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkFontFamilyResource { + const NAME: &'static str = "inkFontFamilyResource"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Serialize, Clone, Deserialize)] +#[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] pub struct fontStyle(Name); +unsafe impl red4ext_rs::prelude::NativeRepr for fontStyle { + const NAME: &'static str = "fontStyle"; +} + #[allow(non_camel_case_types, clippy::enum_variant_names)] #[derive(Debug, Serialize, Clone, Deserialize)] pub enum textLetterCase { diff --git a/src/ink/widget/mod.rs b/src/ink/widget/mod.rs index f0228ef..e462d0f 100644 --- a/src/ink/widget/mod.rs +++ b/src/ink/widget/mod.rs @@ -12,6 +12,7 @@ pub mod properties; use enum_dispatch::enum_dispatch; pub use implementation::*; +use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_bool_from_anything; @@ -33,14 +34,19 @@ pub trait SiblingOrNested { fn sibling_or_nested(&self, searched: &[usize]) -> bool; } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] #[non_exhaustive] pub enum Flags { + #[default] Default, Soft, Hard, } +unsafe impl red4ext_rs::prelude::NativeRepr for Flags { + const NAME: &'static str = "Flags"; +} + macro_rules! native_compound_widget { ($ty:ident) => { #[doc=concat!("see [NativeDB](https://nativedb.red4ext.com/", stringify!($ty), ")")] diff --git a/src/lib.rs b/src/lib.rs index 0e99017..a200f65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,6 @@ mod ink; pub use ink::*; -pub enum Reds { - Default, - OneLiner(String), - MultiStep { name: String, instantiation: String }, -} - pub trait RedsValue { fn reds_value(&self) -> Option; } From a27f20fda171de9b6ddf213cb9ba7339df53750b Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Wed, 7 Feb 2024 11:11:30 +0700 Subject: [PATCH 07/17] :construction: work in progress : tuple and default values --- macros/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index c8112b5..1bddea8 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -66,7 +66,7 @@ fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) - } let mut args = Vec::::new(); #( - args.push(self.#indexes.reds_value().unwrap_or(self.#indexes.default())); + args.push(self.#indexes.reds_value().unwrap_or(Default::default())); )* Some(format!("new {}({})", Self::NAME, args.join(", "))) } @@ -83,7 +83,7 @@ fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) - } let mut args = Vec::::new(); #( - args.push(self.#fields.reds_value().unwrap_or(self.#fields.default())); + args.push(self.#fields.reds_value().unwrap_or(Default::default())); )* Some(format!("new {}({})", Self::NAME, args.join(", "))) } From d1fc991fd2c932da4270a0523021d4b869a713a5 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Wed, 7 Feb 2024 16:32:52 +0700 Subject: [PATCH 08/17] :construction: work in progress : split into leaf/compound --- Cargo.lock | 7 ++ Cargo.toml | 1 + macros/src/lib.rs | 66 ++++++++++++++--- src/ink/mod.rs | 138 ++++++++++++++++++++++++++--------- src/ink/widget/font.rs | 28 ++++++- src/ink/widget/image.rs | 2 +- src/ink/widget/layout.rs | 2 +- src/ink/widget/mod.rs | 80 +++++++++++++++++--- src/ink/widget/properties.rs | 19 ++++- src/lib.rs | 81 ++++++++++++++++++++ src/show/mod.rs | 3 +- 11 files changed, 364 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d92e79..97fc9d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,6 +178,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68d13f542d70e5b339bf46f6f74704ac052cfd526c58cd87996bd1ef4615b9a0" +[[package]] +name = "const-str" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6" + [[package]] name = "core-foundation-sys" version = "0.8.3" @@ -276,6 +282,7 @@ version = "0.3.0" dependencies = [ "chrono", "clap", + "const-str", "enum_dispatch", "inkanim-macros", "red4ext-rs", diff --git a/Cargo.toml b/Cargo.toml index 74cf8a9..d8017b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ chrono = { version = "0.4.33", default-features = false, features = [ "std", "serde", ] } +const-str = "0.5.6" clap = { version = "4.4.18", features = ["derive"] } red4ext-rs = { git = "https://github.com/jac3km4/red4ext-rs.git", rev = "2646318" } term-table = "1.3.2" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 1bddea8..214a740 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,13 +1,24 @@ use proc_macro::TokenStream; -use syn::{parse_macro_input, Fields}; +use syn::{parse_macro_input, spanned::Spanned, Fields}; use quote::quote; -#[proc_macro_derive(RedsWidget)] -pub fn derive_reds_widget(item: TokenStream) -> TokenStream { +#[proc_macro_derive(RedsWidgetCompound)] +pub fn derive_reds_widget_compound(item: TokenStream) -> TokenStream { let syn::DeriveInput{ ident, data, .. } = parse_macro_input!(item as syn::DeriveInput); match &data { - syn::Data::Struct(data) => derive_reds_widget_for_struct(&ident, data), - syn::Data::Enum(_) | syn::Data::Union(_) => syn::Error::new(ident.span(), "RedsWidget cannot be derived neither on union nor enum") + syn::Data::Struct(data) => derive_reds_widget_compound_for_struct(&ident, data), + syn::Data::Enum(_) | syn::Data::Union(_) => syn::Error::new(ident.span(), "RedsWidgetCompound cannot be derived neither on union nor enum") + .to_compile_error() + .into(), + } +} + +#[proc_macro_derive(RedsWidgetLeaf)] +pub fn derive_reds_widget_leaf(item: TokenStream) -> TokenStream { + let syn::DeriveInput{ ident, data, .. } = parse_macro_input!(item as syn::DeriveInput); + match &data { + syn::Data::Struct(data) => derive_reds_widget_leaf_for_struct(&ident, data), + syn::Data::Enum(_) | syn::Data::Union(_) => syn::Error::new(ident.span(), "RedsWidgetLeaf cannot be derived neither on union nor enum") .to_compile_error() .into(), } @@ -26,11 +37,11 @@ pub fn derive_reds_value(item: TokenStream) -> TokenStream { } /// used with Redscript inkWidget class descendants -fn derive_reds_widget_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) -> TokenStream { +fn derive_reds_widget_leaf_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) -> TokenStream { let oneliners = r#struct.fields.iter().map(|x| x.ident.clone()); quote! { - impl crate::RedsWidget for #name { - fn reds_widget(&self, instance: &str, parent: Option<&str>) -> String { + impl crate::RedsWidgetLeaf for #name { + fn reds_widget_leaf(&self, instance: &str, parent: Option<&str>) -> String { use ::red4ext_rs::conv::NativeRepr; use crate::RedsValue; let mut steps = vec![]; @@ -40,9 +51,6 @@ fn derive_reds_widget_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), v)); } )* - if let Some(parent) = parent { - steps.push(format!("{}.AddChild({});", parent, instance)); - } steps.join("\n") } } @@ -117,4 +125,40 @@ fn derive_reds_value_for_enum(name: &syn::Ident, r#enum: &syn::DataEnum) -> Toke } } }.into() +} + +fn derive_reds_widget_compound_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) -> TokenStream { + let oneliners = r#struct.fields + .iter() + .filter(|x| x.ident != Some(syn::Ident::new(::std::stringify!(children), x.span()))) + .map(|x| x.ident.clone()); + quote! { + impl crate::RedsWidgetCompound for #name { + fn reds_widget_compound(&self, instance: &str, parent: Option<&str>) -> String { + use ::red4ext_rs::conv::NativeRepr; + use crate::widget::layout::inkEChildOrder; + use crate::RedsValue; + let mut steps = vec![]; + steps.push(format!("let {} = new {}();", instance, Self::NAME)); + #( + if let Some(v) = self.#oneliners.reds_value() { + steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), v)); + } + )* + let mut name; + if self.child_order == inkEChildOrder::Forward { + for child in self.children.iter() { + name = child.name().expect("no child to be a inkMultiChildren"); + steps.push(child.reds_widget(name, self.name.reds_value().as_deref())); + } + } else { + for child in self.children.iter().rev() { + name = child.name().expect("no child to be a inkMultiChildren"); + steps.push(child.reds_widget(name, self.name.reds_value().as_deref())); + } + } + steps.join("\n") + } + } + }.into() } \ No newline at end of file diff --git a/src/ink/mod.rs b/src/ink/mod.rs index b891b97..a76fb18 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -4,9 +4,11 @@ use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use serde_aux::prelude::*; +use crate::RedsWidget; + use self::{ anim::{InkAnimSequence, Target}, - widget::SiblingOrNested, + widget::{inkMultiChildren, SiblingOrNested, Widget}, }; mod conversion; use conversion::deserialize_lockey_from_anything; @@ -110,18 +112,44 @@ unsafe impl red4ext_rs::prelude::NativeRepr for HDRColor { } /// asset handle ID -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default, PartialEq, RedsValue)] #[serde(transparent)] pub struct HandleId(#[serde(deserialize_with = "deserialize_number_from_string")] u32); +unsafe impl red4ext_rs::prelude::NativeRepr for HandleId { + const NAME: &'static str = "HandleId"; +} + +#[cfg(test)] +impl From for HandleId { + fn from(value: u32) -> Self { + Self(value) + } +} + /// wrapper with handle ID -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] #[serde(rename_all = "PascalCase")] pub struct InkWrapper { pub handle_id: HandleId, pub data: T, } +impl InkWrapper { + pub fn iter(&self) -> std::slice::Iter<'_, InkWrapper> { + self.data.iter() + } +} + +impl RedsWidget for InkWrapper +where + T: RedsWidget, +{ + fn reds_widget(&self, name: &str, parent: Option<&str>) -> String { + self.data.reds_widget(name, parent) + } +} + /// specific resource ID #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CName(String); @@ -137,18 +165,12 @@ pub enum LocKey { } /// specific translation ID -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] pub struct LocalizationString { #[serde(deserialize_with = "deserialize_lockey_from_anything")] pub value: Option, } -impl Default for LocalizationString { - fn default() -> Self { - Self { value: None } - } -} - unsafe impl red4ext_rs::prelude::NativeRepr for LocalizationString { const NAME: &'static str = "LocalizationString"; } @@ -210,18 +232,13 @@ impl InkAnimSequence { #[cfg(test)] mod tests { - use inkanim_macros::RedsWidget; - - use crate::{widget::layout::inkEHorizontalAlign, RedsWidget, Vector2}; - - // #[derive(RedsWidget, Debug, Clone, Default, PartialEq)] - // pub struct TestParent { - // pub element: TestChild, - // } - // unsafe impl red4ext_rs::prelude::NativeRepr for TestParent { - // const NAME: &'static str = "TestParent"; - // } - #[derive(RedsWidget, Debug, Clone, Default, PartialEq)] + use inkanim_macros::RedsWidgetLeaf; + + use crate::{ + widget::{inkCanvasWidget, inkMultiChildren, inkTextWidget, layout::inkEHorizontalAlign}, + InkWrapper, RedsWidgetCompound, RedsWidgetLeaf, Vector2, + }; + #[derive(RedsWidgetLeaf, Debug, Clone, Default, PartialEq)] pub struct TestChild { pub content_h_align: inkEHorizontalAlign, pub size: Vector2, @@ -236,7 +253,7 @@ mod tests { size: Vector2 { x: 0., y: 0. }, }; assert_eq!( - child.reds_widget("element", None), + child.reds_widget_leaf("element", None), r#"let element = new TChild();"# ); } @@ -247,7 +264,7 @@ mod tests { size: Vector2 { x: 1., y: 0.6 }, }; assert_eq!( - child.reds_widget("element", None), + child.reds_widget_leaf("element", None), r#"let element = new TChild(); element.content_h_align = inkEHorizontalAlign.Center; element.size = new Vector2(1., 0.6);"# @@ -255,14 +272,69 @@ element.size = new Vector2(1., 0.6);"# } #[test] fn reds_tree() { - // let child = TestChild { - // content_h_align: inkEHorizontalAlign::Fill, - // size: Vector2 { x: 0., y: 0. }, - // }; - // let parent = TestParent { element: child }; - // assert_eq!( - // child.reds_widget("element", Some("parent")), - // r#"let element = new TChild();"# - // ); + let inner = inkTextWidget { + name: crate::Name { + r#type: "CName".to_string(), + storage: "string".to_string(), + value: "shape".to_string(), + }, + layout: crate::widget::layout::inkWidgetLayout { + ..Default::default() + }, + property_manager: None, + render_transform_pivot: Vector2 { x: 1., y: 3. }, + render_transform: crate::widget::layout::inkUITransform { + ..Default::default() + }, + size: Vector2 { x: 360., y: 100. }, + ..Default::default() + }; + let child = crate::widget::Widget::inkTextWidget(inner.clone()); + let parent = inkCanvasWidget { + children: InkWrapper { + handle_id: 1.into(), + data: inkMultiChildren { + children: vec![InkWrapper { + handle_id: 2.into(), + data: child, + }], + }, + }, + name: crate::Name { + r#type: "CName".to_string(), + storage: "string".to_string(), + value: "main_canvas".to_string(), + }, + child_order: crate::widget::layout::inkEChildOrder::Backward, + child_margin: crate::widget::layout::inkMargin { + left: 0., + right: 0., + top: 0., + bottom: 0., + }, + }; + assert_eq!( + inner.reds_widget_leaf("element", Some("parent")), + r#"let element = new inkText(); +element.name = n"shape"; +element.render_transform_pivot = new Vector2(1., 3.); +element.size = new Vector2(360., 100.); +element.line_height_percentage = 0.; +element.scroll_delay = 0; +element.scroll_text_speed = 0.;"# + ); + assert_eq!( + parent.reds_widget_compound("parent", None), + r#"let parent = new inkCanvas(); +parent.name = n"main_canvas"; +parent.child_order = inkEChildOrder.Backward; +let shape = new inkText(); +shape.name = n"shape"; +shape.render_transform_pivot = new Vector2(1., 3.); +shape.size = new Vector2(360., 100.); +shape.line_height_percentage = 0.; +shape.scroll_delay = 0; +shape.scroll_text_speed = 0.;"# + ); } } diff --git a/src/ink/widget/font.rs b/src/ink/widget/font.rs index 98b3a7d..71a9480 100644 --- a/src/ink/widget/font.rs +++ b/src/ink/widget/font.rs @@ -26,32 +26,48 @@ unsafe impl red4ext_rs::prelude::NativeRepr for fontStyle { } #[allow(non_camel_case_types, clippy::enum_variant_names)] -#[derive(Debug, Serialize, Clone, Deserialize)] +#[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] pub enum textLetterCase { + #[default] OriginalCase = 0, UpperCase = 1, LowerCase = 2, } +unsafe impl red4ext_rs::prelude::NativeRepr for textLetterCase { + const NAME: &'static str = "textLetterCase"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Serialize, Clone, Deserialize)] +#[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] pub enum textHorizontalAlignment { + #[default] Left = 0, Center = 1, Right = 2, } +unsafe impl red4ext_rs::prelude::NativeRepr for textHorizontalAlignment { + const NAME: &'static str = "textHorizontalAlignment"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Serialize, Clone, Deserialize)] +#[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] pub enum textVerticalAlignment { + #[default] Top = 0, Center = 1, Bottom = 2, } +unsafe impl red4ext_rs::prelude::NativeRepr for textVerticalAlignment { + const NAME: &'static str = "textVerticalAlignment"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Serialize, Clone, Deserialize)] +#[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] pub enum textOverflowPolicy { + #[default] None = 0, DotsEnd = 1, DotsEndLastLine = 2, @@ -59,3 +75,7 @@ pub enum textOverflowPolicy { PingPongScroll = 4, AdjustToSize = 5, } + +unsafe impl red4ext_rs::prelude::NativeRepr for textOverflowPolicy { + const NAME: &'static str = "textOverflowPolicy"; +} diff --git a/src/ink/widget/image.rs b/src/ink/widget/image.rs index 82e9b23..b7015ce 100644 --- a/src/ink/widget/image.rs +++ b/src/ink/widget/image.rs @@ -6,7 +6,7 @@ use crate::Name; use super::Flags; #[allow(non_camel_case_types)] -#[derive(Debug, Serialize, Clone, Deserialize)] +#[derive(Debug, Serialize, Clone, Deserialize, Default, PartialEq, RedsValue)] #[serde(rename_all = "PascalCase")] pub struct inkTextureAtlas { depot_path: Name, diff --git a/src/ink/widget/layout.rs b/src/ink/widget/layout.rs index 51770ae..dc32d31 100644 --- a/src/ink/widget/layout.rs +++ b/src/ink/widget/layout.rs @@ -44,7 +44,7 @@ unsafe impl red4ext_rs::prelude::NativeRepr for inkEHorizontalAlign { } #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, RedsValue)] pub enum inkEVerticalAlign { #[default] Fill = 0, diff --git a/src/ink/widget/mod.rs b/src/ink/widget/mod.rs index e462d0f..53d927a 100644 --- a/src/ink/widget/mod.rs +++ b/src/ink/widget/mod.rs @@ -16,7 +16,7 @@ use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_bool_from_anything; -use crate::Name; +use crate::{Name, RedsWidget}; use self::{ font::{ @@ -51,7 +51,15 @@ macro_rules! native_compound_widget { ($ty:ident) => { #[doc=concat!("see [NativeDB](https://nativedb.red4ext.com/", stringify!($ty), ")")] #[allow(non_camel_case_types)] - #[derive(Debug, Clone, Serialize, Deserialize)] + #[derive( + Debug, + Clone, + Serialize, + Deserialize, + Default, + PartialEq, + inkanim_macros::RedsWidgetCompound, + )] #[serde(rename_all = "camelCase")] pub struct $ty { pub children: InkWrapper, @@ -59,6 +67,10 @@ macro_rules! native_compound_widget { pub child_order: self::layout::inkEChildOrder, pub child_margin: self::layout::inkMargin, } + unsafe impl red4ext_rs::prelude::NativeRepr for $ty { + const NAME: &'static str = ::const_str::replace!(::std::stringify!($ty), "Widget", ""); + const NATIVE_NAME: &'static str = ::std::stringify!($ty); + } }; } @@ -66,7 +78,7 @@ macro_rules! native_leaf_widget { ($ty:ident { $($tt:tt)* }) => { #[doc=concat!("🌿 see [NativeDB](https://nativedb.red4ext.com/", stringify!($ty), ")")] #[allow(non_camel_case_types)] - #[derive(Debug, Clone, Serialize, Deserialize)] + #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, inkanim_macros::RedsWidgetLeaf)] #[serde(rename_all = "camelCase")] pub struct $ty { pub name: $crate::Name, @@ -77,6 +89,10 @@ macro_rules! native_leaf_widget { pub size: crate::Vector2, $($tt)* } + unsafe impl red4ext_rs::prelude::NativeRepr for $ty { + const NAME: &'static str = ::const_str::replace!(::std::stringify!($ty), "Widget", ""); + const NATIVE_NAME: &'static str = ::std::stringify!($ty); + } }; ($ty:ident) => { native_leaf_widget!($ty {}); @@ -94,11 +110,27 @@ native_compound_widget!(inkCacheWidget); /// see [NativeDB](https://nativedb.red4ext.com/inkMultiChildren) #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] pub struct inkMultiChildren { pub children: Vec>, } +impl RedsWidget for inkMultiChildren { + fn reds_widget(&self, name: &str, parent: Option<&str>) -> String { + self.children + .iter() + .map(|x| x.reds_widget(name, parent)) + .collect::>() + .join("\n") + } +} + +impl inkMultiChildren { + pub fn iter(&self) -> std::slice::Iter<'_, InkWrapper> { + self.children.iter() + } +} + native_leaf_widget!(inkTextWidget { pub localization_string: LocalizationString, pub text: String, @@ -141,16 +173,46 @@ native_leaf_widget!(inkCircleWidget); native_leaf_widget!(inkRectangleWidget); native_leaf_widget!(inkVectorGraphicWidget); -unsafe impl red4ext_rs::prelude::NativeRepr for inkTextWidget { - const NAME: &'static str = "inkText"; - const NATIVE_NAME: &'static str = "inkTextWidget"; -} +// unsafe impl red4ext_rs::prelude::NativeRepr for inkTextWidget { +// const NAME: &'static str = "inkText"; +// const NATIVE_NAME: &'static str = "inkTextWidget"; +// } + +// unsafe impl red4ext_rs::prelude::NativeRepr for inkImageWidget { +// const NAME: &'static str = "inkImage"; +// const NATIVE_NAME: &'static str = "inkImageWidget"; +// } + +// unsafe impl red4ext_rs::prelude::NativeRepr for inkVideoWidget { +// const NAME: &'static str = "inkVideo"; +// const NATIVE_NAME: &'static str = "inkVideoWidget"; +// } + +// unsafe impl red4ext_rs::prelude::NativeRepr for inkMaskWidget { +// const NAME: &'static str = "inkMask"; +// const NATIVE_NAME: &'static str = "inkMaskWidget"; +// } + +// unsafe impl red4ext_rs::prelude::NativeRepr for inkBorderWidget { +// const NAME: &'static str = "inkBorder"; +// const NATIVE_NAME: &'static str = "inkBorderWidget"; +// } + +// unsafe impl red4ext_rs::prelude::NativeRepr for inkShapeWidget { +// const NAME: &'static str = "inkShape"; +// const NATIVE_NAME: &'static str = "inkShapeWidget"; +// } + +// unsafe impl red4ext_rs::prelude::NativeRepr for inkCircleWidget { +// const NAME: &'static str = "inkCircle"; +// const NATIVE_NAME: &'static str = "inkCircleWidget"; +// } /// any widget #[allow(clippy::enum_variant_names)] #[allow(non_camel_case_types)] #[non_exhaustive] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[enum_dispatch(Classname)] #[serde(tag = "$type")] pub enum Widget { diff --git a/src/ink/widget/properties.rs b/src/ink/widget/properties.rs index 1a0ddfe..8e13bfa 100644 --- a/src/ink/widget/properties.rs +++ b/src/ink/widget/properties.rs @@ -1,25 +1,38 @@ +use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use crate::{HandleId, Name}; #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, RedsValue)] #[serde(tag = "$type", rename_all = "camelCase")] pub struct inkPropertyBinding { pub property_name: Name, pub style_path: Name, } +unsafe impl red4ext_rs::prelude::NativeRepr for inkPropertyBinding { + const NAME: &'static str = "inkPropertyBinding"; +} + #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, RedsValue)] #[serde(tag = "$type")] pub struct inkPropertyManager { pub bindings: Vec, } -#[derive(Debug, Clone, Serialize, Deserialize)] +unsafe impl red4ext_rs::prelude::NativeRepr for inkPropertyManager { + const NAME: &'static str = "inkPropertyManager"; +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, RedsValue)] #[serde(rename_all = "PascalCase")] pub struct PropertyManager { pub handle_id: HandleId, pub data: inkPropertyManager, } + +unsafe impl red4ext_rs::prelude::NativeRepr for PropertyManager { + const NAME: &'static str = "PropertyManager"; +} diff --git a/src/lib.rs b/src/lib.rs index a200f65..0879ae7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,89 @@ mod ink; +use ink::widget::Widget; pub use ink::*; pub trait RedsValue { fn reds_value(&self) -> Option; } +pub trait RedsWidgetLeaf { + fn reds_widget_leaf(&self, name: &str, parent: Option<&str>) -> String; +} + +pub trait RedsWidgetCompound { + fn reds_widget_compound(&self, name: &str, parent: Option<&str>) -> String; +} + pub trait RedsWidget { fn reds_widget(&self, name: &str, parent: Option<&str>) -> String; } +impl RedsWidget for &dyn RedsWidgetLeaf { + fn reds_widget(&self, name: &str, parent: Option<&str>) -> String { + self.reds_widget_leaf(name, parent) + } +} + +impl RedsWidget for &dyn RedsWidgetCompound { + fn reds_widget(&self, name: &str, parent: Option<&str>) -> String { + self.reds_widget_compound(name, parent) + } +} + +impl InkWrapper { + pub fn name(&self) -> Option<&str> { + self.data.name() + } +} + +impl RedsWidget for &InkWrapper { + fn reds_widget(&self, name: &str, parent: Option<&str>) -> String { + match &self.data { + Widget::inkMultiChildren(x) => x.reds_widget(name, parent), + Widget::inkCanvasWidget(x) => x.reds_widget_compound(name, parent), + Widget::inkHorizontalPanelWidget(x) => x.reds_widget_compound(name, parent), + Widget::inkVerticalPanelWidget(x) => x.reds_widget_compound(name, parent), + Widget::inkScrollAreaWidget(x) => x.reds_widget_compound(name, parent), + Widget::inkUniformGridWidget(x) => x.reds_widget_compound(name, parent), + Widget::inkVirtualCompoundWidget(x) => x.reds_widget_compound(name, parent), + Widget::inkFlexWidget(x) => x.reds_widget_compound(name, parent), + Widget::inkCacheWidget(x) => x.reds_widget_compound(name, parent), + Widget::inkTextWidget(x) => x.reds_widget_leaf(name, parent), + Widget::inkImageWidget(x) => x.reds_widget_leaf(name, parent), + Widget::inkVideoWidget(x) => x.reds_widget_leaf(name, parent), + Widget::inkMaskWidget(x) => x.reds_widget_leaf(name, parent), + Widget::inkBorderWidget(x) => x.reds_widget_leaf(name, parent), + Widget::inkShapeWidget(x) => x.reds_widget_leaf(name, parent), + Widget::inkCircleWidget(x) => x.reds_widget_leaf(name, parent), + Widget::inkRectangleWidget(x) => x.reds_widget_leaf(name, parent), + Widget::inkVectorGraphicWidget(x) => x.reds_widget_leaf(name, parent), + } + } +} + +impl RedsValue for Vec +where + T: RedsValue, +{ + fn reds_value(&self) -> Option { + Some( + self.iter() + .map(|x| x.reds_value().unwrap_or_default()) + .collect::>() + .join(""), + ) + } +} + +impl RedsValue for Option +where + T: RedsValue, +{ + fn reds_value(&self) -> Option { + self.as_ref().and_then(|x| x.reds_value()) + } +} + impl RedsValue for f32 { fn reds_value(&self) -> Option { if self == &self.trunc() { @@ -31,6 +106,12 @@ impl RedsValue for u16 { } } +impl RedsValue for u32 { + fn reds_value(&self) -> Option { + Some(format!("{}", self.clone())) + } +} + impl RedsValue for bool { fn reds_value(&self) -> Option { if !self { diff --git a/src/show/mod.rs b/src/show/mod.rs index 0f45000..84c7dd9 100644 --- a/src/show/mod.rs +++ b/src/show/mod.rs @@ -30,7 +30,8 @@ fn reds(widget: &inkWidgetLibraryResource, names: &[&str]) { panic!("unable to find widget in tree: {names:#?}"); }); } - println!("{:#?}", parent); + // println!("{:#?}", parent.reds_widget_compound()); + todo!() } pub(crate) fn show( From 59dfc470b059d2fb7a52871188d97409f9a95dc9 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Wed, 7 Feb 2024 16:44:15 +0700 Subject: [PATCH 09/17] :construction: work in progress : add children --- macros/src/lib.rs | 23 ++++++++++++++++++----- src/ink/mod.rs | 3 ++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 214a740..aedbd8a 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -145,16 +145,29 @@ fn derive_reds_widget_compound_for_struct(name: &syn::Ident, r#struct: &syn::Dat steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), v)); } )* - let mut name; + let mut child_name; + let parent_name = self.name.reds_value(); if self.child_order == inkEChildOrder::Forward { for child in self.children.iter() { - name = child.name().expect("no child to be a inkMultiChildren"); - steps.push(child.reds_widget(name, self.name.reds_value().as_deref())); + child_name = child.name().expect("no child should be a inkMultiChildren"); + steps.push(child.reds_widget(child_name, parent_name.as_deref())); + } + if let Some(v) = parent_name { + for child in self.children.iter() { + child_name = child.name().expect("no child should be a inkMultiChildren"); + steps.push(format!("{}.AddChild({});", instance, child_name)); + } } } else { for child in self.children.iter().rev() { - name = child.name().expect("no child to be a inkMultiChildren"); - steps.push(child.reds_widget(name, self.name.reds_value().as_deref())); + child_name = child.name().expect("no child to be a inkMultiChildren"); + steps.push(child.reds_widget(child_name, parent_name.as_deref())); + } + if let Some(v) = parent_name { + for child in self.children.iter() { + child_name = child.name().expect("no child should be a inkMultiChildren"); + steps.push(format!("{}.AddChild({});", instance, child_name)); + } } } steps.join("\n") diff --git a/src/ink/mod.rs b/src/ink/mod.rs index a76fb18..57bbd0c 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -334,7 +334,8 @@ shape.render_transform_pivot = new Vector2(1., 3.); shape.size = new Vector2(360., 100.); shape.line_height_percentage = 0.; shape.scroll_delay = 0; -shape.scroll_text_speed = 0.;"# +shape.scroll_text_speed = 0.; +parent.AddChild(shape);"# ); } } From cf1ccc3abf3a4bf4eeaf665994c21b3ef512a952 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Wed, 7 Feb 2024 22:41:29 +0700 Subject: [PATCH 10/17] :construction: work in progress : fix definition --- src/ink/widget/layout.rs | 20 ++++++++++++++++++-- src/show/mod.rs | 4 ++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/ink/widget/layout.rs b/src/ink/widget/layout.rs index dc32d31..a74c3ab 100644 --- a/src/ink/widget/layout.rs +++ b/src/ink/widget/layout.rs @@ -101,12 +101,16 @@ unsafe impl red4ext_rs::prelude::NativeRepr for inkMargin { #[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] #[serde(tag = "$type", rename_all = "camelCase")] pub struct inkWidgetLayout { - pub anchor: inkEAnchor, - pub anchor_point: Vector2, pub padding: inkMargin, pub margin: inkMargin, + pub anchor_point: Vector2, + pub size_coefficient: f32, #[serde(rename = "HAlign")] pub h_align: inkEHorizontalAlign, + #[serde(rename = "VAlign")] + pub v_align: inkEVerticalAlign, + pub anchor: inkEAnchor, + pub size_rule: inkESizeRule, } unsafe impl red4ext_rs::prelude::NativeRepr for inkWidgetLayout { @@ -124,3 +128,15 @@ pub enum inkEChildOrder { unsafe impl red4ext_rs::prelude::NativeRepr for inkEChildOrder { const NAME: &'static str = "inkEChildOrder"; } + +#[allow(non_camel_case_types)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, RedsValue, PartialEq)] +pub enum inkESizeRule { + #[default] + Fixed = 0, + Stretch = 1, +} + +unsafe impl red4ext_rs::prelude::NativeRepr for inkESizeRule { + const NAME: &'static str = "inkESizeRule"; +} diff --git a/src/show/mod.rs b/src/show/mod.rs index 84c7dd9..7435e60 100644 --- a/src/show/mod.rs +++ b/src/show/mod.rs @@ -3,6 +3,7 @@ pub(crate) use args::Args; use inkanim::{ anim::InkAnimAnimationLibraryResource, widget::{inkWidgetLibraryResource, ByName}, + RedsWidget, }; fn reds(widget: &inkWidgetLibraryResource, names: &[&str]) { @@ -30,8 +31,7 @@ fn reds(widget: &inkWidgetLibraryResource, names: &[&str]) { panic!("unable to find widget in tree: {names:#?}"); }); } - // println!("{:#?}", parent.reds_widget_compound()); - todo!() + println!("{}", parent.reds_widget("root", None)); } pub(crate) fn show( From 17afad2838e9284ceb0eca86c6fd18c53138afc1 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Wed, 7 Feb 2024 23:00:44 +0700 Subject: [PATCH 11/17] :construction: work in progress : fixes --- src/ink/widget/mod.rs | 35 ----------------------------------- src/lib.rs | 8 +++++++- 2 files changed, 7 insertions(+), 36 deletions(-) diff --git a/src/ink/widget/mod.rs b/src/ink/widget/mod.rs index 53d927a..3e6ae8b 100644 --- a/src/ink/widget/mod.rs +++ b/src/ink/widget/mod.rs @@ -173,41 +173,6 @@ native_leaf_widget!(inkCircleWidget); native_leaf_widget!(inkRectangleWidget); native_leaf_widget!(inkVectorGraphicWidget); -// unsafe impl red4ext_rs::prelude::NativeRepr for inkTextWidget { -// const NAME: &'static str = "inkText"; -// const NATIVE_NAME: &'static str = "inkTextWidget"; -// } - -// unsafe impl red4ext_rs::prelude::NativeRepr for inkImageWidget { -// const NAME: &'static str = "inkImage"; -// const NATIVE_NAME: &'static str = "inkImageWidget"; -// } - -// unsafe impl red4ext_rs::prelude::NativeRepr for inkVideoWidget { -// const NAME: &'static str = "inkVideo"; -// const NATIVE_NAME: &'static str = "inkVideoWidget"; -// } - -// unsafe impl red4ext_rs::prelude::NativeRepr for inkMaskWidget { -// const NAME: &'static str = "inkMask"; -// const NATIVE_NAME: &'static str = "inkMaskWidget"; -// } - -// unsafe impl red4ext_rs::prelude::NativeRepr for inkBorderWidget { -// const NAME: &'static str = "inkBorder"; -// const NATIVE_NAME: &'static str = "inkBorderWidget"; -// } - -// unsafe impl red4ext_rs::prelude::NativeRepr for inkShapeWidget { -// const NAME: &'static str = "inkShape"; -// const NATIVE_NAME: &'static str = "inkShapeWidget"; -// } - -// unsafe impl red4ext_rs::prelude::NativeRepr for inkCircleWidget { -// const NAME: &'static str = "inkCircle"; -// const NATIVE_NAME: &'static str = "inkCircleWidget"; -// } - /// any widget #[allow(clippy::enum_variant_names)] #[allow(non_camel_case_types)] diff --git a/src/lib.rs b/src/lib.rs index 0879ae7..2354fbe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,7 +38,13 @@ impl InkWrapper { impl RedsWidget for &InkWrapper { fn reds_widget(&self, name: &str, parent: Option<&str>) -> String { - match &self.data { + self.data.reds_widget(name, parent) + } +} + +impl RedsWidget for Widget { + fn reds_widget(&self, name: &str, parent: Option<&str>) -> String { + match self { Widget::inkMultiChildren(x) => x.reds_widget(name, parent), Widget::inkCanvasWidget(x) => x.reds_widget_compound(name, parent), Widget::inkHorizontalPanelWidget(x) => x.reds_widget_compound(name, parent), From 68d9f673ab798802cf87d3d6c2bce5f2c00426f0 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Thu, 8 Feb 2024 00:11:59 +0700 Subject: [PATCH 12/17] :construction: work in progress : refactor cname and resourcepath --- src/ink/anim/mod.rs | 8 +-- src/ink/conversion.rs | 104 +++++++++++++++++++++++++++++++ src/ink/mod.rs | 95 +++++++++++++++------------- src/ink/widget/font.rs | 6 +- src/ink/widget/image.rs | 4 +- src/ink/widget/implementation.rs | 8 +-- src/ink/widget/mod.rs | 16 ++--- src/ink/widget/properties.rs | 6 +- src/lib.rs | 30 ++++----- 9 files changed, 191 insertions(+), 86 deletions(-) diff --git a/src/ink/anim/mod.rs b/src/ink/anim/mod.rs index 6a924d2..e7ae078 100644 --- a/src/ink/anim/mod.rs +++ b/src/ink/anim/mod.rs @@ -3,7 +3,7 @@ mod display; use serde::{Deserialize, Serialize}; use serde_aux::prelude::*; -use crate::{HDRColor, Name, Vector2}; +use crate::{CName, HDRColor, Vector2}; use super::InkWrapper; @@ -124,8 +124,8 @@ pub struct Interpolator { #[serde(rename_all = "camelCase")] pub struct EffectInterpolator { pub effect_type: inkEffectType, - pub effect_name: Name, - pub param_name: Name, + pub effect_name: CName, + pub param_name: CName, #[serde(flatten)] pub base: Interpolator, } @@ -307,7 +307,7 @@ pub struct InkAnimSequence { /// /// ⚠️ `definitions` size must always match `targets` size pub definitions: Vec>, - pub name: Name, + pub name: CName, /// describe the targets onto which the interpolations are played /// /// ⚠️ `targets` size must always match `definitions` size diff --git a/src/ink/conversion.rs b/src/ink/conversion.rs index eee5c75..3bd80cf 100644 --- a/src/ink/conversion.rs +++ b/src/ink/conversion.rs @@ -6,6 +6,110 @@ use serde::Deserialize; use crate::anim::Range; use crate::LocKey; +pub fn deserialize_cname_from_format<'de, D>(deserializer: D) -> Result +where + D: de::Deserializer<'de>, +{ + struct CNameVisitor; + impl<'de> de::Visitor<'de> for CNameVisitor { + type Value = String; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("$type CName, with valid $storage and $value") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut type_ok = false; + let mut storage_ok = false; + let mut value_ok = false; + let mut value: String = String::new(); + while let Some(key) = map.next_key::<&str>()? { + if key == "$type" { + let value: &str = map.next_value()?; + if value != "CName" { + return Err(de::Error::custom("invalid map type")); + } else { + type_ok = true; + } + } + if key == "$storage" { + let value: &str = map.next_value()?; + if value != "string" { + return Err(de::Error::custom("invalid map storage")); + } else { + storage_ok = true; + } + } + if key == "$value" { + value = map.next_value::()?; + value_ok = true; + } + } + if type_ok && storage_ok && value_ok { + return Ok(value); + } + Err(de::Error::custom("invalid map sequence")) + } + } + deserializer.deserialize_any(CNameVisitor) +} + +pub fn deserialize_resourcepath_from_format<'de, D>( + deserializer: D, +) -> Result +where + D: de::Deserializer<'de>, +{ + struct ResourcePathVisitor; + impl<'de> de::Visitor<'de> for ResourcePathVisitor { + type Value = std::path::PathBuf; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("$type ResourcePath, with valid $storage and $value") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut type_ok = false; + let mut storage_ok = false; + let mut value_ok = false; + let mut value: String = String::new(); + while let Some(key) = map.next_key::<&str>()? { + if key == "$type" { + let value: &str = map.next_value()?; + if value != "ResourcePath" { + return Err(de::Error::custom("invalid map type")); + } else { + type_ok = true; + } + } + if key == "$storage" { + let value: &str = map.next_value()?; + if value != "string" { + return Err(de::Error::custom("invalid map storage")); + } else { + storage_ok = true; + } + } + if key == "$value" { + value = map.next_value::()?; + value_ok = true; + } + } + if type_ok && storage_ok && value_ok { + return Ok(std::path::PathBuf::from(value)); + } + Err(de::Error::custom("invalid map sequence")) + } + } + deserializer.deserialize_any(ResourcePathVisitor) +} + pub fn deserialize_lockey_from_anything<'de, D>(deserializer: D) -> Result, D::Error> where D: de::Deserializer<'de>, diff --git a/src/ink/mod.rs b/src/ink/mod.rs index 57bbd0c..7398a7d 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -4,7 +4,10 @@ use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use serde_aux::prelude::*; -use crate::RedsWidget; +use crate::{ + ink::conversion::{deserialize_cname_from_format, deserialize_resourcepath_from_format}, + RedsValue, RedsWidget, +}; use self::{ anim::{InkAnimSequence, Target}, @@ -18,46 +21,35 @@ pub mod anim; /// everything related to *.inkwidget* pub mod widget; -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Name { - #[serde(rename = "$type")] - pub r#type: String, - #[serde(rename = "$storage")] - pub storage: String, - #[serde(rename = "$value")] - pub value: String, +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum Storage { + #[default] + String, } -impl Default for Name { +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct ResourcePath( + #[serde(deserialize_with = "deserialize_resourcepath_from_format")] pub std::path::PathBuf, +); + +impl Default for ResourcePath { fn default() -> Self { - Self { - r#type: "CName".to_string(), - storage: "string".to_string(), - value: "None".to_string(), - } + Self(PathBuf::new()) } } -impl Name { - pub fn as_str(&self) -> &str { - self.value.as_str() +impl RedsValue for ResourcePath { + fn reds_value(&self) -> Option { + if self.0.as_os_str().to_str().is_none() + || self.0.as_os_str().to_str().unwrap().to_string().is_empty() + { + return None; + } + Some(format!("r\"{}\"", self.0.as_os_str().to_str().unwrap())) } } -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -pub enum Storage { - String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ResourcePath { - #[serde(rename = "$storage")] - storage: Storage, - #[serde(rename = "$value")] - value: PathBuf, -} - #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct Data { @@ -151,8 +143,29 @@ where } /// specific resource ID -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CName(String); +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct CName(#[serde(deserialize_with = "deserialize_cname_from_format")] pub String); + +impl Default for CName { + fn default() -> Self { + Self("None".to_string()) + } +} + +impl CName { + pub fn as_str(&self) -> &str { + &self.0 + } +} + +impl RedsValue for CName { + fn reds_value(&self) -> Option { + if self.0 == "None" { + return None; + } + Some(self.0.clone()) + } +} unsafe impl red4ext_rs::prelude::NativeRepr for CName { const NAME: &'static str = "CName"; @@ -195,7 +208,7 @@ impl std::fmt::Display for HandleId { #[derive(Debug)] pub struct PathSummary { /// animation name - Name: Name, + Name: CName, /// unique handle ID HandleId: HandleId, /// index in sequence @@ -273,11 +286,7 @@ element.size = new Vector2(1., 0.6);"# #[test] fn reds_tree() { let inner = inkTextWidget { - name: crate::Name { - r#type: "CName".to_string(), - storage: "string".to_string(), - value: "shape".to_string(), - }, + name: crate::CName("shape".to_string()), layout: crate::widget::layout::inkWidgetLayout { ..Default::default() }, @@ -300,11 +309,7 @@ element.size = new Vector2(1., 0.6);"# }], }, }, - name: crate::Name { - r#type: "CName".to_string(), - storage: "string".to_string(), - value: "main_canvas".to_string(), - }, + name: crate::CName("main_canvas".to_string()), child_order: crate::widget::layout::inkEChildOrder::Backward, child_margin: crate::widget::layout::inkMargin { left: 0., diff --git a/src/ink/widget/font.rs b/src/ink/widget/font.rs index 71a9480..2fd7674 100644 --- a/src/ink/widget/font.rs +++ b/src/ink/widget/font.rs @@ -1,7 +1,7 @@ use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; -use crate::Name; +use crate::{CName, ResourcePath}; use super::Flags; @@ -9,7 +9,7 @@ use super::Flags; #[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] #[serde(rename_all = "PascalCase")] pub struct inkFontFamilyResource { - depot_path: Name, + depot_path: ResourcePath, flags: Flags, } @@ -19,7 +19,7 @@ unsafe impl red4ext_rs::prelude::NativeRepr for inkFontFamilyResource { #[allow(non_camel_case_types)] #[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] -pub struct fontStyle(Name); +pub struct fontStyle(pub CName); unsafe impl red4ext_rs::prelude::NativeRepr for fontStyle { const NAME: &'static str = "fontStyle"; diff --git a/src/ink/widget/image.rs b/src/ink/widget/image.rs index b7015ce..bd0595f 100644 --- a/src/ink/widget/image.rs +++ b/src/ink/widget/image.rs @@ -1,7 +1,7 @@ use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; -use crate::Name; +use crate::ResourcePath; use super::Flags; @@ -9,7 +9,7 @@ use super::Flags; #[derive(Debug, Serialize, Clone, Deserialize, Default, PartialEq, RedsValue)] #[serde(rename_all = "PascalCase")] pub struct inkTextureAtlas { - depot_path: Name, + depot_path: ResourcePath, flags: Flags, } diff --git a/src/ink/widget/implementation.rs b/src/ink/widget/implementation.rs index 961e235..df5021d 100644 --- a/src/ink/widget/implementation.rs +++ b/src/ink/widget/implementation.rs @@ -2,7 +2,7 @@ use std::fmt::Debug; use enum_dispatch::enum_dispatch; -use crate::{ink::InkWrapper, Name}; +use crate::{ink::InkWrapper, CName}; use super::{ inkBorderWidget, inkCacheWidget, inkCanvasWidget, inkCircleWidget, inkFlexWidget, @@ -317,11 +317,7 @@ where if let Some(name) = child.data.name() { out.push(WidgetSummary { HandleId: child.handle_id, - Name: Name { - r#type: String::from("CName"), - storage: String::from("string"), - value: name.to_string(), - }, + Name: CName(name.to_string()), }); } } diff --git a/src/ink/widget/mod.rs b/src/ink/widget/mod.rs index 3e6ae8b..31f779c 100644 --- a/src/ink/widget/mod.rs +++ b/src/ink/widget/mod.rs @@ -16,7 +16,7 @@ use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_bool_from_anything; -use crate::{Name, RedsWidget}; +use crate::{CName, RedsWidget, ResourcePath}; use self::{ font::{ @@ -63,7 +63,7 @@ macro_rules! native_compound_widget { #[serde(rename_all = "camelCase")] pub struct $ty { pub children: InkWrapper, - pub name: $crate::Name, + pub name: $crate::CName, pub child_order: self::layout::inkEChildOrder, pub child_margin: self::layout::inkMargin, } @@ -81,7 +81,7 @@ macro_rules! native_leaf_widget { #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, inkanim_macros::RedsWidgetLeaf)] #[serde(rename_all = "camelCase")] pub struct $ty { - pub name: $crate::Name, + pub name: $crate::CName, pub layout: self::layout::inkWidgetLayout, pub property_manager: Option, pub render_transform_pivot: crate::Vector2, @@ -150,7 +150,7 @@ native_leaf_widget!(inkTextWidget { native_leaf_widget!(inkImageWidget { #[serde(deserialize_with = "deserialize_bool_from_anything")] pub use_external_dynamic_texture: bool, - pub external_dynamic_texture: Name, + pub external_dynamic_texture: CName, #[serde(deserialize_with = "deserialize_bool_from_anything")] pub use_nine_slice_scale: bool, pub nine_slice_scale: inkMargin, @@ -159,7 +159,7 @@ native_leaf_widget!(inkImageWidget { pub horizontal_tile_crop: f32, pub vertical_tile_crop: f32, pub texture_atlas: inkTextureAtlas, - pub texture_part: Name, + pub texture_part: CName, pub content_h_align: inkEHorizontalAlign, pub content_v_align: inkEVerticalAlign, pub tile_h_align: inkEHorizontalAlign, @@ -227,7 +227,7 @@ pub struct Package { #[allow(non_camel_case_types)] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct inkWidgetLibraryItem { - pub name: Name, + pub name: CName, pub package: Package, } @@ -236,7 +236,7 @@ pub struct inkWidgetLibraryItem { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct inkanimAnimationLibraryResource { - depot_path: Name, + depot_path: ResourcePath, flags: Flags, } @@ -256,5 +256,5 @@ pub struct WidgetSummary { /// unique handle ID pub HandleId: HandleId, /// widget name - pub Name: Name, + pub Name: CName, } diff --git a/src/ink/widget/properties.rs b/src/ink/widget/properties.rs index 8e13bfa..7a9baad 100644 --- a/src/ink/widget/properties.rs +++ b/src/ink/widget/properties.rs @@ -1,14 +1,14 @@ use inkanim_macros::RedsValue; use serde::{Deserialize, Serialize}; -use crate::{HandleId, Name}; +use crate::{CName, HandleId}; #[allow(non_camel_case_types)] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, RedsValue)] #[serde(tag = "$type", rename_all = "camelCase")] pub struct inkPropertyBinding { - pub property_name: Name, - pub style_path: Name, + pub property_name: CName, + pub style_path: CName, } unsafe impl red4ext_rs::prelude::NativeRepr for inkPropertyBinding { diff --git a/src/lib.rs b/src/lib.rs index 2354fbe..ad6fc16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -138,21 +138,21 @@ impl RedsValue for String { } } -impl RedsValue for Name { - fn reds_value(&self) -> Option { - match ( - self.r#type.as_str(), - self.storage.as_str(), - self.value.as_str(), - ) { - ("ResourcePath", "string", "") => None, - ("ResourcePath", "string", v) => Some(format!("r\"{v}\"")), - ("CName", "string", "None") => None, - ("CName", "string", v) => Some(format!("n\"{v}\"")), - _ => unreachable!(), - } - } -} +// impl RedsValue for Name { +// fn reds_value(&self) -> Option { +// match ( +// self.r#type.as_str(), +// self.storage.as_str(), +// self.value.as_str(), +// ) { +// ("ResourcePath", "string", "") => None, +// ("ResourcePath", "string", v) => Some(format!("r\"{v}\"")), +// ("CName", "string", "None") => None, +// ("CName", "string", v) => Some(format!("n\"{v}\"")), +// _ => unreachable!(), +// } +// } +// } impl RedsValue for LocalizationString { fn reds_value(&self) -> Option { From 5c745a1c5c2a8fd1972ddbcf26a0224936cf1fa9 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Thu, 8 Feb 2024 10:05:38 +0700 Subject: [PATCH 13/17] :construction: work in progress : fixes --- macros/src/lib.rs | 65 ++++++++++------------ src/ink/mod.rs | 16 ++---- src/ink/widget/implementation.rs | 1 + src/lib.rs | 94 ++++++++++++++++---------------- 4 files changed, 80 insertions(+), 96 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index aedbd8a..4bf78eb 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -44,11 +44,12 @@ fn derive_reds_widget_leaf_for_struct(name: &syn::Ident, r#struct: &syn::DataStr fn reds_widget_leaf(&self, instance: &str, parent: Option<&str>) -> String { use ::red4ext_rs::conv::NativeRepr; use crate::RedsValue; + use crate::IsDefault; let mut steps = vec![]; steps.push(format!("let {} = new {}();", instance, Self::NAME)); #( - if let Some(v) = self.#oneliners.reds_value() { - steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), v)); + if !self.#oneliners.is_default() { + steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), self.#oneliners.reds_value())); } )* steps.join("\n") @@ -67,16 +68,13 @@ fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) - let indexes = r#struct.fields.iter().enumerate().map(|(index, _)| syn::Index::from(index)); return quote! { impl crate::RedsValue for #name { - fn reds_value(&self) -> Option { + fn reds_value(&self) -> String { use ::red4ext_rs::conv::NativeRepr; - if self == &Self::default() { - return None; - } let mut args = Vec::::new(); #( - args.push(self.#indexes.reds_value().unwrap_or(Default::default())); + args.push(self.#indexes.reds_value()); )* - Some(format!("new {}({})", Self::NAME, args.join(", "))) + format!("new {}({})", Self::NAME, args.join(", ")) } } }.into() @@ -84,16 +82,13 @@ fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) - let fields = r#struct.fields.iter().map(|x| x.ident.clone()); quote! { impl crate::RedsValue for #name { - fn reds_value(&self) -> Option { + fn reds_value(&self) -> String { use ::red4ext_rs::conv::NativeRepr; - if self == &Self::default() { - return None; - } let mut args = Vec::::new(); #( - args.push(self.#fields.reds_value().unwrap_or(Default::default())); + args.push(self.#fields.reds_value()); )* - Some(format!("new {}({})", Self::NAME, args.join(", "))) + format!("new {}({})", Self::NAME, args.join(", ")) } } }.into() @@ -109,16 +104,13 @@ fn derive_reds_value_for_enum(name: &syn::Ident, r#enum: &syn::DataEnum) -> Toke .into() } quote!{ - #name::#variant => Some(::std::format!("{}.{}", Self::NAME, ::std::stringify!(#variant))) + #name::#variant => ::std::format!("{}.{}", Self::NAME, ::std::stringify!(#variant)) } }); quote! { impl crate::RedsValue for #name { - fn reds_value(&self) -> Option { + fn reds_value(&self) -> String { use ::red4ext_rs::conv::NativeRepr; - if self == &Self::default() { - return None; - } match self { #(#matches),* } @@ -138,36 +130,37 @@ fn derive_reds_widget_compound_for_struct(name: &syn::Ident, r#struct: &syn::Dat use ::red4ext_rs::conv::NativeRepr; use crate::widget::layout::inkEChildOrder; use crate::RedsValue; + use crate::IsDefault; let mut steps = vec![]; - steps.push(format!("let {} = new {}();", instance, Self::NAME)); + steps.push(::std::format!("let {} = new {}();", instance, Self::NAME)); #( - if let Some(v) = self.#oneliners.reds_value() { - steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), v)); + if !self.#oneliners.is_default() { + steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), self.#oneliners.reds_value())); } )* let mut child_name; - let parent_name = self.name.reds_value(); + let mut result: String; + let parent_name = if self.name.is_default() { None } else { Some(self.name.reds_value()) }; + let borrow_parent_name = parent_name.as_ref().map(|x| x.as_str()); if self.child_order == inkEChildOrder::Forward { for child in self.children.iter() { child_name = child.name().expect("no child should be a inkMultiChildren"); - steps.push(child.reds_widget(child_name, parent_name.as_deref())); + result = child.reds_widget(child_name, borrow_parent_name); + steps.push(result.to_owned()); } - if let Some(v) = parent_name { - for child in self.children.iter() { - child_name = child.name().expect("no child should be a inkMultiChildren"); - steps.push(format!("{}.AddChild({});", instance, child_name)); - } + for child in self.children.iter() { + child_name = child.name().expect("no child should be a inkMultiChildren"); + steps.push(format!("{}.AddChild({});", instance, child_name)); } } else { for child in self.children.iter().rev() { - child_name = child.name().expect("no child to be a inkMultiChildren"); - steps.push(child.reds_widget(child_name, parent_name.as_deref())); + child_name = child.name().expect("no child should be a inkMultiChildren"); + result = child.reds_widget(child_name, borrow_parent_name); + steps.push(result.to_owned()); } - if let Some(v) = parent_name { - for child in self.children.iter() { - child_name = child.name().expect("no child should be a inkMultiChildren"); - steps.push(format!("{}.AddChild({});", instance, child_name)); - } + for child in self.children.iter().rev() { + child_name = child.name().expect("no child should be a inkMultiChildren"); + steps.push(format!("{}.AddChild({});", instance, child_name)); } } steps.join("\n") diff --git a/src/ink/mod.rs b/src/ink/mod.rs index 7398a7d..e6a53d8 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -40,13 +40,8 @@ impl Default for ResourcePath { } impl RedsValue for ResourcePath { - fn reds_value(&self) -> Option { - if self.0.as_os_str().to_str().is_none() - || self.0.as_os_str().to_str().unwrap().to_string().is_empty() - { - return None; - } - Some(format!("r\"{}\"", self.0.as_os_str().to_str().unwrap())) + fn reds_value(&self) -> String { + format!("r\"{}\"", self.0.as_os_str().to_str().unwrap_or_default()) } } @@ -159,11 +154,8 @@ impl CName { } impl RedsValue for CName { - fn reds_value(&self) -> Option { - if self.0 == "None" { - return None; - } - Some(self.0.clone()) + fn reds_value(&self) -> String { + format!("n\"{}\"", self.0.clone()) } } diff --git a/src/ink/widget/implementation.rs b/src/ink/widget/implementation.rs index df5021d..c00c45b 100644 --- a/src/ink/widget/implementation.rs +++ b/src/ink/widget/implementation.rs @@ -161,6 +161,7 @@ impl_classname!(inkShapeWidget); impl_classname!(inkCircleWidget); impl_classname!(inkRectangleWidget); impl_classname!(inkVectorGraphicWidget); + impl Widget { pub fn name(&self) -> Option<&str> { match self { diff --git a/src/lib.rs b/src/lib.rs index ad6fc16..ea28d83 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,8 +2,21 @@ mod ink; use ink::widget::Widget; pub use ink::*; +pub trait IsDefault { + fn is_default(&self) -> bool; +} + +impl IsDefault for T +where + T: Default + PartialEq, +{ + fn is_default(&self) -> bool { + self == &T::default() + } +} + pub trait RedsValue { - fn reds_value(&self) -> Option; + fn reds_value(&self) -> String; } pub trait RedsWidgetLeaf { @@ -71,12 +84,13 @@ impl RedsValue for Vec where T: RedsValue, { - fn reds_value(&self) -> Option { - Some( + fn reds_value(&self) -> String { + format!( + "[{}]", self.iter() - .map(|x| x.reds_value().unwrap_or_default()) + .map(|x| x.reds_value()) .collect::>() - .join(""), + .join(", "), ) } } @@ -85,86 +99,70 @@ impl RedsValue for Option where T: RedsValue, { - fn reds_value(&self) -> Option { - self.as_ref().and_then(|x| x.reds_value()) + fn reds_value(&self) -> String { + if self.is_some() { + self.as_ref().unwrap().reds_value() + } else { + "".to_string() + } } } impl RedsValue for f32 { - fn reds_value(&self) -> Option { + fn reds_value(&self) -> String { if self == &self.trunc() { - Some(format!("{}.", self)) + format!("{}.", self) } else { - Some(format!("{}", self)) + format!("{}", self) } } } impl RedsValue for i32 { - fn reds_value(&self) -> Option { - Some(format!("{}", self.clone())) + fn reds_value(&self) -> String { + format!("{}", self.clone()) } } impl RedsValue for u16 { - fn reds_value(&self) -> Option { - Some(format!("{}", self.clone())) + fn reds_value(&self) -> String { + format!("{}", self.clone()) } } impl RedsValue for u32 { - fn reds_value(&self) -> Option { - Some(format!("{}", self.clone())) + fn reds_value(&self) -> String { + format!("{}", self.clone()) } } impl RedsValue for bool { - fn reds_value(&self) -> Option { + fn reds_value(&self) -> String { if !self { - None + "false".to_string() } else { - Some("true".to_string()) + "true".to_string() } } } impl RedsValue for String { - fn reds_value(&self) -> Option { - if self.is_empty() { - None - } else { - Some(self.clone()) - } + fn reds_value(&self) -> String { + self.clone() } } -// impl RedsValue for Name { -// fn reds_value(&self) -> Option { -// match ( -// self.r#type.as_str(), -// self.storage.as_str(), -// self.value.as_str(), -// ) { -// ("ResourcePath", "string", "") => None, -// ("ResourcePath", "string", v) => Some(format!("r\"{v}\"")), -// ("CName", "string", "None") => None, -// ("CName", "string", v) => Some(format!("n\"{v}\"")), -// _ => unreachable!(), -// } -// } -// } - impl RedsValue for LocalizationString { - fn reds_value(&self) -> Option { + fn reds_value(&self) -> String { if let Some(ref v) = self.value { return match v { - LocKey::ID(v) if v == &0 => None, - LocKey::ID(v) => Some(format!("LocKey#{}", v)), - LocKey::Value(v) if v.as_str() == "null" => None, - LocKey::Value(v) if v.as_str() == "None" => None, - LocKey::Value(v) => Some(format!("l\"{}\"", v)), + LocKey::ID(v) if v == &0 => "null".to_string(), + LocKey::ID(v) => format!("LocKey#{}", v), + LocKey::Value(v) if v.as_str() == "null" => "null".to_string(), + LocKey::Value(v) if v.as_str() == "None" => "null".to_string(), + LocKey::Value(v) => format!("l\"{}\"", v), }; } - None + "null".to_string() } } From daee3285d427bd4268eeabd343fe034a97431d4b Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Thu, 8 Feb 2024 10:45:29 +0700 Subject: [PATCH 14/17] :construction: work in progress : cleanup --- macros/src/lib.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 4bf78eb..39bcb64 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -139,28 +139,24 @@ fn derive_reds_widget_compound_for_struct(name: &syn::Ident, r#struct: &syn::Dat } )* let mut child_name; - let mut result: String; let parent_name = if self.name.is_default() { None } else { Some(self.name.reds_value()) }; - let borrow_parent_name = parent_name.as_ref().map(|x| x.as_str()); if self.child_order == inkEChildOrder::Forward { for child in self.children.iter() { child_name = child.name().expect("no child should be a inkMultiChildren"); - result = child.reds_widget(child_name, borrow_parent_name); - steps.push(result.to_owned()); + steps.push(child.reds_widget(child_name, parent_name.as_ref().map(|x| x.as_str()))); } for child in self.children.iter() { child_name = child.name().expect("no child should be a inkMultiChildren"); - steps.push(format!("{}.AddChild({});", instance, child_name)); + steps.push(format!("{}.AddChildWidget({});", instance, child_name)); } } else { for child in self.children.iter().rev() { child_name = child.name().expect("no child should be a inkMultiChildren"); - result = child.reds_widget(child_name, borrow_parent_name); - steps.push(result.to_owned()); + steps.push(child.reds_widget(child_name, parent_name.as_ref().map(|x| x.as_str()))); } for child in self.children.iter().rev() { child_name = child.name().expect("no child should be a inkMultiChildren"); - steps.push(format!("{}.AddChild({});", instance, child_name)); + steps.push(format!("{}.AddChildWidget({});", instance, child_name)); } } steps.join("\n") From 3806db30d185d194d5310d1292fe935bd0e43f22 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Fri, 9 Feb 2024 15:38:21 +0700 Subject: [PATCH 15/17] :construction: work in progress: ongoing setters --- Cargo.lock | 16 ++++++++++++++++ Cargo.toml | 1 + macros/src/lib.rs | 6 ++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97fc9d0..a3eb0e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -184,6 +184,15 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6" +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation-sys" version = "0.8.3" @@ -283,6 +292,7 @@ dependencies = [ "chrono", "clap", "const-str", + "convert_case", "enum_dispatch", "inkanim-macros", "red4ext-rs", @@ -573,6 +583,12 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "unicode-width" version = "0.1.10" diff --git a/Cargo.toml b/Cargo.toml index d8017b6..f052826 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ chrono = { version = "0.4.33", default-features = false, features = [ "serde", ] } const-str = "0.5.6" +convert_case = "0.6.0" clap = { version = "4.4.18", features = ["derive"] } red4ext-rs = { git = "https://github.com/jac3km4/red4ext-rs.git", rev = "2646318" } term-table = "1.3.2" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 39bcb64..76bedba 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -45,11 +45,12 @@ fn derive_reds_widget_leaf_for_struct(name: &syn::Ident, r#struct: &syn::DataStr use ::red4ext_rs::conv::NativeRepr; use crate::RedsValue; use crate::IsDefault; + use convert_case::{Case, Casing}; let mut steps = vec![]; steps.push(format!("let {} = new {}();", instance, Self::NAME)); #( if !self.#oneliners.is_default() { - steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), self.#oneliners.reds_value())); + steps.push(::std::format!("{}.Set{}({});", instance, ::std::stringify!(#oneliners).to_case(Case::Pascal), self.#oneliners.reds_value())); } )* steps.join("\n") @@ -131,11 +132,12 @@ fn derive_reds_widget_compound_for_struct(name: &syn::Ident, r#struct: &syn::Dat use crate::widget::layout::inkEChildOrder; use crate::RedsValue; use crate::IsDefault; + use convert_case::{Case, Casing}; let mut steps = vec![]; steps.push(::std::format!("let {} = new {}();", instance, Self::NAME)); #( if !self.#oneliners.is_default() { - steps.push(::std::format!("{}.{} = {};", instance, ::std::stringify!(#oneliners), self.#oneliners.reds_value())); + steps.push(::std::format!("{}.Set{}({});", instance, ::std::stringify!(#oneliners).to_case(Case::Pascal), self.#oneliners.reds_value())); } )* let mut child_name; From 94525e5e84b0cfde45d72d82489af11a9a803c3c Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Mon, 28 Oct 2024 12:11:44 +0700 Subject: [PATCH 16/17] :arrow_up: update red4ext-rs --- Cargo.lock | 293 ++++++++++++++++++++++++++-------------------- Cargo.toml | 2 +- macros/Cargo.toml | 1 + 3 files changed, 168 insertions(+), 128 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0584500..111e617 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,16 @@ dependencies = [ "libc", ] +[[package]] +name = "annotate-snippets" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaf7e9dfbb6ab22c82e473cd1a8a7bd313c19a5b7e40970f3d89ef5a5c9e81e" +dependencies = [ + "unicode-width", + "yansi-term", +] + [[package]] name = "anstream" version = "0.6.17" @@ -81,6 +91,33 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "annotate-snippets", + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "bumpalo" version = "3.16.0" @@ -96,6 +133,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -115,6 +161,17 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.20" @@ -143,10 +200,10 @@ version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -156,13 +213,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "cmake" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" dependencies = [ - "termcolor", - "unicode-width", + "cc", ] [[package]] @@ -204,60 +260,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "cxx" -version = "1.0.129" +name = "either" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdc8cca144dce1c4981b5c9ab748761619979e515c3d53b5df385c677d1d007" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] -name = "cxx-build" -version = "1.0.129" +name = "enum_dispatch" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5764c3142ab44fcf857101d12c0ddf09c34499900557c764f5ad0597159d1fc" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ - "cc", - "codespan-reporting", "once_cell", "proc-macro2", "quote", - "scratch", - "syn 2.0.85", + "syn", ] [[package]] -name = "cxxbridge-flags" -version = "1.0.129" +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d422aff542b4fa28c2ce8e5cc202d42dbf24702345c1fba3087b2d3f8a1b90ff" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] -name = "cxxbridge-macro" -version = "1.0.129" +name = "heck" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1719100f31492cd6adeeab9a0f46cdbc846e615fdb66d7b398aa46ec7fdd06f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.85", -] - -[[package]] -name = "enum_dispatch" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.85", -] +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "heck" @@ -311,7 +341,8 @@ version = "0.3.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "red4ext-rs", + "syn", ] [[package]] @@ -320,6 +351,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -348,12 +388,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] -name = "link-cplusplus" -version = "1.0.9" +name = "libloading" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ - "cc", + "cfg-if", + "windows-targets", ] [[package]] @@ -369,32 +410,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] -name = "num-traits" -version = "0.2.19" +name = "minimal-lexical" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] -name = "num_enum" -version = "0.7.3" +name = "nom" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ - "num_enum_derive", + "memchr", + "minimal-lexical", ] [[package]] -name = "num_enum_derive" -version = "0.7.3" +name = "num-traits" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.85", + "autocfg", ] [[package]] @@ -403,6 +440,16 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.89" @@ -423,25 +470,17 @@ dependencies = [ [[package]] name = "red4ext-rs" -version = "0.5.3" -source = "git+https://github.com/jac3km4/red4ext-rs.git?rev=2646318#26463186d9cd5a10fc296009f7eb0663efc0b55e" +version = "0.9.1" +source = "git+https://github.com/jac3km4/red4ext-rs.git?rev=v0.9.1#41c16ccbba70355cdeedea82e431c0a184a1f3cc" dependencies = [ + "bindgen", + "cmake", "const-combine", - "red4ext-sys", - "thiserror", - "wchar", -] - -[[package]] -name = "red4ext-sys" -version = "0.5.3" -source = "git+https://github.com/jac3km4/red4ext-rs.git?rev=2646318#26463186d9cd5a10fc296009f7eb0663efc0b55e" -dependencies = [ "const-crc32", - "cxx", - "cxx-build", - "num_enum", + "once_cell", + "sealed", "thiserror", + "widestring", ] [[package]] @@ -473,6 +512,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "ryu" version = "1.0.18" @@ -480,10 +525,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] -name = "scratch" -version = "1.0.7" +name = "sealed" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" +checksum = "f4a8caec23b7800fb97971a1c6ae365b6239aaeddfb934d6265f8505e795699d" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn", +] [[package]] name = "serde" @@ -513,7 +564,7 @@ checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -540,17 +591,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.85" @@ -573,15 +613,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.65" @@ -599,7 +630,7 @@ checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -648,7 +679,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn", "wasm-bindgen-shared", ] @@ -670,7 +701,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -682,33 +713,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] -name = "wchar" -version = "0.11.1" +name = "widestring" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8be48fe4c433c0d4aa71bb8759c5f7b1da6dacb1b99998566ebe16503f6a59c" -dependencies = [ - "wchar-impl", -] +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] -name = "wchar-impl" -version = "0.11.0" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "075c93156fed21f9dab57af5e81604d0fdb67432c919a8c1f78bb979f06a3d25" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] -name = "winapi-util" -version = "0.1.9" +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys", -] +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" @@ -791,3 +821,12 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "yansi-term" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1" +dependencies = [ + "winapi", +] diff --git a/Cargo.toml b/Cargo.toml index 188baf2..f21a706 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,5 +30,5 @@ chrono = { version = "0.4.38", default-features = false, features = [ clap = { version = "4.5.20", features = ["derive"] } const-str = "0.5.6" convert_case = "0.6.0" -red4ext-rs = { git = "https://github.com/jac3km4/red4ext-rs.git", rev = "2646318" } +red4ext-rs = { git = "https://github.com/jac3km4/red4ext-rs.git", rev = "v0.9.1" } term-table = "1.4.0" diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 3b8b8e2..963b686 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -17,3 +17,4 @@ proc-macro = true syn = "2" proc-macro2 = "1" quote = "1" +red4ext-rs = { git = "https://github.com/jac3km4/red4ext-rs.git", rev = "v0.9.1" } From 2784a2128bec07d5702abb375bdc012b9dd9c6d5 Mon Sep 17 00:00:00 2001 From: Roms1383 Date: Mon, 28 Oct 2024 12:11:59 +0700 Subject: [PATCH 17/17] :alien: update from latest red4ext-rs changes --- macros/src/lib.rs | 10 +++++----- src/ink/mod.rs | 12 ++++++------ src/ink/widget/font.rs | 12 ++++++------ src/ink/widget/image.rs | 6 +++--- src/ink/widget/layout.rs | 18 +++++++++--------- src/ink/widget/mod.rs | 8 +++----- src/ink/widget/properties.rs | 6 +++--- 7 files changed, 35 insertions(+), 37 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 76bedba..51254ba 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -42,7 +42,7 @@ fn derive_reds_widget_leaf_for_struct(name: &syn::Ident, r#struct: &syn::DataStr quote! { impl crate::RedsWidgetLeaf for #name { fn reds_widget_leaf(&self, instance: &str, parent: Option<&str>) -> String { - use ::red4ext_rs::conv::NativeRepr; + use ::red4ext_rs::NativeRepr; use crate::RedsValue; use crate::IsDefault; use convert_case::{Case, Casing}; @@ -70,7 +70,7 @@ fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) - return quote! { impl crate::RedsValue for #name { fn reds_value(&self) -> String { - use ::red4ext_rs::conv::NativeRepr; + use ::red4ext_rs::NativeRepr; let mut args = Vec::::new(); #( args.push(self.#indexes.reds_value()); @@ -84,7 +84,7 @@ fn derive_reds_value_for_struct(name: &syn::Ident, r#struct: &syn::DataStruct) - quote! { impl crate::RedsValue for #name { fn reds_value(&self) -> String { - use ::red4ext_rs::conv::NativeRepr; + use ::red4ext_rs::NativeRepr; let mut args = Vec::::new(); #( args.push(self.#fields.reds_value()); @@ -111,7 +111,7 @@ fn derive_reds_value_for_enum(name: &syn::Ident, r#enum: &syn::DataEnum) -> Toke quote! { impl crate::RedsValue for #name { fn reds_value(&self) -> String { - use ::red4ext_rs::conv::NativeRepr; + use ::red4ext_rs::NativeRepr; match self { #(#matches),* } @@ -128,7 +128,7 @@ fn derive_reds_widget_compound_for_struct(name: &syn::Ident, r#struct: &syn::Dat quote! { impl crate::RedsWidgetCompound for #name { fn reds_widget_compound(&self, instance: &str, parent: Option<&str>) -> String { - use ::red4ext_rs::conv::NativeRepr; + use ::red4ext_rs::NativeRepr; use crate::widget::layout::inkEChildOrder; use crate::RedsValue; use crate::IsDefault; diff --git a/src/ink/mod.rs b/src/ink/mod.rs index e6a53d8..1268860 100644 --- a/src/ink/mod.rs +++ b/src/ink/mod.rs @@ -79,7 +79,7 @@ pub struct Vector2 { pub y: f32, } -unsafe impl red4ext_rs::prelude::NativeRepr for Vector2 { +unsafe impl red4ext_rs::NativeRepr for Vector2 { const NAME: &'static str = "Vector2"; } @@ -94,7 +94,7 @@ pub struct HDRColor { pub red: f32, } -unsafe impl red4ext_rs::prelude::NativeRepr for HDRColor { +unsafe impl red4ext_rs::NativeRepr for HDRColor { const NAME: &'static str = "HDRColor"; } @@ -103,7 +103,7 @@ unsafe impl red4ext_rs::prelude::NativeRepr for HDRColor { #[serde(transparent)] pub struct HandleId(#[serde(deserialize_with = "deserialize_number_from_string")] u32); -unsafe impl red4ext_rs::prelude::NativeRepr for HandleId { +unsafe impl red4ext_rs::NativeRepr for HandleId { const NAME: &'static str = "HandleId"; } @@ -159,7 +159,7 @@ impl RedsValue for CName { } } -unsafe impl red4ext_rs::prelude::NativeRepr for CName { +unsafe impl red4ext_rs::NativeRepr for CName { const NAME: &'static str = "CName"; } @@ -176,7 +176,7 @@ pub struct LocalizationString { pub value: Option, } -unsafe impl red4ext_rs::prelude::NativeRepr for LocalizationString { +unsafe impl red4ext_rs::NativeRepr for LocalizationString { const NAME: &'static str = "LocalizationString"; } @@ -248,7 +248,7 @@ mod tests { pub content_h_align: inkEHorizontalAlign, pub size: Vector2, } - unsafe impl red4ext_rs::prelude::NativeRepr for TestChild { + unsafe impl red4ext_rs::NativeRepr for TestChild { const NAME: &'static str = "TChild"; } #[test] diff --git a/src/ink/widget/font.rs b/src/ink/widget/font.rs index 2fd7674..0d18d31 100644 --- a/src/ink/widget/font.rs +++ b/src/ink/widget/font.rs @@ -13,7 +13,7 @@ pub struct inkFontFamilyResource { flags: Flags, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkFontFamilyResource { +unsafe impl red4ext_rs::NativeRepr for inkFontFamilyResource { const NAME: &'static str = "inkFontFamilyResource"; } @@ -21,7 +21,7 @@ unsafe impl red4ext_rs::prelude::NativeRepr for inkFontFamilyResource { #[derive(Debug, Serialize, Clone, Deserialize, Default, RedsValue, PartialEq)] pub struct fontStyle(pub CName); -unsafe impl red4ext_rs::prelude::NativeRepr for fontStyle { +unsafe impl red4ext_rs::NativeRepr for fontStyle { const NAME: &'static str = "fontStyle"; } @@ -34,7 +34,7 @@ pub enum textLetterCase { LowerCase = 2, } -unsafe impl red4ext_rs::prelude::NativeRepr for textLetterCase { +unsafe impl red4ext_rs::NativeRepr for textLetterCase { const NAME: &'static str = "textLetterCase"; } @@ -47,7 +47,7 @@ pub enum textHorizontalAlignment { Right = 2, } -unsafe impl red4ext_rs::prelude::NativeRepr for textHorizontalAlignment { +unsafe impl red4ext_rs::NativeRepr for textHorizontalAlignment { const NAME: &'static str = "textHorizontalAlignment"; } @@ -60,7 +60,7 @@ pub enum textVerticalAlignment { Bottom = 2, } -unsafe impl red4ext_rs::prelude::NativeRepr for textVerticalAlignment { +unsafe impl red4ext_rs::NativeRepr for textVerticalAlignment { const NAME: &'static str = "textVerticalAlignment"; } @@ -76,6 +76,6 @@ pub enum textOverflowPolicy { AdjustToSize = 5, } -unsafe impl red4ext_rs::prelude::NativeRepr for textOverflowPolicy { +unsafe impl red4ext_rs::NativeRepr for textOverflowPolicy { const NAME: &'static str = "textOverflowPolicy"; } diff --git a/src/ink/widget/image.rs b/src/ink/widget/image.rs index bd0595f..2da2ffc 100644 --- a/src/ink/widget/image.rs +++ b/src/ink/widget/image.rs @@ -13,7 +13,7 @@ pub struct inkTextureAtlas { flags: Flags, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkTextureAtlas { +unsafe impl red4ext_rs::NativeRepr for inkTextureAtlas { const NAME: &'static str = "inkTextureAtlas"; } @@ -27,7 +27,7 @@ pub enum inkBrushMirrorType { Both = 3, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkBrushMirrorType { +unsafe impl red4ext_rs::NativeRepr for inkBrushMirrorType { const NAME: &'static str = "inkBrushMirrorType"; } @@ -41,6 +41,6 @@ pub enum inkBrushTileType { Both = 3, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkBrushTileType { +unsafe impl red4ext_rs::NativeRepr for inkBrushTileType { const NAME: &'static str = "inkBrushTileType"; } diff --git a/src/ink/widget/layout.rs b/src/ink/widget/layout.rs index a74c3ab..d22fb0f 100644 --- a/src/ink/widget/layout.rs +++ b/src/ink/widget/layout.rs @@ -25,7 +25,7 @@ pub enum inkEAnchor { Fill = 15, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkEAnchor { +unsafe impl red4ext_rs::NativeRepr for inkEAnchor { const NAME: &'static str = "inkEAnchor"; } @@ -39,7 +39,7 @@ pub enum inkEHorizontalAlign { Right = 3, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkEHorizontalAlign { +unsafe impl red4ext_rs::NativeRepr for inkEHorizontalAlign { const NAME: &'static str = "inkEHorizontalAlign"; } @@ -53,7 +53,7 @@ pub enum inkEVerticalAlign { Bottom = 3, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkEVerticalAlign { +unsafe impl red4ext_rs::NativeRepr for inkEVerticalAlign { const NAME: &'static str = "inkEVerticalAlign"; } @@ -66,7 +66,7 @@ pub struct inkUITransform { pub rotation: f32, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkUITransform { +unsafe impl red4ext_rs::NativeRepr for inkUITransform { const NAME: &'static str = "inkUITransform"; } @@ -79,7 +79,7 @@ pub enum textJustificationType { Right = 2, } -unsafe impl red4ext_rs::prelude::NativeRepr for textJustificationType { +unsafe impl red4ext_rs::NativeRepr for textJustificationType { const NAME: &'static str = "textJustificationType"; } @@ -93,7 +93,7 @@ pub struct inkMargin { pub bottom: f32, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkMargin { +unsafe impl red4ext_rs::NativeRepr for inkMargin { const NAME: &'static str = "inkMargin"; } @@ -113,7 +113,7 @@ pub struct inkWidgetLayout { pub size_rule: inkESizeRule, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkWidgetLayout { +unsafe impl red4ext_rs::NativeRepr for inkWidgetLayout { const NAME: &'static str = "inkWidgetLayout"; } @@ -125,7 +125,7 @@ pub enum inkEChildOrder { Backward = 1, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkEChildOrder { +unsafe impl red4ext_rs::NativeRepr for inkEChildOrder { const NAME: &'static str = "inkEChildOrder"; } @@ -137,6 +137,6 @@ pub enum inkESizeRule { Stretch = 1, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkESizeRule { +unsafe impl red4ext_rs::NativeRepr for inkESizeRule { const NAME: &'static str = "inkESizeRule"; } diff --git a/src/ink/widget/mod.rs b/src/ink/widget/mod.rs index 31f779c..31012cf 100644 --- a/src/ink/widget/mod.rs +++ b/src/ink/widget/mod.rs @@ -43,7 +43,7 @@ pub enum Flags { Hard, } -unsafe impl red4ext_rs::prelude::NativeRepr for Flags { +unsafe impl red4ext_rs::NativeRepr for Flags { const NAME: &'static str = "Flags"; } @@ -67,9 +67,8 @@ macro_rules! native_compound_widget { pub child_order: self::layout::inkEChildOrder, pub child_margin: self::layout::inkMargin, } - unsafe impl red4ext_rs::prelude::NativeRepr for $ty { + unsafe impl red4ext_rs::NativeRepr for $ty { const NAME: &'static str = ::const_str::replace!(::std::stringify!($ty), "Widget", ""); - const NATIVE_NAME: &'static str = ::std::stringify!($ty); } }; } @@ -89,9 +88,8 @@ macro_rules! native_leaf_widget { pub size: crate::Vector2, $($tt)* } - unsafe impl red4ext_rs::prelude::NativeRepr for $ty { + unsafe impl red4ext_rs::NativeRepr for $ty { const NAME: &'static str = ::const_str::replace!(::std::stringify!($ty), "Widget", ""); - const NATIVE_NAME: &'static str = ::std::stringify!($ty); } }; ($ty:ident) => { diff --git a/src/ink/widget/properties.rs b/src/ink/widget/properties.rs index 7a9baad..c11057e 100644 --- a/src/ink/widget/properties.rs +++ b/src/ink/widget/properties.rs @@ -11,7 +11,7 @@ pub struct inkPropertyBinding { pub style_path: CName, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkPropertyBinding { +unsafe impl red4ext_rs::NativeRepr for inkPropertyBinding { const NAME: &'static str = "inkPropertyBinding"; } @@ -22,7 +22,7 @@ pub struct inkPropertyManager { pub bindings: Vec, } -unsafe impl red4ext_rs::prelude::NativeRepr for inkPropertyManager { +unsafe impl red4ext_rs::NativeRepr for inkPropertyManager { const NAME: &'static str = "inkPropertyManager"; } @@ -33,6 +33,6 @@ pub struct PropertyManager { pub data: inkPropertyManager, } -unsafe impl red4ext_rs::prelude::NativeRepr for PropertyManager { +unsafe impl red4ext_rs::NativeRepr for PropertyManager { const NAME: &'static str = "PropertyManager"; }