sdk-builder: proper absolute paths for types, proper ident construction

This commit is contained in:
Janis 2023-06-29 16:26:06 +02:00
parent 98b8d0378f
commit de6ff073dc

View file

@ -309,32 +309,32 @@ pub mod rust {
} }
Type::WeakPtr(inner) => { Type::WeakPtr(inner) => {
format!( format!(
"::crate::engine::TWeakObjectPtr<{}>", "crate::engine::TWeakObjectPtr<{}>",
self.get_type_path(inner) self.get_type_path(inner)
.context("type name was not cached.")? .context("type name was not cached.")?
) )
} }
Type::SoftPtr(inner) => { Type::SoftPtr(inner) => {
format!( format!(
"::crate::engine::TSoftObjectPtr<{}>", "crate::engine::TSoftObjectPtr<{}>",
self.get_type_path(inner) self.get_type_path(inner)
.context("type name was not cached.")? .context("type name was not cached.")?
) )
} }
Type::LazyPtr(inner) => { Type::LazyPtr(inner) => {
format!( format!(
"::crate::engine::TLazyObjectPtr<{}>", "crate::engine::TLazyObjectPtr<{}>",
self.get_type_path(inner) self.get_type_path(inner)
.context("type name was not cached.")? .context("type name was not cached.")?
) )
} }
Type::AssetPtr(inner) => format!( Type::AssetPtr(inner) => format!(
"::crate::engine::TAssetPtr<{}>", "crate::engine::TAssetPtr<{}>",
self.get_type_path(inner) self.get_type_path(inner)
.context("type name was not cached.")? .context("type name was not cached.")?
), ),
Type::Array(inner) => { Type::Array(inner) => {
format!("::crate::engine::TArray<{}>", self.type_name(&inner)?) format!("crate::engine::TArray<{}>", self.type_name(&inner)?)
} }
Type::Primitive(prim) => { Type::Primitive(prim) => {
format!("{prim}") format!("{prim}")
@ -342,9 +342,9 @@ pub mod rust {
Type::RawArray { ty, len } => { Type::RawArray { ty, len } => {
format!("[{}; {}]", self.type_name(&ty)?, len) format!("[{}; {}]", self.type_name(&ty)?, len)
} }
Type::Name => "::crate::engine::FName".to_string(), Type::Name => "crate::engine::FName".to_string(),
Type::String => "::crate::engine::FString".to_string(), Type::String => "crate::engine::FString".to_string(),
Type::Text => "::crate::engine::FText".to_string(), Type::Text => "crate::engine::FText".to_string(),
Type::Enum { enum_type, .. } => self Type::Enum { enum_type, .. } => self
.get_type_path(enum_type) .get_type_path(enum_type)
.context("type name was not cached.")?, .context("type name was not cached.")?,
@ -403,17 +403,17 @@ pub mod rust {
let static_class_impl: TokenStream = Self::generate_find_object(name); let static_class_impl: TokenStream = Self::generate_find_object(name);
let impls = quote! { let impls = quote! {
impl AsUObject for #name { impl crate::engine::AsUObject for #name {
fn as_uobject(&self) -> UObject { fn as_uobject(&self) -> crate::engine::UObject {
UObject(self.0) crate::engine::UObject(self.0)
} }
fn from_uobject(obj: &UObject) -> Self { fn from_uobject(obj: &crate::engine::UObject) -> Self {
Self(obj.0) Self(obj.0)
} }
} }
impl AsPtr for #name { impl crate::engine::AsPtr for #name {
fn as_ptr(&self) -> *const u8 { fn as_ptr(&self) -> *const u8 {
unsafe { self.0.as_ref().get() as _ } unsafe { self.0.as_ref().get() as _ }
} }
@ -423,9 +423,10 @@ pub mod rust {
} }
} }
impl StaticClass for #name { impl crate::engine::StaticClass for #name {
fn get_static_class() -> Option<UClass> { fn get_static_class() -> ::core::option::Option<crate::engine::UClass> {
let class: Option<UClass> = #static_class_impl; let class: ::core::option::Option<crate::engine::UClass> =
#static_class_impl;
class class
} }
} }
@ -462,7 +463,7 @@ pub mod rust {
} }
} }
impl AsPtr for #name { impl crate::engine::AsPtr for #name {
fn as_ptr(&self) -> *const u8 { fn as_ptr(&self) -> *const u8 {
self.0.get().cast() self.0.get().cast()
} }
@ -693,6 +694,8 @@ pub mod rust {
}); });
// FIXME: handle super struct fields aswell, ARK doesnt seem to have those anyways. // FIXME: handle super struct fields aswell, ARK doesnt seem to have those anyways.
// export getting fields into a seperate function, this function will be fallible then.
// it is a lot of work for nothing currently.
quote! { quote! {
pub fn new(#(#fields_defs),*) -> Self { pub fn new(#(#fields_defs),*) -> Self {
@ -762,6 +765,23 @@ pub mod rust {
} }
} }
fn iter_super_types(&self, class: &Class) -> impl Iterator<Item = &UnrealType> {
let super_traits = core::iter::from_fn({
let mut sup = class.super_class;
move || {
if let Some(key) = sup {
let next = self.sdk.get_object(&key);
sup = next.and_then(|next| next.super_class());
next
} else {
None
}
}
});
super_traits
}
fn generate_class(&self, class: &Class) -> anyhow::Result<TokenStream> { fn generate_class(&self, class: &Class) -> anyhow::Result<TokenStream> {
let name = &self let name = &self
.get_type_name(&class.obj_ref) .get_type_name(&class.obj_ref)
@ -788,29 +808,26 @@ pub mod rust {
impl #method_trait for #name {} impl #method_trait for #name {}
}; };
let mut sup = class.super_class; let super_traits = self
let super_traits = core::iter::from_fn(|| { .iter_super_types(class)
if let Some(key) = sup {
let next = self.sdk.get_object(&key);
sup = next.and_then(|next| next.super_class());
next
} else {
None
}
})
// SAFETY: we already got this type by its obj_ref, so it must be there. // SAFETY: we already got this type by its obj_ref, so it must be there.
.map(|ty| self.get_type_path(&ty.obj_ref()).unwrap()) .map(|ty| {
.map(|super_name| { (
self.get_type_package_path(&ty.obj_ref()).unwrap(),
self.get_type_name(&ty.obj_ref()).unwrap(),
)
})
.map(|(super_path, super_name)| {
let fields = format_ident!("{super_name}Fields"); let fields = format_ident!("{super_name}Fields");
let methods = format_ident!("{super_name}Methods"); let methods = format_ident!("{super_name}Methods");
quote! { quote! {
impl #fields for #name {} impl #super_path::#fields for #name {}
impl #methods for #name {} impl #super_path::#methods for #name {}
} }
}); });
quote! { let tokens = quote! {
#[repr(transparent)] #[repr(transparent)]
#[derive(Debug)] #[derive(Debug)]
#typedef #typedef