removed old files/modules

This commit is contained in:
Janis 2023-05-23 09:52:06 +02:00
parent b1bf442a27
commit 4af21ba271
3 changed files with 16 additions and 889 deletions

View file

@ -1,231 +0,0 @@
#![allow(non_upper_case_globals)]
use crate::tarray::{FString, TArray};
use bitflags::bitflags;
use std::ptr::NonNull;
#[derive(Debug)]
#[repr(transparent)]
pub struct VTbl(NonNull<()>);
impl VTbl {}
bitflags! {
#[repr(C)]
pub struct EObjectFlags: u32 {
const RF_NoFlags = 0x00000000;
const RF_Public = 0x00000001;
const RF_Standalone = 0x00000002;
const RF_MarkAsNative = 0x00000004;
const RF_Transactional = 0x00000008;
const RF_ClassDefaultObject = 0x00000010;
const RF_ArchetypeObject = 0x00000020;
const RF_Transient = 0x00000040;
const RF_MarkAsRootSet = 0x00000080;
const RF_TagGarbageTemp = 0x00000100;
const RF_NeedInitialization = 0x00000200;
const RF_NeedLoad = 0x00000400;
const RF_KeepForCooker = 0x00000800;
const RF_NeedPostLoad = 0x00001000;
const RF_NeedPostLoadSubobjects = 0x00002000;
const RF_NewerVersionExists = 0x00004000;
const RF_BeginDestroyed = 0x00008000;
const RF_FinishDestroyed = 0x00010000;
const RF_BeingRegenerated = 0x00020000;
const RF_DefaultSubObject = 0x00040000;
const RF_WasLoaded = 0x00080000;
const RF_TextExportTransient = 0x00100000;
const RF_LoadCompleted = 0x00200000;
const RF_InheritableComponentTemplate = 0x00400000;
const RF_DuplicateTransient = 0x00800000;
const RF_StrongRefOnFrame = 0x01000000;
const RF_NonPIEDuplicateTransient = 0x02000000;
const RF_Dynamic = 0x04000000;
const RF_WillBeLoaded = 0x08000000;
const RF_HasExternalPackage = 0x10000000;
}
}
use crate::global_tables::names::GNAMES;
#[repr(C)]
#[derive(Debug)]
pub struct UObject {
pub vtbl: VTbl,
pub object_flags: EObjectFlags, //EObjectFlags,
pub internal_index: u32,
pub class: Option<NonNull<UClass>>,
pub name: FName,
pub outer: Option<NonNull<UObject>>,
}
#[repr(C)]
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
pub struct FName {
pub comparison_index: u32,
pub number: u32,
}
impl FName {
pub fn get_name(&self) -> anyhow::Result<String> {
GNAMES
.read()
.unwrap()
.as_names()
.unwrap()
.fname_to_string(self)
}
}
#[repr(C)]
#[derive(Debug)]
pub struct UField {
pub uobject: UObject,
pub next: Option<NonNull<UField>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UEnum {
pub ufield: UField,
pub cpp_type: FString,
pub names: TArray<FName>,
pub cpp_form: u32,
}
#[repr(C)]
#[derive(Debug)]
pub struct UStruct {
pub(crate) ufield: UField,
pub(crate) super_field: Option<NonNull<UStruct>>,
pub(crate) children: Option<NonNull<UField>>,
pub(crate) property_size: u32,
pub(crate) min_alignment: u32,
padding1: [u8; 0x48],
}
#[repr(C)]
#[derive(Debug)]
pub struct UClass {
pub(crate) ustruct: UStruct,
padding1: [u8; 0xF8],
}
#[repr(C)]
#[derive(Debug)]
pub struct UProperty {
pub(crate) ufield: UField,
array_dim: i32,
element_size: i32,
property_flags: u64,
rep_index: i16,
rep_notify_function: FName,
offset: i32,
property_link_next: Option<NonNull<UProperty>>,
next_ref: Option<NonNull<UProperty>>,
destructor_link_next: Option<NonNull<UProperty>>,
post_construct_link_next: Option<NonNull<UProperty>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UByteProperty {
pub(crate) uproperty: UProperty,
uenum: Option<NonNull<UEnum>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UBoolProperty {
pub(crate) uproperty: UProperty,
field_size: u8,
byte_offset: u8,
byte_mask: u8,
field_mask: u8,
}
#[repr(C)]
#[derive(Debug)]
pub struct UObjectProperty {
pub(crate) uproperty: UProperty,
property_class: Option<NonNull<UClass>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UClassProperty {
pub(crate) uobjectproperty: UObjectProperty,
meta_class: Option<NonNull<UClass>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UAssetClassProperty {
pub(crate) uobjectproperty: UObjectProperty,
meta_class: Option<NonNull<UClass>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UInterfaceProperty {
pub(crate) uproperty: UProperty,
interface_class: Option<NonNull<UClass>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UStructProperty {
pub(crate) uproperty: UProperty,
ustruct: Option<NonNull<UStruct>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UArrayProperty {
pub(crate) uproperty: UProperty,
inner: Option<NonNull<UProperty>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UMapProperty {
pub(crate) uproperty: UProperty,
key_prop: Option<NonNull<UProperty>>,
value_prop: Option<NonNull<UProperty>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UDelegateProperty {
pub(crate) uproperty: UProperty,
signature_function: Option<NonNull<UFunction>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UMulticastDelegateProperty {
pub(crate) uproperty: UProperty,
signature_function: Option<NonNull<UFunction>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UEnumProperty {
pub(crate) uproperty: UProperty,
underlying_type: Option<NonNull<UProperty>>,
uenum: Option<NonNull<UEnum>>,
}
#[repr(C)]
#[derive(Debug)]
pub struct UFunction {
pub(crate) ustruct: UStruct,
function_flags: u32,
rep_offset: u16,
num_params: u8,
params_size: u16,
return_value_offset: u16,
rpc_id: u16,
rpc_response_id: u16,
first_property_to_init: Option<NonNull<UProperty>>,
function: Option<NonNull<()>>,
}

View file

@ -7,12 +7,10 @@
if_let_guard if_let_guard
)] )]
// mod core_types;
pub mod fname; pub mod fname;
pub mod global_tables; pub mod global_tables;
pub mod helper_types; pub mod helper_types;
pub mod tarray; pub mod tarray;
// pub mod types;
pub mod v2_types; pub mod v2_types;
pub mod sdk { pub mod sdk {
@ -34,10 +32,10 @@ pub mod sdk {
actor_static_class, actor_static_class,
any_type::{self, AnyField, AnyObject, AnyProperty, AnyStruct}, any_type::{self, AnyField, AnyObject, AnyProperty, AnyStruct},
traits::{ traits::{
AsUObject, StaticClass, UArrayPropertyTrait, UBoolPropertyTrait, AsUObject, StaticClass, UArrayPropertyTrait, UBytePropertyTrait,
UBytePropertyTrait, UEnumPropertyTrait, UEnumTrait, UFunctionTrait, UEnumPropertyTrait, UEnumTrait, UFunctionTrait, UObjectNonConst,
UObjectNonConst, UObjectPropertyBaseTrait, UObjectTrait, UPropertyTrait, UObjectPropertyBaseTrait, UObjectTrait, UPropertyTrait, UStructNonConst,
UStructNonConst, UStructPropertyTrait, UStructTrait, UStructPropertyTrait, UStructTrait,
}, },
EFunctionFlags, EPropertyFlags, UBoolProperty, UClass, UEnum, UFunction, UObject, EFunctionFlags, EPropertyFlags, UBoolProperty, UClass, UEnum, UFunction, UObject,
UStruct, UStruct,
@ -431,6 +429,7 @@ pub mod sdk {
) )
), ),
ty, ty,
flags: *prop.property_flags(),
}; };
let param = if prop let param = if prop
@ -469,6 +468,7 @@ pub mod sdk {
full_name, full_name,
is_native, is_native,
is_static, is_static,
flags: *func.function_flags(),
}) })
} }
@ -805,6 +805,14 @@ pub mod sdk {
} }
} }
#[derive(Debug)]
pub enum TypeKind {
Object,
Actor,
Enum,
Struct,
}
#[derive(Debug)] #[derive(Debug)]
pub struct ClassField { pub struct ClassField {
pub offset: u32, pub offset: u32,
@ -817,6 +825,7 @@ pub mod sdk {
pub struct MethodParameter { pub struct MethodParameter {
pub name: String, pub name: String,
pub ty: Type, pub ty: Type,
pub flags: EPropertyFlags,
} }
#[derive(Debug)] #[derive(Debug)]
@ -827,6 +836,7 @@ pub mod sdk {
pub is_static: bool, pub is_static: bool,
pub parameters: Vec<ParameterKind>, pub parameters: Vec<ParameterKind>,
pub return_type: Option<MethodParameter>, pub return_type: Option<MethodParameter>,
pub flags: EFunctionFlags,
} }
impl ClassMethod { impl ClassMethod {

View file

@ -1,652 +0,0 @@
use anyhow::Context;
use itertools::Itertools;
use std::{hash::Hash, ptr::NonNull};
use crate::core_types::{self, FName};
use crate::tarray::TArray;
use self::traits::{AsUObject, AsUStruct, FromRaw};
#[repr(transparent)]
#[derive(Debug, Clone)]
pub struct UObject {
inner: NonNull<core_types::UObject>,
}
unsafe impl Send for UObject {}
unsafe impl Sync for UObject {}
impl Eq for UObject {}
impl PartialEq for UObject {
fn eq(&self, other: &Self) -> bool {
unsafe {
self.inner.as_ref().internal_index == other.inner.as_ref().internal_index
&& self.inner.as_ref().name == other.inner.as_ref().name
}
}
}
impl Hash for UObject {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.internal_index().hash(state);
self.name().hash(state);
}
}
#[repr(transparent)]
#[derive(Debug, Clone)]
pub struct UClass {
pub(crate) inner: NonNull<core_types::UClass>,
}
impl Eq for UClass {}
impl PartialEq for UClass {
fn eq(&self, other: &Self) -> bool {
self.as_uobject().eq(&other.as_uobject())
}
}
impl Hash for UClass {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_uobject().hash(state);
}
}
#[repr(transparent)]
#[derive(Debug, Clone)]
pub struct UField {
inner: NonNull<core_types::UField>,
}
impl Eq for UField {}
impl PartialEq for UField {
fn eq(&self, other: &Self) -> bool {
self.as_uobject().eq(&other.as_uobject())
}
}
impl Hash for UField {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_uobject().hash(state);
}
}
impl UObject {
pub fn new(inner: NonNull<core_types::UObject>) -> Self {
Self { inner }
}
pub fn maybe_new(inner: Option<NonNull<core_types::UObject>>) -> Option<Self> {
inner.map(|inner| Self { inner })
}
pub fn to_inner(self) -> NonNull<core_types::UObject> {
self.inner
}
pub const unsafe fn cast<T>(self) -> NonNull<T> {
self.inner.cast::<T>()
}
/// returns a `Self` with the provided raw pointer, if the pointer is not null
pub fn maybe_with_raw(raw: *mut core_types::UObject) -> Option<Self> {
Self::maybe_new(NonNull::new(raw))
}
pub fn class(&self) -> Option<UClass> {
unsafe { self.inner.as_ref().class.map(|inner| UClass::new(inner)) }
}
pub fn internal_index(&self) -> u32 {
unsafe { self.inner.as_ref().internal_index }
}
pub fn name(&self) -> core_types::FName {
unsafe { self.inner.as_ref().name }
}
pub fn get_name(&self) -> anyhow::Result<String> {
let name = self.name();
name.get_name()
.map(|name_str| {
if name.number > 0 {
format!("{}_{}", name_str, name.number)
} else {
name_str
}
})
.map(|name_str| {
name_str
.rfind("/")
.map(|pos| name_str[(pos + 1)..].to_string())
.unwrap_or_else(|| name_str)
})
}
pub fn get_name_or_default(&self) -> String {
self.get_name()
.unwrap_or_else(|_| "DefaultObjectName".to_string())
}
pub fn get_full_name(&self) -> anyhow::Result<String> {
let tmp = self
.iter_outer_objects()
.map(|obj| obj.get_name())
.fold_ok(String::new(), |acc, obj_name| {
format!("{}.{}", obj_name, acc)
})?;
Ok(format!(
"{} {}{}",
self.class()
.context("invalid class pointer")?
.as_uobject()
.get_name_or_default(),
tmp,
self.get_name_or_default()
))
}
pub fn get_full_name_or_default(&self) -> String {
self.get_full_name()
.unwrap_or_else(|_| "DefaultObjectFullName".to_string())
}
pub fn outer(&self) -> Option<UObject> {
unsafe { self.inner.as_ref().outer.map(|inner| UObject::new(inner)) }
}
/// returns the package object of this object
pub fn outermost(&self) -> Option<UObject> {
self.iter_outer_objects().last()
}
pub fn is_package_object(&self) -> bool {
unsafe { self.inner.as_ref().outer.is_none() }
}
pub fn iter_outer_objects(&self) -> OuterObjectIterator {
OuterObjectIterator::new(self.clone())
}
pub fn is_a(&self, other: &UClass) -> bool {
self.class()
.map(|class| class.iter_super_classes().contains(other))
.unwrap_or(false)
}
}
pub struct OuterObjectIterator {
object: UObject,
}
impl OuterObjectIterator {
pub fn new(object: UObject) -> Self {
Self { object }
}
}
impl Iterator for OuterObjectIterator {
type Item = UObject;
fn next(&mut self) -> Option<Self::Item> {
if let Some(outer) = self.object.outer() {
self.object = outer.clone();
Some(outer)
} else {
None
}
}
}
impl From<UObject> for UClass {
fn from(obj: UObject) -> Self {
Self::new(obj.inner.cast())
}
}
impl AsUStruct for UClass {
fn as_ustruct(&self) -> UStruct {
UStruct::new(self.inner.clone().cast())
}
}
impl AsRef<core_types::UClass> for UClass {
fn as_ref(&self) -> &core_types::UClass {
unsafe { self.inner.as_ref() }
}
}
impl FromRaw<core_types::UClass> for UClass {
fn from_non_null(inner: NonNull<core_types::UClass>) -> Self {
Self::new(inner)
}
}
impl UClass {
pub fn new(inner: NonNull<core_types::UClass>) -> Self {
Self { inner }
}
pub fn iter_super_classes(&self) -> SuperClassIter {
SuperClassIter::new(self.clone())
}
}
pub struct SuperClassIter {
class: UClass,
}
impl SuperClassIter {
pub fn new(class: UClass) -> Self {
Self { class }
}
}
impl Iterator for SuperClassIter {
type Item = UClass;
fn next(&mut self) -> Option<Self::Item> {
if let Some(next) = self.class.super_struct().map(|spr| spr.as_uobject().into()) {
let item = core::mem::replace(&mut self.class, next);
Some(item)
} else {
None
}
}
}
impl From<UObject> for UField {
fn from(obj: UObject) -> Self {
Self::new(obj.inner.cast())
}
}
impl UField {
pub fn new(inner: NonNull<core_types::UField>) -> Self {
Self { inner }
}
pub fn maybe_new(inner: Option<NonNull<core_types::UField>>) -> Option<Self> {
inner.map(|inner| Self { inner })
}
pub fn maybe_with_raw(raw: *mut core_types::UField) -> Option<Self> {
NonNull::new(raw).map(|inner| Self::new(inner))
}
pub fn as_uobject(&self) -> UObject {
UObject::new(self.inner.clone().cast())
}
pub unsafe fn as_ref(&self) -> &core_types::UField {
self.inner.as_ref()
}
pub fn next(&self) -> Option<Self> {
Self::maybe_new(unsafe { self.as_ref().next })
}
}
#[derive(Debug, Clone)]
pub struct UEnum {
inner: NonNull<core_types::UEnum>,
}
impl From<UObject> for UEnum {
fn from(obj: UObject) -> Self {
Self::new(obj.inner.cast())
}
}
impl UEnum {
pub fn new(inner: NonNull<core_types::UEnum>) -> Self {
Self { inner }
}
pub fn maybe_new(inner: Option<NonNull<core_types::UEnum>>) -> Option<Self> {
inner.map(|inner| Self { inner })
}
pub fn maybe_with_raw(raw: *mut core_types::UEnum) -> Option<Self> {
NonNull::new(raw).map(|inner| Self::new(inner))
}
pub fn as_uobject(&self) -> UObject {
UObject::new(self.inner.clone().cast())
}
pub unsafe fn as_ref(&self) -> &core_types::UEnum {
self.inner.as_ref()
}
pub fn get_names(&self) -> &TArray<FName> {
unsafe { &self.as_ref().names }
}
}
#[derive(Debug, Clone)]
pub struct UStruct {
inner: NonNull<core_types::UStruct>,
}
impl From<UObject> for UStruct {
fn from(obj: UObject) -> Self {
Self::new(obj.inner.cast())
}
}
impl FromRaw<core_types::UStruct> for UStruct {
fn from_non_null(inner: NonNull<core_types::UStruct>) -> Self {
Self::new(inner)
}
}
impl UStruct {
pub fn new(inner: NonNull<core_types::UStruct>) -> Self {
Self { inner }
}
pub unsafe fn as_raw(&self) -> &core_types::UStruct {
self.inner.as_ref()
}
fn super_struct(&self) -> Option<Self> {
Self::from_maybe_non_null(unsafe { self.as_raw().super_field })
}
fn children(&self) -> Option<UField> {
UField::maybe_new(unsafe { self.as_raw().children })
}
fn iter_fields(&self) -> Option<UStructFieldIterator> {
self.children()
.map(|field| UStructFieldIterator::new(field))
}
}
impl traits::AsUStruct for UStruct {
fn as_ustruct(&self) -> UStruct {
self.clone()
}
}
pub struct UStructFieldIterator {
field: UField,
}
impl UStructFieldIterator {
pub fn new(field: UField) -> Self {
Self { field }
}
}
impl Iterator for UStructFieldIterator {
type Item = UField;
fn next(&mut self) -> Option<Self::Item> {
if let Some(mut next) = self.field.next() {
std::mem::swap(&mut self.field, &mut next);
Some(next)
} else {
None
}
}
}
#[derive(Debug, Clone)]
pub struct UScriptStruct {
inner: NonNull<core_types::UStruct>,
}
impl From<UObject> for UScriptStruct {
fn from(obj: UObject) -> Self {
Self::new(obj.inner.cast())
}
}
impl UScriptStruct {
pub fn new(inner: NonNull<core_types::UStruct>) -> Self {
Self { inner }
}
pub fn maybe_new(inner: Option<NonNull<core_types::UStruct>>) -> Option<Self> {
inner.map(|inner| Self { inner })
}
pub fn maybe_with_raw(raw: *mut core_types::UStruct) -> Option<Self> {
NonNull::new(raw).map(|inner| Self::new(inner))
}
pub fn as_uobject(&self) -> UObject {
UObject::new(self.inner.clone().cast())
}
pub unsafe fn as_ref(&self) -> &core_types::UStruct {
self.inner.as_ref()
}
pub fn iter_fields(&self) -> Option<UStructFieldIterator> {
UField::maybe_new(unsafe { self.as_ref().children })
.map(|field| UStructFieldIterator::new(field))
}
}
#[derive(Debug, Clone)]
pub struct UProperty {
inner: NonNull<core_types::UProperty>,
}
impl From<UObject> for UProperty {
/// WARNING: There is no type check on this conversion, so it is most certainly unsafe
fn from(obj: UObject) -> Self {
Self::new(obj.inner.cast())
}
}
impl UProperty {
pub fn new(inner: NonNull<core_types::UProperty>) -> Self {
Self { inner }
}
pub fn maybe_new(inner: Option<NonNull<core_types::UProperty>>) -> Option<Self> {
inner.map(|inner| Self { inner })
}
pub fn maybe_with_raw(raw: *mut core_types::UProperty) -> Option<Self> {
NonNull::new(raw).map(|inner| Self::new(inner))
}
pub fn as_uobject(&self) -> UObject {
UObject::new(self.inner.clone().cast())
}
pub unsafe fn as_ref(&self) -> &core_types::UProperty {
self.inner.as_ref()
}
}
#[derive(Debug, Clone)]
pub struct UFunction {
inner: NonNull<core_types::UFunction>,
}
impl From<UObject> for UFunction {
/// WARNING: There is no type check on this conversion, so it is most certainly unsafe
fn from(obj: UObject) -> Self {
Self::new(obj.inner.cast())
}
}
impl UFunction {
pub fn new(inner: NonNull<core_types::UFunction>) -> Self {
Self { inner }
}
pub fn maybe_new(inner: Option<NonNull<core_types::UFunction>>) -> Option<Self> {
inner.map(|inner| Self { inner })
}
pub fn maybe_with_raw(raw: *mut core_types::UFunction) -> Option<Self> {
NonNull::new(raw).map(|inner| Self::new(inner))
}
pub fn as_uobject(&self) -> UObject {
UObject::new(self.inner.clone().cast())
}
pub unsafe fn as_ref(&self) -> &core_types::UFunction {
self.inner.as_ref()
}
}
#[derive(Debug, Clone)]
pub enum UAnyType {
UObject(UObject),
UClass(UClass),
UField(UField),
UScriptStruct(UScriptStruct),
UProperty(UProperty),
UEnum(UEnum),
UStruct(UStruct),
UFunction(UFunction),
}
impl UAnyType {
pub fn as_uobject(&self) -> UObject {
match self {
UAnyType::UObject(rep) => rep.clone(),
UAnyType::UClass(rep) => rep.as_uobject(),
UAnyType::UField(rep) => rep.as_uobject(),
UAnyType::UScriptStruct(rep) => rep.as_uobject(),
UAnyType::UProperty(rep) => rep.as_uobject(),
UAnyType::UEnum(rep) => rep.as_uobject(),
UAnyType::UStruct(rep) => rep.as_uobject(),
UAnyType::UFunction(rep) => rep.as_uobject(),
}
}
}
impl Hash for UAnyType {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_uobject().hash(state);
}
}
pub mod traits {
use crate::core_types::FName;
use std::ptr::NonNull;
use itertools::Itertools;
use super::{OuterObjectIterator, UClass, UField, UObject, UStruct, UStructFieldIterator};
pub unsafe fn null_ptr_cast<'a, T, U>(ptr: &'a NonNull<T>) -> &'a NonNull<U> {
std::mem::transmute(ptr)
}
pub trait AsUObject: Sized {
fn as_uobject(&self) -> UObject;
fn class(&self) -> Option<UClass> {
self.as_uobject().class()
}
fn internal_index(&self) -> u32 {
self.as_uobject().internal_index()
}
fn name(&self) -> FName {
self.as_uobject().name()
}
fn get_name(&self) -> anyhow::Result<String> {
self.as_uobject().get_name()
}
fn get_name_or_default(&self) -> String {
self.as_uobject().get_name_or_default()
}
fn get_full_name(&self) -> anyhow::Result<String> {
self.as_uobject().get_full_name()
}
fn get_full_name_or_default(&self) -> String {
self.as_uobject().get_full_name_or_default()
}
fn outer(&self) -> Option<UObject> {
self.as_uobject().outer()
}
fn outermost(&self) -> Option<UObject> {
self.as_uobject().outermost()
}
fn is_package_object(&self) -> bool {
self.as_uobject().is_package_object()
}
fn iter_outer_objects(&self) -> OuterObjectIterator {
OuterObjectIterator::new(self.as_uobject())
}
fn is_a(&self, other: &UClass) -> bool {
self.class()
.map(|class| class.iter_super_classes().contains(other))
.unwrap_or(false)
}
}
pub trait AsUStruct {
fn as_ustruct(&self) -> UStruct;
#[inline]
fn children(&self) -> Option<UField> {
self.as_ustruct().children()
}
#[inline]
fn super_struct(&self) -> Option<UStruct> {
self.as_ustruct().super_struct()
}
#[inline]
fn iter_fields(&self) -> Option<UStructFieldIterator> {
self.children()
.map(|field| UStructFieldIterator::new(field))
}
}
impl<T> AsUObject for T
where
T: AsUStruct,
{
fn as_uobject(&self) -> UObject {
UObject::new(self.as_ustruct().inner.cast())
}
}
pub trait FromRaw<R> {
fn from_non_null(inner: NonNull<R>) -> Self;
fn from_raw(raw: *mut R) -> Option<Self>
where
Self: Sized,
{
NonNull::new(raw).map(|inner| Self::from_non_null(inner))
}
fn from_maybe_non_null(inner: Option<NonNull<R>>) -> Option<Self>
where
Self: Sized,
{
inner.map(|inner| Self::from_non_null(inner))
}
}
}