From 5b8ec055898df08d60e7dbd3f89fa368a31e2e58 Mon Sep 17 00:00:00 2001 From: Janis Date: Mon, 26 Jun 2023 12:55:30 +0200 Subject: [PATCH] absolute paths and getters for path/type name --- sdk-builder/src/main.rs | 113 ++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/sdk-builder/src/main.rs b/sdk-builder/src/main.rs index f878e7f..b372a45 100644 --- a/sdk-builder/src/main.rs +++ b/sdk-builder/src/main.rs @@ -157,24 +157,9 @@ pub mod rust { .packages .iter() .flat_map(|(_, pkg)| { - pkg.types.values().map(|ty| { - let name = match ty { - UnrealType::Class(class) => { - format!("U{}", canonicalize_name(&class.name)) - } - UnrealType::Struct(class) => { - format!("F{}", canonicalize_name(&class.name)) - } - UnrealType::Actor(class) => { - format!("A{}", canonicalize_name(&class.name)) - } - UnrealType::Enum(class) => { - format!("E{}", canonicalize_name(&class.name)) - } - }; - - (ty.obj_ref(), name) - }) + pkg.types + .values() + .map(|ty| (ty.obj_ref(), Self::get_prefixed_name(&ty))) }) .collect::>(); @@ -184,6 +169,38 @@ pub mod rust { } } + /// returns the absolute path of a type with the assumption that all + /// packages are children of the path `::crate::sdk` + fn get_type_path(&self, key: &ObjectRef) -> Option { + let pkg = &self.sdk.packages.get(&key.package)?.name; + self.get_type_name(key) + .map(|name| format!("::crate::sdk::{pkg}::{name}")) + } + + /// returns the precached, prefixed and cannonicalized (for this + /// language, Rust) name for this object-ref + fn get_type_name(&self, key: &ObjectRef) -> Option { + self.type_name_cache.get(key).cloned() + } + + /// prefixes the typename according to its kind (UObject, AActor, FStruct, EEnum) + fn get_prefixed_name(ty: &UnrealType) -> String { + match ty { + UnrealType::Class(_) => { + format!("U{}", canonicalize_name(&ty.unique_name())) + } + UnrealType::Struct(_) => { + format!("F{}", canonicalize_name(&ty.unique_name())) + } + UnrealType::Actor(_) => { + format!("A{}", canonicalize_name(&ty.unique_name())) + } + UnrealType::Enum(_) => { + format!("E{}", canonicalize_name(&ty.unique_name())) + } + } + } + pub fn build(self) -> anyhow::Result<()> { for pkg in self.sdk.packages.values() { self.generate_package(pkg)?; @@ -195,64 +212,61 @@ pub mod rust { fn type_name(&self, ty: &Type) -> anyhow::Result { let type_name = match ty { Type::Ptr(inner) | Type::Ref(inner) => { - format!("Option>", self.type_name(&inner)?) + format!( + "::core::option::Option>", + self.type_name(&inner)? + ) } Type::WeakPtr(inner) => { format!( - "TWeakObjectPtr<{}>", - self.type_name_cache - .get(inner) + "::crate::engine::TWeakObjectPtr<{}>", + self.get_type_path(inner) .context("type name was not cached.")? ) } Type::SoftPtr(inner) => { format!( - "TSoftObjectPtr<{}>", - self.type_name_cache - .get(inner) + "::crate::engine::TSoftObjectPtr<{}>", + self.get_type_path(inner) .context("type name was not cached.")? ) } Type::LazyPtr(inner) => { format!( - "TLazyObjectPtr<{}>", - self.type_name_cache - .get(inner) + "::crate::engine::TLazyObjectPtr<{}>", + self.get_type_path(inner) .context("type name was not cached.")? ) } Type::AssetPtr(inner) => format!( - "TAssetPtr<{}>", - self.type_name_cache - .get(inner) + "::crate::engine::TAssetPtr<{}>", + self.get_type_path(inner) .context("type name was not cached.")? ), - Type::Array(inner) => format!("TArray<{}>", self.type_name(&inner)?), + Type::Array(inner) => { + format!("::crate::engine::TArray<{}>", self.type_name(&inner)?) + } Type::Primitive(prim) => { format!("{prim}") } Type::RawArray { ty, len } => { format!("[{}; {}]", self.type_name(&ty)?, len) } - Type::Name => "FName".to_string(), - Type::String => "FString".to_string(), - Type::Text => "FText".to_string(), + Type::Name => "::crate::engine::FName".to_string(), + Type::String => "::crate::engine::FString".to_string(), + Type::Text => "::crate::engine::FText".to_string(), Type::Enum { enum_type, .. } => self - .type_name_cache - .get(enum_type) - .context("type name was not cached.")? - .clone(), + .get_type_path(enum_type) + .context("type name was not cached.")?, Type::Class(class) => { format!( "::core::option::Option<{}>", - self.type_name_cache - .get(class) + self.get_type_path(class) .context("type name was not cached.")? ) } Type::Struct(class) => self - .type_name_cache - .get(class) + .get_type_path(class) .context("type name was not cached.")? .clone(), }; @@ -262,8 +276,7 @@ pub mod rust { fn generate_enum(&self, enum0: &Enum) -> anyhow::Result { let name = self - .type_name_cache - .get(&enum0.obj_ref) + .get_type_name(&enum0.obj_ref) .context("enum name was not previously canonicalized and cached.")?; let variants = enum0.values.iter().map(|(&value, name)| { @@ -658,9 +671,8 @@ pub mod rust { } fn generate_class(&self, class: &Class) -> anyhow::Result { - let name = self - .type_name_cache - .get(&class.obj_ref) + let name = &self + .get_type_name(&class.obj_ref) .context("enum name was not previously canonicalized and cached.")?; let (field_trait, ctor) = self.generate_struct_fields(class, name)?; @@ -696,13 +708,12 @@ pub mod rust { None } }) - .map(|ty| ty.unique_name()) + // 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(|super_name| { let fields = format_ident!("{super_name}Fields"); let methods = format_ident!("{super_name}Methods"); - // FIXME: full path here? meaning I need the package name aswell. - quote! { impl #fields for #name {} impl #methods for #name {}