fname new doesnt need static str, return tuples for methods, constr for structs

This commit is contained in:
Janis 2023-05-12 17:45:45 +02:00
parent 285ae4b56f
commit 1e059a3b92
3 changed files with 61 additions and 31 deletions

View file

@ -17,13 +17,14 @@ pub struct FName {
} }
impl FName { impl FName {
pub fn new(name: &'static str) -> anyhow::Result<Self> { pub fn new(name: &str) -> anyhow::Result<Self> {
static CACHE: Lazy<Mutex<RefCell<HashMap<&'static str, u32>>>> = let name = name.to_owned();
static CACHE: Lazy<Mutex<RefCell<HashMap<String, u32>>>> =
Lazy::new(|| Mutex::new(RefCell::new(HashMap::new()))); Lazy::new(|| Mutex::new(RefCell::new(HashMap::new())));
let cache = CACHE.lock().unwrap(); 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 { Entry::Occupied(entry) => Self {
comparison_index: *entry.get(), comparison_index: *entry.get(),
number: 0, number: 0,
@ -35,7 +36,7 @@ impl FName {
.as_names() .as_names()
.unwrap() .unwrap()
.enumerate() .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; .context("could not find fname.")? as u32;
entry.insert(name); entry.insert(name);

View file

@ -828,6 +828,19 @@ pub mod sdk {
pub return_type: Option<MethodParameter>, pub return_type: Option<MethodParameter>,
} }
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)] #[derive(Debug)]
pub struct Class { pub struct Class {
pub is_class: bool, pub is_class: bool,

View file

@ -152,11 +152,12 @@ pub fn generate_enum<W: Write>(enm: &Enum, _sdk: &Sdk, w: &mut W) -> anyhow::Res
Ok(()) Ok(())
} }
pub fn generate_class<W: Write>(class: &Class, _sdk: &Sdk, w: &mut W) -> anyhow::Result<()> { pub fn generate_class<W: Write>(class: &Class, sdk: &Sdk, w: &mut W) -> anyhow::Result<()> {
let Class { let Class {
is_class, is_class,
size, size,
full_name, full_name,
fields,
.. ..
} = class; } = class;
@ -210,9 +211,27 @@ impl {name} {{
pub fn zeroed() -> Self {{ pub fn zeroed() -> Self {{
unsafe {{ core::mem::MaybeUninit::<Self>::zeroed().assume_init() }} unsafe {{ core::mem::MaybeUninit::<Self>::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 { } else {
writeln!(w, "#[derive(Debug, Eq, PartialEq, Copy, Clone)]")?; writeln!(w, "#[derive(Debug, Eq, PartialEq, Copy, Clone)]")?;
writeln!(w, "pub struct {name}(pub NonNull<UnsafeCell<u8>>);")?; writeln!(w, "pub struct {name}(pub NonNull<UnsafeCell<u8>>);")?;
@ -374,21 +393,25 @@ pub fn generate_method<W: Write>(
write!(w, ",{}: ", parm.name)?; write!(w, ",{}: ", parm.name)?;
parm.ty.rust_type(sdk, w)?; 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, ") -> ")?; write!(w, ") -> ")?;
match &method.return_type { let return_tuple = method.return_tuple();
Some(param) => {
// 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)?; param.ty.rust_type(sdk, w)?;
write!(w, ",")?;
} }
None => write!(w, "()")?, write!(w, ")")?;
} }
writeln!(w, " {{")?; writeln!(w, " {{")?;
@ -405,10 +428,6 @@ pub fn generate_method<W: Write>(
crate::sdk::ParameterKind::Default(param) => { crate::sdk::ParameterKind::Default(param) => {
writeln!(w, "params.{0} = {0};", param.name)?; 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<W: Write>(
writeln!(w, "process_event(self.as_uobject(), func, &mut params);")?; writeln!(w, "process_event(self.as_uobject(), func, &mut params);")?;
writeln!(w, "func.set_function_flags(flags);")?; writeln!(w, "func.set_function_flags(flags);")?;
for param in &method.parameters { // return returntype and out params
match param {
crate::sdk::ParameterKind::Out(param) => {
// swap back
writeln!(w, "core::mem::swap({0}, &mut params.{0});", param.name)?;
}
_ => {}
}
}
match &method.return_type { if return_tuple.is_empty() {
Some(param) => { write!(w, "()")?;
writeln!(w, "params.{}", param.name)?; } 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, "}}")?; writeln!(w, "}}")?;