representing Objects as transparent ´NonNull<UnsafeCell<u8>>´

This commit is contained in:
Janis 2023-04-21 17:33:09 +02:00
parent 32bcc30b96
commit 6ea9e81e29
2 changed files with 47 additions and 28 deletions

View file

@ -230,14 +230,10 @@ pub mod sdk {
} }
object @ AnyProperty::ObjectBase(_) => { object @ AnyProperty::ObjectBase(_) => {
match object.as_any_object_base_property().unwrap() { match object.as_any_object_base_property().unwrap() {
any_type::AnyObjectBaseProperty::Object(obj) => { any_type::AnyObjectBaseProperty::Object(obj) => Type::Class(
Type::Ptr(Box::new(Type::Class(unsafe { obj.property_class()
// safety: any uclass is also a ustruct .context("object property missing properry class")?,
obj.property_class() ),
.context("object property missing properry class")?
.cast()
})))
}
any_type::AnyObjectBaseProperty::WeakObject(obj) => Type::WeakPtr( any_type::AnyObjectBaseProperty::WeakObject(obj) => Type::WeakPtr(
obj.property_class() obj.property_class()
.context("weak ptr property missing property class.")?, .context("weak ptr property missing property class.")?,
@ -293,7 +289,7 @@ pub mod sdk {
))?), ))?),
enum_type: enm.uenum().context("enum property missing enum type")?, enum_type: enm.uenum().context("enum property missing enum type")?,
}, },
AnyProperty::Struct(class) => Type::Class( AnyProperty::Struct(class) => Type::Struct(
class class
.ustruct() .ustruct()
.context("struct property had no inner struct")?, .context("struct property had no inner struct")?,
@ -733,7 +729,8 @@ pub mod sdk {
underlying: Box<Type>, underlying: Box<Type>,
enum_type: UEnum, enum_type: UEnum,
}, },
Class(UStruct), Class(UClass),
Struct(UStruct),
} }
impl Type { impl Type {
@ -746,6 +743,7 @@ pub mod sdk {
Some(o.as_uobject()) Some(o.as_uobject())
} }
Type::Class(o) => Some(o.as_uobject()), Type::Class(o) => Some(o.as_uobject()),
Type::Struct(o) => Some(o.as_uobject()),
Type::Primitive(_) | Type::Name | Type::String | Type::Text => None, Type::Primitive(_) | Type::Name | Type::String | Type::Text => None,
Type::Enum { enum_type, .. } => Some(enum_type.as_uobject()), Type::Enum { enum_type, .. } => Some(enum_type.as_uobject()),
} }

View file

@ -115,6 +115,11 @@ impl RustType for Type {
write!(w, ">")?; write!(w, ">")?;
} }
Type::Class(class) => { Type::Class(class) => {
write!(w, "Option<")?;
class.rust_type(sdk, w)?;
write!(w, ">")?;
}
Type::Struct(class) => {
class.rust_type(sdk, w)?; class.rust_type(sdk, w)?;
} }
} }
@ -133,27 +138,24 @@ pub fn generate_class<W: Write>(class: &Class, _sdk: &Sdk, w: &mut W) -> anyhow:
let name = class.rust_name(); let name = class.rust_name();
writeln!(w, "#[repr(transparent)]")?; writeln!(w, "#[repr(transparent)]")?;
writeln!(w, "#[derive(Debug)]")?; writeln!(w, "#[derive(Debug, Eq, PartialEq, Copy, Clone)]")?;
if !is_class { if !is_class {
writeln!(w, "#[derive(Debug, Eq, PartialEq, Copy, Clone)]")?; writeln!(w, "pub struct {name}(UnsafeCell<[u8; {size}]>);")?;
}
writeln!(w, "pub struct {name}(UnsafeCell<[u8; {size}]>);")?;
write!( write!(
w, w,
r#" r#"
impl AsPtr for {name} {{ impl AsPtr for {name} {{
fn as_ptr(&self) -> *const u8 {{ fn as_ptr(&self) -> *const u8 {{
self.0.get() as _ self.0.get() as _
}} }}
fn as_mut_ptr(&self) -> *mut u8 {{ fn as_mut_ptr(&self) -> *mut u8 {{
self.0.get() self.0.get()
}} }}
}} }}
"# "#
)?; )?;
if !is_class {
write!( write!(
w, w,
r#" r#"
@ -165,6 +167,22 @@ impl {name} {{
"# "#
)?; )?;
} else { } else {
writeln!(w, "pub struct {name}(NonNull<UnsafeCell<u8>>);")?;
write!(
w,
r#"
impl AsPtr for {name} {{
fn as_ptr(&self) -> *const u8 {{
unsafe {{ self.0.as_ref().get() as _ }}
}}
fn as_mut_ptr(&self) -> *mut u8 {{
unsafe {{ self.0.as_ref().get() as _ }}
}}
}}
"#
)?;
writeln!(w, "impl StaticClass for {name} {{")?; writeln!(w, "impl StaticClass for {name} {{")?;
writeln!(w, "fn get_static_class() -> Option<UClass> {{")?; writeln!(w, "fn get_static_class() -> Option<UClass> {{")?;
write!(w, "let class: UClass = ")?; write!(w, "let class: UClass = ")?;
@ -188,7 +206,7 @@ pub fn generate_class_impl<W: Write>(class: &Class, sdk: &Sdk, w: &mut W) -> any
let name = class.rust_name(); let name = class.rust_name();
writeln!(w, "pub trait {}_Fields {{", name)?; writeln!(w, "pub trait {}_Fields: AsPtr {{", name)?;
for field in fields { for field in fields {
write!(w, "fn get_{}(&self) -> &", field.name)?; write!(w, "fn get_{}(&self) -> &", field.name)?;
field.ty.rust_type(sdk, w)?; field.ty.rust_type(sdk, w)?;
@ -213,7 +231,7 @@ pub fn generate_class_impl<W: Write>(class: &Class, sdk: &Sdk, w: &mut W) -> any
generate_method_params(class, method, sdk, w)?; generate_method_params(class, method, sdk, w)?;
} }
writeln!(w, "pub trait {}_Methods {{", name)?; writeln!(w, "pub trait {}_Methods: AsPtr {{", name)?;
for method in methods { for method in methods {
generate_method(class, method, sdk, w)?; generate_method(class, method, sdk, w)?;
@ -313,7 +331,10 @@ pub fn generate_method<W: Write>(
} }
writeln!(w, "let flags = *func.function_flags();")?; writeln!(w, "let flags = *func.function_flags();")?;
writeln!(w, "process_event(&self as *const _, func, &mut params);")?; writeln!(
w,
"process_event(self.as_ptr() as *const _, func, &mut params);"
)?;
writeln!(w, "*func.function_flags_mut() = flags;")?; writeln!(w, "*func.function_flags_mut() = flags;")?;
for param in &method.parameters { for param in &method.parameters {