serialization of UStructs/UClasses/AActors
This commit is contained in:
parent
e74ed77703
commit
47dbb8e3d1
|
@ -1,3 +1,4 @@
|
||||||
|
use std::collections::BTreeSet;
|
||||||
use std::collections::{btree_map::Entry, BTreeMap};
|
use std::collections::{btree_map::Entry, BTreeMap};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
@ -11,8 +12,9 @@ use crate::v2_types::{
|
||||||
AsUObject, UArrayPropertyTrait, UBoolPropertyTrait, UEnumPropertyTrait, UEnumTrait,
|
AsUObject, UArrayPropertyTrait, UBoolPropertyTrait, UEnumPropertyTrait, UEnumTrait,
|
||||||
UObjectNonConst, UObjectTrait, UPropertyTrait, UStructPropertyTrait, *,
|
UObjectNonConst, UObjectTrait, UPropertyTrait, UStructPropertyTrait, *,
|
||||||
},
|
},
|
||||||
UClass, UEnum, UFunction, UProperty, UScriptStruct,
|
UClass, UEnum, UFunction, UProperty,
|
||||||
};
|
};
|
||||||
|
use crate::v2_types::{UScriptStruct, UStruct};
|
||||||
|
|
||||||
use super::repr::{
|
use super::repr::{
|
||||||
Class, ClassField, ClassMethod, Enum, Package, ProcessedPackage, Type, UnrealType,
|
Class, ClassField, ClassMethod, Enum, Package, ProcessedPackage, Type, UnrealType,
|
||||||
|
@ -61,6 +63,7 @@ impl Enum {
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(UnrealType::Enum(Enum {
|
Ok(UnrealType::Enum(Enum {
|
||||||
|
obj_ref: value.as_uobject().object_ref(),
|
||||||
name: value.get_name().context("could not get name")?,
|
name: value.get_name().context("could not get name")?,
|
||||||
full_name: value.get_full_name().context("could not get full name")?,
|
full_name: value.get_full_name().context("could not get full name")?,
|
||||||
values,
|
values,
|
||||||
|
@ -69,11 +72,107 @@ impl Enum {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Class {
|
impl Class {
|
||||||
pub fn from_uclass(value: UClass) -> anyhow::Result<UnrealType> {
|
pub fn from_uclass(class: UClass) -> anyhow::Result<UnrealType> {
|
||||||
todo!()
|
Ok(UnrealType::Class(Self {
|
||||||
|
kind: StructKind::Object,
|
||||||
|
..Self::from_struct_inner(unsafe { class.cast() })?
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
pub fn from_uscriptstruct(value: UScriptStruct) -> anyhow::Result<UnrealType> {
|
|
||||||
todo!()
|
pub fn from_actor(class: UClass) -> anyhow::Result<UnrealType> {
|
||||||
|
Ok(UnrealType::Actor(Self {
|
||||||
|
kind: StructKind::Actor,
|
||||||
|
..Self::from_struct_inner(unsafe { class.cast() })?
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_struct(strct: UScriptStruct) -> anyhow::Result<UnrealType> {
|
||||||
|
Ok(UnrealType::Struct(Self {
|
||||||
|
kind: StructKind::Struct,
|
||||||
|
..Self::from_struct_inner(unsafe { strct.cast() })?
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_struct_inner(strct: UStruct) -> anyhow::Result<Self> {
|
||||||
|
let name = strct.get_name().context("could not get function name")?;
|
||||||
|
let full_name = strct
|
||||||
|
.get_full_name()
|
||||||
|
.context("could not get full function name")?;
|
||||||
|
|
||||||
|
let super_class = strct.super_field().and_then(|supr| {
|
||||||
|
if supr != strct {
|
||||||
|
Some(supr.as_uobject().object_ref())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let (fields, methods) = Self::process_children(&strct)?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
obj_ref: strct.as_uobject().object_ref(),
|
||||||
|
kind: StructKind::Struct,
|
||||||
|
size: *strct.property_size() as u32,
|
||||||
|
name,
|
||||||
|
full_name,
|
||||||
|
super_class,
|
||||||
|
properties_size: *strct.property_size() as u32,
|
||||||
|
min_alignment: *strct.min_alignment() as u32,
|
||||||
|
fields,
|
||||||
|
methods,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns tuple of (fields, methods)
|
||||||
|
fn process_children(strct: &UStruct) -> anyhow::Result<(Vec<ClassField>, Vec<ClassMethod>)> {
|
||||||
|
enum ClassChild {
|
||||||
|
Field(ClassField),
|
||||||
|
Method(ClassMethod),
|
||||||
|
}
|
||||||
|
|
||||||
|
let (fields, methods) = strct
|
||||||
|
.iter_children()
|
||||||
|
.map(|field| -> anyhow::Result<Option<ClassChild>> {
|
||||||
|
let child = match any_type::AnyField::from_field(field) {
|
||||||
|
AnyField::Property(prop) => Some(ClassChild::Field(ClassField::from_uprop(prop)?)),
|
||||||
|
AnyField::Struct(strct)
|
||||||
|
if let AnyStruct::Function(func) = AnyStruct::from_struct(strct) => {
|
||||||
|
{
|
||||||
|
Some(ClassChild::Method(ClassMethod::from_ufunction(func)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(child)
|
||||||
|
})
|
||||||
|
.fold_ok(
|
||||||
|
(Vec::new(), Vec::new()),
|
||||||
|
|(mut fields, mut methods), child| {
|
||||||
|
if let Some(child) = child {
|
||||||
|
match child {
|
||||||
|
ClassChild::Field(field) => fields.push(field),
|
||||||
|
ClassChild::Method(method) => methods.push(method),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(fields, methods)
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok((fields, methods))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_dependent_types(&self) -> Vec<ObjectRef> {
|
||||||
|
self.fields
|
||||||
|
.iter()
|
||||||
|
.filter_map(|field| field.ty.dependent_type())
|
||||||
|
.chain(
|
||||||
|
self.methods
|
||||||
|
.iter()
|
||||||
|
.flat_map(|method| method.get_dependent_types()),
|
||||||
|
)
|
||||||
|
.chain(self.super_class)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +189,10 @@ impl ClassField {
|
||||||
ty: resolve_type(prop).context("failed to get field type")?,
|
ty: resolve_type(prop).context("failed to get field type")?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_dependent_types(&self) -> Vec<ObjectRef> {
|
||||||
|
self.ty.dependent_type().into_iter().collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClassMethod {
|
impl ClassMethod {
|
||||||
|
@ -115,6 +218,13 @@ impl ClassMethod {
|
||||||
parameters: params,
|
parameters: params,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_dependent_types(&self) -> Vec<ObjectRef> {
|
||||||
|
self.parameters
|
||||||
|
.iter()
|
||||||
|
.filter_map(|field| field.ty.dependent_type())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Package {
|
impl Package {
|
||||||
|
|
Loading…
Reference in a new issue