stuff that i mostly dont remember but refactoring in progress init consequences

of not looking at this for a month and not having commited anything before...........
This commit is contained in:
Janis 2023-06-17 16:49:07 +02:00
parent eef7ce3cfc
commit 77df17392c
8 changed files with 75 additions and 68 deletions

0
src/any_type.rs Normal file
View file

View file

@ -5,7 +5,7 @@ use std::{
}; };
use anyhow::Context; use anyhow::Context;
use once_cell::sync::{Lazy, OnceCell}; use once_cell::sync::Lazy;
use crate::global_tables::names::GNAMES; use crate::global_tables::names::GNAMES;

View file

@ -25,7 +25,7 @@ use crate::{
UObjectPropertyBaseTrait, UObjectTrait, UPropertyTrait, UStructNonConst, UObjectPropertyBaseTrait, UObjectTrait, UPropertyTrait, UStructNonConst,
UStructPropertyTrait, UStructTrait, UStructPropertyTrait, UStructTrait,
}, },
EFunctionFlags, EPropertyFlags, UBoolProperty, UClass, UEnum, UFunction, UObject, UStruct, EFunctionFlags, EPropertyFlags, UClass, UEnum, UFunction, UObject, UStruct,
}, },
}; };
@ -186,15 +186,6 @@ impl Package {
size: *strct.property_size() as u32, size: *strct.property_size() as u32,
super_class: super_struct, super_class: super_struct,
fields, fields,
min_alignment,
properties_size,
kind: if is_actor {
StructKind::Actor
} else if is_class {
StructKind::Object
} else {
StructKind::Struct
},
name, name,
methods, methods,
full_name, full_name,
@ -353,7 +344,6 @@ impl Package {
ClassField { ClassField {
offset: *prop.offset() as u32, offset: *prop.offset() as u32,
size: *prop.element_size() as u32, size: *prop.element_size() as u32,
flags: *prop.property_flags(),
name, name,
ty, ty,
}); });
@ -811,7 +801,6 @@ pub struct ClassField {
pub offset: u32, pub offset: u32,
pub size: u32, pub size: u32,
pub name: String, pub name: String,
pub flags: EPropertyFlags,
pub ty: Type, pub ty: Type,
} }
@ -853,24 +842,13 @@ pub struct Class {
pub name: String, pub name: String,
pub full_name: String, pub full_name: String,
pub super_class: Option<UStruct>, pub super_class: Option<UStruct>,
pub properties_size: u32,
pub min_alignment: u32,
pub kind: StructKind,
pub fields: Vec<ClassField>, pub fields: Vec<ClassField>,
pub methods: Vec<ClassMethod>, pub methods: Vec<ClassMethod>,
} }
impl Class { impl Class {
pub fn rust_name(&self) -> String { pub fn rust_name(&self) -> String {
format!( format!("U{}", canonicalize_name(&self.name))
"{}{}",
match self.kind {
StructKind::Object => "U",
StructKind::Actor => "A",
StructKind::Struct => "F",
},
canonicalize_name(&self.name)
)
} }
pub fn referenced_types(&self) -> Vec<UObject> { pub fn referenced_types(&self) -> Vec<UObject> {

View file

@ -12,7 +12,7 @@ use crate::{
Sdk, Type, Types, Sdk, Type, Types,
}, },
v2_types::{ v2_types::{
traits::{AsUObject, UBoolPropertyTrait, UObjectNonConst, UStructNonConst}, traits::{AsUObject, UObjectNonConst, UStructNonConst},
UObject, UObject,
}, },
}; };
@ -87,7 +87,7 @@ impl RustType for Type {
w, w,
"{}", "{}",
match ty { match ty {
PrimitiveType::Bool(_) => "bool", PrimitiveType::Bool { .. } => "bool",
PrimitiveType::U8 => "u8", PrimitiveType::U8 => "u8",
PrimitiveType::U16 => "u16", PrimitiveType::U16 => "u16",
PrimitiveType::U32 => "u32", PrimitiveType::U32 => "u32",
@ -298,13 +298,17 @@ pub fn generate_class_impl<W: Write>(class: &Class, sdk: &Sdk, w: &mut W) -> any
// need to handle bools in a special way because they might be bitfields // need to handle bools in a special way because they might be bitfields
match field.ty { match field.ty {
Type::Primitive(PrimitiveType::Bool(prop)) if *prop.byte_mask() != 0xff => { Type::Primitive(PrimitiveType::Bool {
byte_mask,
field_mask,
..
}) if byte_mask != 0xff => {
write!(w, "fn {}(&self) -> bool", field.name)?; write!(w, "fn {}(&self) -> bool", field.name)?;
writeln!( writeln!(
w, w,
" {{unsafe {{ *self.as_ptr().offset({}) & (1u8 << {}u8) != 0 }} }}", " {{unsafe {{ *self.as_ptr().offset({}) & (1u8 << {}u8) != 0 }} }}",
field.offset, field.offset,
prop.field_mask().trailing_zeros(), field_mask.trailing_zeros(),
)?; )?;
write!(w, "fn set_{0}(&mut self, {0}: bool", field.name)?; write!(w, "fn set_{0}(&mut self, {0}: bool", field.name)?;
@ -314,7 +318,7 @@ pub fn generate_class_impl<W: Write>(class: &Class, sdk: &Sdk, w: &mut W) -> any
" {{unsafe {{ if {1} {{ *self.as_mut_ptr().offset({0}) |= ({1} as u8) << {2}u8; }} else {{ *self.as_mut_ptr().offset({0}) &= !(({1} as u8) << {2}u8); }} }} }}", " {{unsafe {{ if {1} {{ *self.as_mut_ptr().offset({0}) |= ({1} as u8) << {2}u8; }} else {{ *self.as_mut_ptr().offset({0}) &= !(({1} as u8) << {2}u8); }} }} }}",
field.offset, field.offset,
field.name, field.name,
prop.field_mask().trailing_zeros(), field_mask.trailing_zeros(),
)?; )?;
} }
_ => { _ => {

View file

@ -1,12 +1,17 @@
use std::collections::{btree_map::Entry, BTreeMap}; use std::collections::{btree_map::Entry, BTreeMap};
use anyhow::Context; use anyhow::Context;
use itertools::Itertools;
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
use crate::sdk::repr::*;
use crate::v2_types::{ use crate::v2_types::{
any_type::{AnyField, AnyObject, AnyStruct}, any_type::{self, AnyField, AnyObject, AnyProperty, AnyStruct},
traits::{UEnumTrait, UObjectTrait, UPropertyTrait}, traits::{
UClass, UEnum, UFunction, UProperty, UScriptStruct, UStruct, AsUObject, UArrayPropertyTrait, UBoolPropertyTrait, UEnumPropertyTrait, UEnumTrait,
UObjectNonConst, UObjectTrait, UPropertyTrait, UStructPropertyTrait, *,
},
UClass, UEnum, UFunction, UProperty, UScriptStruct,
}; };
use super::repr::{ use super::repr::{
@ -50,16 +55,16 @@ impl Enum {
if values.len() > 1 { if values.len() > 1 {
acc.extend(values.into_iter().map(|i| (i as u32, format!("{name}{i}")))); acc.extend(values.into_iter().map(|i| (i as u32, format!("{name}{i}"))));
} else { } else {
acc.insert(values.into_iter().next().unwrap() as u32, name) acc.insert(values.into_iter().next().unwrap() as u32, name);
} }
acc acc
}); });
Ok(Enum { Ok(UnrealType::Enum(Enum {
name: value.name().get_name().context("could not get name")?, name: value.get_name().context("could not get name")?,
full_name: value.name().get_full_name().context("could not get name")?, full_name: value.get_full_name().context("could not get full name")?,
values, values,
}) }))
} }
} }
@ -149,26 +154,36 @@ fn resolve_type(prop: UProperty) -> anyhow::Result<Type> {
match object.as_any_object_base_property().unwrap() { match object.as_any_object_base_property().unwrap() {
any_type::AnyObjectBaseProperty::Object(obj) => Type::Class( any_type::AnyObjectBaseProperty::Object(obj) => Type::Class(
obj.property_class() obj.property_class()
.context("object property missing properry class")?, .context("object property missing properry class")?
.as_uobject()
.object_ref(),
), ),
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.")?
.as_uobject()
.object_ref(),
), ),
any_type::AnyObjectBaseProperty::LazyObject(obj) => Type::LazyPtr( any_type::AnyObjectBaseProperty::LazyObject(obj) => Type::LazyPtr(
obj.property_class() obj.property_class()
.context("lazy ptr property missing property class.")?, .context("lazy ptr property missing property class.")?
.as_uobject()
.object_ref(),
), ),
any_type::AnyObjectBaseProperty::SoftObject(obj) => Type::SoftPtr( any_type::AnyObjectBaseProperty::SoftObject(obj) => Type::SoftPtr(
obj.property_class() obj.property_class()
.context("soft ptr property missing property class.")?, .context("soft ptr property missing property class.")?
.as_uobject()
.object_ref(),
), ),
asset @ any_type::AnyObjectBaseProperty::AssetObject(_) => { asset @ any_type::AnyObjectBaseProperty::AssetObject(_) => {
match asset.as_any_asset_object_property().unwrap() { match asset.as_any_asset_object_property().unwrap() {
any_type::AnyAssetObjectProperty::Class(class) => Type::AssetPtr( any_type::AnyAssetObjectProperty::Class(class) => Type::AssetPtr(
class class
.property_class() .property_class()
.context("asset object property missing properry class")?, .context("asset object property missing properry class")?
.as_uobject()
.object_ref(),
), ),
any_type::AnyAssetObjectProperty::Object(_) => { any_type::AnyAssetObjectProperty::Object(_) => {
return Err(anyhow::anyhow!( return Err(anyhow::anyhow!(
@ -182,13 +197,11 @@ fn resolve_type(prop: UProperty) -> anyhow::Result<Type> {
} }
} }
} }
AnyProperty::Array(array) => { AnyProperty::Array(array) => Type::Array(Box::new(resolve_type(
Type::Array(Box::new(Self::find_type(AnyProperty::from_prop( array
array .inner()
.inner() .context("array property inner type missing.")?,
.context("array property inner type missing.")?, )?)),
))?))
}
AnyProperty::Map(_) => unreachable!("not used in ARK"), AnyProperty::Map(_) => unreachable!("not used in ARK"),
AnyProperty::Str(_) => Type::String, AnyProperty::Str(_) => Type::String,
AnyProperty::Text(_) => Type::Text, AnyProperty::Text(_) => Type::Text,
@ -200,16 +213,22 @@ fn resolve_type(prop: UProperty) -> anyhow::Result<Type> {
return Err(anyhow::anyhow!("skipping multicast delegates for now")); return Err(anyhow::anyhow!("skipping multicast delegates for now"));
} }
AnyProperty::Enum(enm) => Type::Enum { AnyProperty::Enum(enm) => Type::Enum {
underlying: Box::new(Self::find_type(AnyProperty::from_prop( underlying: Box::new(resolve_type(
enm.underlying_type() enm.underlying_type()
.context("enum property was missing underlying type")?, .context("enum property was missing underlying type")?,
))?), )?),
enum_type: enm.uenum().context("enum property missing enum type")?, enum_type: enm
.uenum()
.context("enum property missing enum type")?
.as_uobject()
.object_ref(),
}, },
AnyProperty::Struct(class) => Type::Struct( AnyProperty::Struct(class) => Type::Struct(
class class
.ustruct() .ustruct()
.context("struct property had no inner struct")?, .context("struct property had no inner struct")?
.as_uobject()
.object_ref(),
), ),
AnyProperty::Other(_) => { AnyProperty::Other(_) => {
return Err(anyhow::anyhow!("unhandled property.")); return Err(anyhow::anyhow!("unhandled property."));

View file

@ -1,4 +1,4 @@
use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::collections::BTreeMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -10,16 +10,16 @@ use crate::v2_types::{
impl UObject { impl UObject {
pub fn object_ref(&self) -> ObjectRef { pub fn object_ref(&self) -> ObjectRef {
ObjectRef { ObjectRef {
package: PackageRef(self.package_object().internal_index()), package: PackageRef(*self.package_object().internal_index()),
object: self.internal_index(), object: *self.internal_index(),
} }
} }
} }
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize, Deserialize)]
pub struct PackageRef(u32); pub struct PackageRef(u32);
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize, Deserialize)]
pub struct ObjectRef { pub struct ObjectRef {
package: PackageRef, package: PackageRef,
object: u32, object: u32,
@ -43,17 +43,17 @@ pub struct Package {
pub children: Vec<UObject>, pub children: Vec<UObject>,
} }
#[derive(Debug)] #[derive(Debug, Serialize, Deserialize)]
pub struct ProcessedPackage { pub struct ProcessedPackage {
/// the package object. /// the package object ref.
pub package_object: UObject, pub package_object: PackageRef,
/// all types extracted from this package referenced by their `ObjectRef`. /// all types extracted from this package referenced by their `ObjectRef`.
pub types: BTreeMap<ObjectRef, UnrealType>, pub types: BTreeMap<ObjectRef, UnrealType>,
/// All other packages that types in this package depend on directly. /// All other packages that types in this package depend on directly.
pub dependencies: Vec<ObjectRef>, pub dependencies: Vec<ObjectRef>,
} }
#[derive(Debug)] #[derive(Debug, Serialize, Deserialize)]
pub enum UnrealType { pub enum UnrealType {
Class(Class), Class(Class),
Struct(Class), Struct(Class),
@ -85,7 +85,7 @@ pub struct Class {
pub properties_size: u32, pub properties_size: u32,
pub min_alignment: u32, pub min_alignment: u32,
pub fields: Vec<ClassField>, pub fields: Vec<ClassField>,
pub methods: Vec<ClassMethods>, pub methods: Vec<ClassMethod>,
/// types this class depends on; includes super types, types of fields and /// types this class depends on; includes super types, types of fields and
/// types of function parameters. /// types of function parameters.
pub dependencies: Vec<ObjectRef>, pub dependencies: Vec<ObjectRef>,
@ -104,15 +104,22 @@ impl ClassField {
pub fn is_return_param(&self) -> bool { pub fn is_return_param(&self) -> bool {
self.flags.contains(EPropertyFlags::ReturnParm) self.flags.contains(EPropertyFlags::ReturnParm)
} }
pub fn is_param(&self) -> bool { pub fn is_param(&self) -> bool {
self.flags.contains(EPropertyFlags::Parm) self.flags.contains(EPropertyFlags::Parm)
} }
pub fn is_const_param(&self) -> bool { pub fn is_const_param(&self) -> bool {
self.flags.contains(EPropertyFlags::ConstParm) self.flags.contains(EPropertyFlags::ConstParm)
} }
pub fn is_out_param(&self) -> bool { pub fn is_out_param(&self) -> bool {
!self.is_const_param() && self.flags.contains(EPropertyFlags::OutParm) !self.is_const_param() && self.flags.contains(EPropertyFlags::OutParm)
} }
pub fn is_rep(&self) -> bool {
!self.flags.contains(EPropertyFlags::RepSkip)
}
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -121,7 +128,6 @@ pub struct ClassMethod {
pub full_name: String, pub full_name: String,
pub flags: EFunctionFlags, pub flags: EFunctionFlags,
pub parameters: Vec<ClassField>, pub parameters: Vec<ClassField>,
pub return_param: Option<ClassField>,
} }
impl ClassMethod { impl ClassMethod {
@ -150,7 +156,7 @@ impl ClassMethod {
} }
} }
#[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PrimitiveType { pub enum PrimitiveType {
Bool { Bool {
byte_mask: u8, byte_mask: u8,
@ -190,7 +196,7 @@ pub enum Type {
Text, Text,
Enum { Enum {
underlying: Box<Type>, underlying: Box<Type>,
enum_type: UEnum, enum_type: ObjectRef,
}, },
Class(ObjectRef), Class(ObjectRef),
Struct(ObjectRef), Struct(ObjectRef),

0
src/types.rs Normal file
View file

View file

@ -359,7 +359,7 @@ define_utypes!(
); );
impl Hash for UObject { impl Hash for UObject {
fn hash<H: ~const std::hash::Hasher>(&self, state: &mut H) { fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state); self.0.hash(state);
} }
} }