diff --git a/src/fname.rs b/src/fname.rs index e60d68a..5a48d75 100644 --- a/src/fname.rs +++ b/src/fname.rs @@ -17,13 +17,14 @@ pub struct FName { } impl FName { - pub fn new(name: &'static str) -> anyhow::Result { - static CACHE: Lazy>>> = + pub fn new(name: &str) -> anyhow::Result { + let name = name.to_owned(); + static CACHE: Lazy>>> = Lazy::new(|| Mutex::new(RefCell::new(HashMap::new()))); let cache = CACHE.lock().unwrap(); - let name = match cache.borrow_mut().entry(name) { + let name = match cache.borrow_mut().entry(name.clone()) { Entry::Occupied(entry) => Self { comparison_index: *entry.get(), number: 0, @@ -35,7 +36,7 @@ impl FName { .as_names() .unwrap() .enumerate() - .find_map(|(i, entry)| (entry.as_str() == name).then_some(i)) + .find_map(|(i, entry)| (entry.as_str() == &name).then_some(i)) .context("could not find fname.")? as u32; entry.insert(name); diff --git a/src/lib.rs b/src/lib.rs index efb7f60..67109c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -828,6 +828,19 @@ pub mod sdk { pub return_type: Option, } + impl ClassMethod { + pub fn return_tuple(&self) -> Vec<&MethodParameter> { + self.parameters + .iter() + .filter_map(|param| match param { + ParameterKind::Out(param) => Some(param), + _ => None, + }) + .chain(self.return_type.iter()) + .collect() + } + } + #[derive(Debug)] pub struct Class { pub is_class: bool, diff --git a/src/sdk/output/rust.rs b/src/sdk/output/rust.rs index 1bccd84..9eef3d8 100644 --- a/src/sdk/output/rust.rs +++ b/src/sdk/output/rust.rs @@ -152,11 +152,12 @@ pub fn generate_enum(enm: &Enum, _sdk: &Sdk, w: &mut W) -> anyhow::Res Ok(()) } -pub fn generate_class(class: &Class, _sdk: &Sdk, w: &mut W) -> anyhow::Result<()> { +pub fn generate_class(class: &Class, sdk: &Sdk, w: &mut W) -> anyhow::Result<()> { let Class { is_class, size, full_name, + fields, .. } = class; @@ -210,9 +211,27 @@ impl {name} {{ pub fn zeroed() -> Self {{ unsafe {{ core::mem::MaybeUninit::::zeroed().assume_init() }} }} -}} "# )?; + + // constructor + write!(w, "pub fn new(")?; + for field in fields { + write!(w, "{}: ", field.name)?; + field.ty.rust_type(sdk, w)?; + write!(w, ", ")?; + } + writeln!( + w, + r#") -> Self {{ +let mut new = Self::zeroed(); +"# + )?; + for field in fields { + writeln!(w, "new.set_{0}({0});", field.name)?; + } + writeln!(w, "new}}")?; + writeln!(w, "}}")?; } else { writeln!(w, "#[derive(Debug, Eq, PartialEq, Copy, Clone)]")?; writeln!(w, "pub struct {name}(pub NonNull>);")?; @@ -374,21 +393,25 @@ pub fn generate_method( write!(w, ",{}: ", parm.name)?; parm.ty.rust_type(sdk, w)?; } - crate::sdk::ParameterKind::Out(parm) => { - write!(w, ",{}: &mut ", parm.name)?; - parm.ty.rust_type(sdk, w)?; - write!(w, "/*(OutParm)*/")?; - } _ => {} } } write!(w, ") -> ")?; - match &method.return_type { - Some(param) => { + let return_tuple = method.return_tuple(); + + // return tuple + if return_tuple.is_empty() { + write!(w, "()")?; + } else if return_tuple.len() == 1 { + return_tuple[0].ty.rust_type(sdk, w)?; + } else { + write!(w, "(")?; + for param in &return_tuple { param.ty.rust_type(sdk, w)?; + write!(w, ",")?; } - None => write!(w, "()")?, + write!(w, ")")?; } writeln!(w, " {{")?; @@ -405,10 +428,6 @@ pub fn generate_method( crate::sdk::ParameterKind::Default(param) => { writeln!(w, "params.{0} = {0};", param.name)?; } - crate::sdk::ParameterKind::Out(param) => { - // swap so we dont have to worry about Clone or Copy - writeln!(w, "core::mem::swap(&mut params.{0}, {0});", param.name)?; - } _ => {} } } @@ -417,21 +436,18 @@ pub fn generate_method( writeln!(w, "process_event(self.as_uobject(), func, &mut params);")?; writeln!(w, "func.set_function_flags(flags);")?; - for param in &method.parameters { - match param { - crate::sdk::ParameterKind::Out(param) => { - // swap back - writeln!(w, "core::mem::swap({0}, &mut params.{0});", param.name)?; - } - _ => {} - } - } + // return returntype and out params - match &method.return_type { - Some(param) => { - writeln!(w, "params.{}", param.name)?; + if return_tuple.is_empty() { + write!(w, "()")?; + } else if return_tuple.len() == 1 { + writeln!(w, "params.{}", return_tuple[0].name)?; + } else { + write!(w, "(")?; + for param in &return_tuple { + writeln!(w, "params.{},", param.name)?; } - None => {} + write!(w, ")")?; } writeln!(w, "}}")?;