parsing classes, structs and enums
This commit is contained in:
parent
a574191066
commit
08149329e1
301
src/lib.rs
301
src/lib.rs
|
@ -23,6 +23,7 @@ pub mod sdk {
|
|||
|
||||
use anyhow::Context;
|
||||
use itertools::any;
|
||||
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
|
||||
|
||||
use crate::{
|
||||
global_tables::objects::{FindClass, GOBJECTS},
|
||||
|
@ -30,10 +31,12 @@ pub mod sdk {
|
|||
any_type::{self, AnyProperty},
|
||||
traits::{
|
||||
AsUObject, StaticClass, UArrayPropertyTrait, UBytePropertyTrait,
|
||||
UEnumPropertyTrait, UEnumTrait, UObjectNonConst, UObjectPropertyBaseTrait,
|
||||
UObjectTrait, UPropertyTrait, UStructNonConst, UStructPropertyTrait, UStructTrait,
|
||||
UEnumPropertyTrait, UEnumTrait, UFunctionTrait, UObjectNonConst,
|
||||
UObjectPropertyBaseTrait, UObjectTrait, UPropertyTrait, UStructNonConst,
|
||||
UStructPropertyTrait, UStructTrait,
|
||||
},
|
||||
AnyProp, UAnyType, UClass, UEnum, UObject, UProperty, UScriptStruct, UStruct,
|
||||
AnyProp, EFunctionFlags, EPropertyFlags, UAnyType, UClass, UEnum, UFunction, UObject,
|
||||
UProperty, UScriptStruct, UStruct,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -93,6 +96,13 @@ pub mod sdk {
|
|||
dependencies: Vec<UObject>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ProcessedPackage {
|
||||
pub package: UObject,
|
||||
pub types: HashMap<UObject, Types>,
|
||||
pub package_dependencies: Vec<UObject>,
|
||||
}
|
||||
|
||||
impl<'a> Package<'a> {
|
||||
pub fn new(sdk: &'a Sdk, package: UObject, objects: Vec<UObject>) -> Self {
|
||||
Self {
|
||||
|
@ -103,57 +113,60 @@ pub mod sdk {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn process(&self) -> anyhow::Result<()> {
|
||||
for object in self.objects.iter() {
|
||||
self.sdk
|
||||
.cache
|
||||
.cache_class(object.class().expect("object had no class?"))
|
||||
.context("object not of any base type?")?;
|
||||
pub fn process(self) -> ProcessedPackage {
|
||||
let types = self
|
||||
.objects
|
||||
.par_iter()
|
||||
.filter_map(|&object| {
|
||||
let ty = UAnyType::from_uobject(object.as_uobject());
|
||||
log::trace!("ty: {ty:?}");
|
||||
|
||||
let ty = UAnyType::from_uobject(object.as_uobject());
|
||||
log::trace!("ty: {ty:?}");
|
||||
match ty {
|
||||
UAnyType::UClass(class) => {
|
||||
if let Ok(class) = self.process_struct(unsafe { class.cast() }) {
|
||||
return Some((object, Types::Class(class)));
|
||||
}
|
||||
}
|
||||
UAnyType::UScriptStruct(class) => {
|
||||
if let Ok(class) = self.process_struct(unsafe { class.cast() }) {
|
||||
return Some((object, Types::Class(class)));
|
||||
}
|
||||
}
|
||||
UAnyType::UEnum(obj) => {
|
||||
if let Ok(enm) = Self::process_enum(obj) {
|
||||
return Some((object, Types::Enum(enm)));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
match ty {
|
||||
UAnyType::UClass(class) => {
|
||||
let _ = self.process_struct(unsafe { class.cast() });
|
||||
}
|
||||
UAnyType::UScriptStruct(class) => {
|
||||
let _ = self.process_struct(unsafe { class.cast() });
|
||||
}
|
||||
UAnyType::UEnum(obj) => {
|
||||
let enm = Self::process_enum(obj)?;
|
||||
log::info!("enum: {enm}");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
ProcessedPackage {
|
||||
package: self.package,
|
||||
types,
|
||||
package_dependencies: self.dependencies,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_struct(&self, strct: UStruct) -> anyhow::Result<()> {
|
||||
fn process_struct(&self, strct: UStruct) -> anyhow::Result<Class> {
|
||||
let name = strct
|
||||
.get_name()
|
||||
.context("failed to get struct or class name")?;
|
||||
let is_struct = strct.is_a(&UScriptStruct::static_class().unwrap());
|
||||
let is_class = strct.is_a(&UClass::static_class().unwrap());
|
||||
if !(is_struct || is_class) {
|
||||
// TODO: skip anything that isnt a struct or class
|
||||
log::info!("skipping {strct:?} as its not a struct or class");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if strct.package_object() != self.package {
|
||||
log::info!("encountered external dependency");
|
||||
// TODO: return dependency on strct.package_object()
|
||||
} else {
|
||||
// process outers for classes
|
||||
if !is_struct {
|
||||
if let Some(outer) = strct.outer() {
|
||||
if outer.is_a(&UStruct::static_class().unwrap()) {
|
||||
self.process_struct(unsafe { outer.cast() })?;
|
||||
}
|
||||
// process outers for classes
|
||||
if !is_struct {
|
||||
if let Some(outer) = strct.outer() {
|
||||
if outer.is_a(&UStruct::static_class().unwrap()) {
|
||||
// depend on this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let super_struct = if let Some(spr) = *strct.super_field() && spr != strct {
|
||||
let super_struct = if let Some(spr) = *strct.super_field() && spr != strct {
|
||||
if spr.package_object() != self.package {
|
||||
log::info!("encountered external dependency");
|
||||
// TODO: return dependency on strct.package_object()
|
||||
|
@ -161,38 +174,41 @@ pub mod sdk {
|
|||
Some(spr)
|
||||
} else {None};
|
||||
|
||||
self.process_children(strct)?;
|
||||
}
|
||||
let (fields, methods) = self.process_children(strct)?;
|
||||
|
||||
Ok(())
|
||||
Ok(Class {
|
||||
is_class,
|
||||
name,
|
||||
super_class: super_struct,
|
||||
fields,
|
||||
methods,
|
||||
})
|
||||
}
|
||||
|
||||
fn find_type(prop: AnyProperty) -> anyhow::Result<Type> {
|
||||
let ty = match prop {
|
||||
let ty = match prop.clone() {
|
||||
numeric @ AnyProperty::Numeric(_) => {
|
||||
Type::Primitive(match numeric.as_any_numeric_property().unwrap() {
|
||||
match numeric.as_any_numeric_property().unwrap() {
|
||||
any_type::AnyNumericProperty::U8(prop) => match prop.uenum() {
|
||||
Some(enm) => {
|
||||
return Ok(Type::Enum {
|
||||
underlying: Box::new(Type::Primitive(PrimitiveType::U8)),
|
||||
enum_type: *enm,
|
||||
})
|
||||
}
|
||||
None => PrimitiveType::U8,
|
||||
Some(enm) => Type::Enum {
|
||||
underlying: Box::new(Type::Primitive(PrimitiveType::U8)),
|
||||
enum_type: *enm,
|
||||
},
|
||||
None => Type::Primitive(PrimitiveType::U8),
|
||||
},
|
||||
any_type::AnyNumericProperty::U16(_) => PrimitiveType::U16,
|
||||
any_type::AnyNumericProperty::U32(_) => PrimitiveType::U32,
|
||||
any_type::AnyNumericProperty::U64(_) => PrimitiveType::U64,
|
||||
any_type::AnyNumericProperty::I8(_) => PrimitiveType::I8,
|
||||
any_type::AnyNumericProperty::I16(_) => PrimitiveType::I16,
|
||||
any_type::AnyNumericProperty::I32(_) => PrimitiveType::I32,
|
||||
any_type::AnyNumericProperty::I64(_) => PrimitiveType::I64,
|
||||
any_type::AnyNumericProperty::F32(_) => PrimitiveType::F32,
|
||||
any_type::AnyNumericProperty::F64(_) => PrimitiveType::F64,
|
||||
any_type::AnyNumericProperty::U16(_) => Type::Primitive(PrimitiveType::U16),
|
||||
any_type::AnyNumericProperty::U32(_) => Type::Primitive(PrimitiveType::U32),
|
||||
any_type::AnyNumericProperty::U64(_) => Type::Primitive(PrimitiveType::U64),
|
||||
any_type::AnyNumericProperty::I8(_) => Type::Primitive(PrimitiveType::I8),
|
||||
any_type::AnyNumericProperty::I16(_) => Type::Primitive(PrimitiveType::I16),
|
||||
any_type::AnyNumericProperty::I32(_) => Type::Primitive(PrimitiveType::I32),
|
||||
any_type::AnyNumericProperty::I64(_) => Type::Primitive(PrimitiveType::I64),
|
||||
any_type::AnyNumericProperty::F32(_) => Type::Primitive(PrimitiveType::F32),
|
||||
any_type::AnyNumericProperty::F64(_) => Type::Primitive(PrimitiveType::F64),
|
||||
any_type::AnyNumericProperty::Other(_) => {
|
||||
return Err(anyhow::anyhow!("unhandled numeric property"));
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
AnyProperty::Bool(_) => Type::Primitive(PrimitiveType::Bool),
|
||||
AnyProperty::Interface(_) => {
|
||||
|
@ -273,13 +289,24 @@ pub mod sdk {
|
|||
}
|
||||
};
|
||||
|
||||
Ok(ty)
|
||||
if *prop.array_dim() > 1 {
|
||||
Ok(Type::RawArray {
|
||||
ty: Box::new(ty),
|
||||
len: *prop.array_dim() as u32,
|
||||
})
|
||||
} else {
|
||||
Ok(ty)
|
||||
}
|
||||
}
|
||||
|
||||
fn process_children(&self, strct: UStruct) -> anyhow::Result<Vec<ClassField>> {
|
||||
fn process_children(
|
||||
&self,
|
||||
strct: UStruct,
|
||||
) -> anyhow::Result<(Vec<ClassField>, Vec<ClassMethod>)> {
|
||||
log::info!("{} children:", strct.get_full_name_or_default());
|
||||
|
||||
let mut fields = Vec::new();
|
||||
let mut methods = Vec::new();
|
||||
|
||||
for child in strct
|
||||
.iter_children()
|
||||
|
@ -306,14 +333,87 @@ pub mod sdk {
|
|||
strt @ any_type::AnyField::Struct(_) if let Some(any_type::AnyStruct::Function(func)) = strt.as_any_struct() => {
|
||||
log::info!("function: {func}");
|
||||
|
||||
// TODO: methods
|
||||
if let Ok(method) = Self::process_function(func) {
|
||||
methods.push(method);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(fields)
|
||||
Ok((fields, methods))
|
||||
}
|
||||
|
||||
fn process_function(func: UFunction) -> anyhow::Result<ClassMethod> {
|
||||
let full_name = func
|
||||
.get_full_name()
|
||||
.context("could not get full function name")?;
|
||||
let rust_name =
|
||||
canonicalize_name(&func.get_name().context("could not get function name")?)
|
||||
.to_string();
|
||||
|
||||
let is_static = func.function_flags().contains(EFunctionFlags::Static);
|
||||
let is_native = func.function_flags().contains(EFunctionFlags::Native);
|
||||
|
||||
let mut params = Vec::new();
|
||||
let mut return_types = Vec::new();
|
||||
|
||||
for child in func
|
||||
.iter_children()
|
||||
.map(|field| any_type::AnyField::from_field(field))
|
||||
{
|
||||
match child {
|
||||
any_type::AnyField::Property(prop) => {
|
||||
match Self::find_type(any_type::AnyProperty::from_prop(prop)) {
|
||||
Ok(ty) => {
|
||||
log::info!("field: {ty:?}: {prop}");
|
||||
if let Some(kind) = if prop
|
||||
.property_flags()
|
||||
.contains(EPropertyFlags::ReturnParm)
|
||||
{
|
||||
Some(ParameterKind::Return)
|
||||
} else if prop.property_flags().contains(EPropertyFlags::OutParm) {
|
||||
if prop.property_flags().contains(EPropertyFlags::ConstParm) {
|
||||
Some(ParameterKind::Default)
|
||||
} else {
|
||||
Some(ParameterKind::Out)
|
||||
}
|
||||
} else if prop.property_flags().contains(EPropertyFlags::Parm) {
|
||||
Some(ParameterKind::Default)
|
||||
} else {
|
||||
None
|
||||
} {
|
||||
match kind {
|
||||
ParameterKind::Return => {
|
||||
return_types.push(ty);
|
||||
}
|
||||
ParameterKind::Default => {
|
||||
params.push(MethodParameter { ty, is_out: false });
|
||||
}
|
||||
ParameterKind::Out => {
|
||||
params.push(MethodParameter { ty, is_out: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("skipping field with offset {}: {e}", prop.offset());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ClassMethod {
|
||||
name: rust_name,
|
||||
parameters: params,
|
||||
return_type: return_types.into_iter().next(),
|
||||
full_name,
|
||||
is_native,
|
||||
is_static,
|
||||
})
|
||||
}
|
||||
|
||||
fn process_enum(enm: UEnum) -> anyhow::Result<Enum> {
|
||||
|
@ -527,7 +627,7 @@ pub mod sdk {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum PrimitiveType {
|
||||
pub enum PrimitiveType {
|
||||
Bool,
|
||||
U8,
|
||||
U16,
|
||||
|
@ -542,7 +642,7 @@ pub mod sdk {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Type {
|
||||
pub enum Type {
|
||||
Ptr(Box<Type>),
|
||||
Ref(Box<Type>),
|
||||
WeakPtr(UClass),
|
||||
|
@ -551,6 +651,10 @@ pub mod sdk {
|
|||
AssetPtr(UClass),
|
||||
Array(Box<Type>),
|
||||
Primitive(PrimitiveType),
|
||||
RawArray {
|
||||
ty: Box<Type>,
|
||||
len: u32,
|
||||
},
|
||||
Name,
|
||||
String,
|
||||
Text,
|
||||
|
@ -562,31 +666,54 @@ pub mod sdk {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ClassField {
|
||||
offset: u32,
|
||||
size: u32,
|
||||
name: String,
|
||||
ty: Type,
|
||||
pub struct ClassField {
|
||||
pub offset: u32,
|
||||
pub size: u32,
|
||||
pub name: String,
|
||||
pub ty: Type,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ClassMethod {
|
||||
offset: u32,
|
||||
size: u32,
|
||||
name: String,
|
||||
pub struct MethodParameter {
|
||||
pub ty: Type,
|
||||
pub is_out: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Class {
|
||||
is_class: bool,
|
||||
name: String,
|
||||
fields: Vec<ClassField>,
|
||||
pub struct ClassMethod {
|
||||
pub name: String,
|
||||
pub full_name: String,
|
||||
pub is_native: bool,
|
||||
pub is_static: bool,
|
||||
pub parameters: Vec<MethodParameter>,
|
||||
pub return_type: Option<Type>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Enum {
|
||||
name: String,
|
||||
values: Vec<String>,
|
||||
pub struct Class {
|
||||
pub is_class: bool,
|
||||
pub name: String,
|
||||
pub super_class: Option<UStruct>,
|
||||
pub fields: Vec<ClassField>,
|
||||
pub methods: Vec<ClassMethod>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Types {
|
||||
Class(Class),
|
||||
Enum(Enum),
|
||||
}
|
||||
|
||||
enum ParameterKind {
|
||||
Return,
|
||||
Default,
|
||||
Out,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Enum {
|
||||
pub name: String,
|
||||
pub values: Vec<String>,
|
||||
}
|
||||
|
||||
impl Display for Enum {
|
||||
|
|
|
@ -516,6 +516,8 @@ impl<'a> Iterator for ChildIter<'a> {
|
|||
pub enum UAnyType {
|
||||
UObject(UObject),
|
||||
UClass(UClass),
|
||||
UProperty(UProperty),
|
||||
UFunction(UFunction),
|
||||
UField(UField),
|
||||
UScriptStruct(UScriptStruct),
|
||||
UEnum(UEnum),
|
||||
|
@ -547,6 +549,147 @@ impl UAnyType {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum AnyNumericProp {
|
||||
U8(UByteProperty),
|
||||
U16(UUInt16Property),
|
||||
U32(UUInt32Property),
|
||||
U64(UUInt64Property),
|
||||
I8(UInt8Property),
|
||||
I16(UInt16Property),
|
||||
I32(UIntProperty),
|
||||
I64(UInt64Property),
|
||||
F32(UFloatProperty),
|
||||
F64(UDoubleProperty),
|
||||
Other(UNumericProperty),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum AnyObjectProp {
|
||||
Object(UObjectProperty),
|
||||
Class(UClassProperty),
|
||||
Interface(UInterfaceProperty),
|
||||
WeakObject(UWeakObjectProperty),
|
||||
LazyObject(UWeakObjectProperty),
|
||||
SoftObject(UWeakObjectProperty),
|
||||
AssetObject(UAssetObjectProperty),
|
||||
AssetClass(UAssetClassProperty),
|
||||
Other(UObjectPropertyBase),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum AnyDelegateProp {
|
||||
Delegate(UDelegateProperty),
|
||||
MulticastDelegate(UMulticastDelegateProperty),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum AnyContainerProp {
|
||||
Array(UArrayProperty),
|
||||
Map(UMapProperty),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum AnyProp {
|
||||
Numeric(AnyNumericProp),
|
||||
Bool(UBoolProperty),
|
||||
ObjectBase(AnyObjectProp),
|
||||
Container(AnyContainerProp),
|
||||
Str(UStrProperty),
|
||||
Text(UTextProperty),
|
||||
Name(UNameProperty),
|
||||
Delegate(AnyDelegateProp),
|
||||
Enum(UEnumProperty),
|
||||
Struct(UStructProperty),
|
||||
Function(UFunction),
|
||||
Other(UProperty),
|
||||
}
|
||||
|
||||
impl AnyNumericProp {
|
||||
fn from_uprop(prop: UNumericProperty) -> Self {
|
||||
if prop.is_a_maybe(&UByteProperty::static_class()) {
|
||||
Self::U8(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UUInt16Property::static_class()) {
|
||||
Self::U16(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UUInt32Property::static_class()) {
|
||||
Self::U32(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UUInt64Property::static_class()) {
|
||||
Self::U64(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UInt8Property::static_class()) {
|
||||
Self::I8(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UInt16Property::static_class()) {
|
||||
Self::I16(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UIntProperty::static_class()) {
|
||||
Self::I32(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UInt64Property::static_class()) {
|
||||
Self::I64(unsafe { prop.cast() })
|
||||
} else {
|
||||
Self::Other(prop)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AnyObjectProp {
|
||||
fn from_uprop(prop: UObjectPropertyBase) -> Self {
|
||||
if prop.is_a_maybe(&UInterfaceProperty::static_class()) {
|
||||
Self::Interface(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UAssetClassProperty::static_class()) {
|
||||
Self::AssetClass(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UAssetObjectProperty::static_class()) {
|
||||
Self::AssetObject(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UWeakObjectProperty::static_class()) {
|
||||
Self::WeakObject(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&ULazyObjectProperty::static_class()) {
|
||||
Self::LazyObject(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&USoftObjectProperty::static_class()) {
|
||||
Self::SoftObject(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UClassProperty::static_class()) {
|
||||
Self::Class(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UObjectProperty::static_class()) {
|
||||
Self::Object(unsafe { prop.cast() })
|
||||
} else {
|
||||
Self::Other(prop)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AnyProp {
|
||||
pub fn from_uprop(prop: UProperty) -> Self {
|
||||
if prop.is_a_maybe(&UNumericProperty::static_class()) {
|
||||
Self::Numeric(AnyNumericProp::from_uprop(unsafe { prop.cast() }))
|
||||
} else if prop.is_a_maybe(&UBoolProperty::static_class()) {
|
||||
Self::Bool(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UObjectPropertyBase::static_class()) {
|
||||
Self::ObjectBase(AnyObjectProp::from_uprop(unsafe { prop.cast() }))
|
||||
} else if prop.is_a_maybe(&UArrayProperty::static_class()) {
|
||||
Self::Container(AnyContainerProp::Array(unsafe { prop.cast() }))
|
||||
} else if prop.is_a_maybe(&UMapProperty::static_class()) {
|
||||
Self::Container(AnyContainerProp::Map(unsafe { prop.cast() }))
|
||||
} else if prop.is_a_maybe(&UDelegateProperty::static_class()) {
|
||||
Self::Delegate(AnyDelegateProp::Delegate(unsafe { prop.cast() }))
|
||||
} else if prop.is_a_maybe(&UMulticastDelegateProperty::static_class()) {
|
||||
Self::Delegate(AnyDelegateProp::MulticastDelegate(unsafe { prop.cast() }))
|
||||
} else if prop.is_a_maybe(&UStrProperty::static_class()) {
|
||||
Self::Str(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UNameProperty::static_class()) {
|
||||
Self::Name(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UTextProperty::static_class()) {
|
||||
Self::Text(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UStructProperty::static_class()) {
|
||||
Self::Struct(unsafe { prop.cast() })
|
||||
} else if prop.is_a_maybe(&UEnumProperty::static_class()) {
|
||||
Self::Enum(unsafe { prop.cast() })
|
||||
} else {
|
||||
Self::Other(prop)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsUObject for UAnyType {
|
||||
fn as_uobject(&self) -> self::UObject {
|
||||
match self {
|
||||
|
@ -556,6 +699,8 @@ impl AsUObject for UAnyType {
|
|||
UAnyType::UScriptStruct(obj) => obj.as_uobject(),
|
||||
UAnyType::UEnum(obj) => obj.as_uobject(),
|
||||
UAnyType::UStruct(obj) => obj.as_uobject(),
|
||||
UAnyType::UProperty(obj) => obj.as_uobject(),
|
||||
UAnyType::UFunction(obj) => obj.as_uobject(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue