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(_) => {
match object.as_any_object_base_property().unwrap() {
any_type::AnyObjectBaseProperty::Object(obj) => {
Type::Ptr(Box::new(Type::Class(unsafe {
// safety: any uclass is also a ustruct
obj.property_class()
.context("object property missing properry class")?
.cast()
})))
}
any_type::AnyObjectBaseProperty::Object(obj) => Type::Class(
obj.property_class()
.context("object property missing properry class")?,
),
any_type::AnyObjectBaseProperty::WeakObject(obj) => Type::WeakPtr(
obj.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")?,
},
AnyProperty::Struct(class) => Type::Class(
AnyProperty::Struct(class) => Type::Struct(
class
.ustruct()
.context("struct property had no inner struct")?,
@ -733,7 +729,8 @@ pub mod sdk {
underlying: Box<Type>,
enum_type: UEnum,
},
Class(UStruct),
Class(UClass),
Struct(UStruct),
}
impl Type {
@ -746,6 +743,7 @@ pub mod sdk {
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::Enum { enum_type, .. } => Some(enum_type.as_uobject()),
}

View file

@ -115,6 +115,11 @@ impl RustType for Type {
write!(w, ">")?;
}
Type::Class(class) => {
write!(w, "Option<")?;
class.rust_type(sdk, w)?;
write!(w, ">")?;
}
Type::Struct(class) => {
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();
writeln!(w, "#[repr(transparent)]")?;
writeln!(w, "#[derive(Debug)]")?;
writeln!(w, "#[derive(Debug, Eq, PartialEq, Copy, Clone)]")?;
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!(
w,
r#"
write!(
w,
r#"
impl AsPtr for {name} {{
fn as_ptr(&self) -> *const u8 {{
self.0.get() as _
}}
fn as_mut_ptr(&self) -> *mut u8 {{
self.0.get()
}}
fn as_ptr(&self) -> *const u8 {{
self.0.get() as _
}}
fn as_mut_ptr(&self) -> *mut u8 {{
self.0.get()
}}
}}
"#
)?;
)?;
if !is_class {
write!(
w,
r#"
@ -165,6 +167,22 @@ impl {name} {{
"#
)?;
} 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, "fn get_static_class() -> Option<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();
writeln!(w, "pub trait {}_Fields {{", name)?;
writeln!(w, "pub trait {}_Fields: AsPtr {{", name)?;
for field in fields {
write!(w, "fn get_{}(&self) -> &", field.name)?;
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)?;
}
writeln!(w, "pub trait {}_Methods {{", name)?;
writeln!(w, "pub trait {}_Methods: AsPtr {{", name)?;
for method in methods {
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, "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;")?;
for param in &method.parameters {