v2 type def
This commit is contained in:
parent
a2233bb3b4
commit
03c1c61d42
1
rust-toolchain
Normal file
1
rust-toolchain
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nightly
|
|
@ -1,6 +1,9 @@
|
||||||
|
#![feature(const_trait_impl, const_ptr_as_ref, const_nonnull_new)]
|
||||||
|
|
||||||
mod core_types;
|
mod core_types;
|
||||||
pub mod global_tables;
|
pub mod global_tables;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
pub mod v2_types;
|
||||||
|
|
||||||
pub mod sdk {
|
pub mod sdk {
|
||||||
use std::{
|
use std::{
|
||||||
|
|
434
src/v2_types/mod.rs
Normal file
434
src/v2_types/mod.rs
Normal file
|
@ -0,0 +1,434 @@
|
||||||
|
//! This module is an attempt to define Unreal Types using just a pointer
|
||||||
|
//! because I thought that was proabably a lot safer and ergonomic than having a
|
||||||
|
//! bunch of nesting structures, and having to worry a lot more about aliasing
|
||||||
|
//! references. every type is also stored in an UnsafeCell which, if I
|
||||||
|
//! understand UnsafeCell and unsafe Rust correctly, should tell the compiler
|
||||||
|
//! that the contents might very well change under its feet (which they might).
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
use bitflags::bitflags;
|
||||||
|
use std::{cell::UnsafeCell, 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! define_utypes {
|
||||||
|
($($ty:ident),+) => {
|
||||||
|
$(
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct $ty(NonNull<UnsafeCell<()>>);
|
||||||
|
|
||||||
|
impl_asuobject!($ty);
|
||||||
|
|
||||||
|
impl const traits::UObject for $ty {}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
($($ty:ident => $name:literal),+) => {
|
||||||
|
$(
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct $ty(NonNull<UnsafeCell<()>>);
|
||||||
|
|
||||||
|
impl $ty {
|
||||||
|
pub const fn static_class_name() -> &'static str {
|
||||||
|
concat!("Class CoreUObject.", $name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_asuobject!($ty);
|
||||||
|
|
||||||
|
impl const traits::UObjectTrait for $ty {}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_const_trait_for {
|
||||||
|
|
||||||
|
($trt:ty: $($ty:ty),+) => {
|
||||||
|
$(
|
||||||
|
impl const $trt for $ty {}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_asuobject {
|
||||||
|
($($ty:ty),+) => {
|
||||||
|
$(
|
||||||
|
impl $ty {
|
||||||
|
pub const fn from_raw(raw: *mut ()) -> Option<Self> {
|
||||||
|
match NonNull::new(raw) {
|
||||||
|
Some(ptr) => Some(Self(ptr.cast())),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn from_nonnull(raw: NonNull<UnsafeCell<()>>) -> Self {
|
||||||
|
Self(raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const traits::AsUObject for $ty {
|
||||||
|
fn as_uobject(&self) -> self::UObject {
|
||||||
|
self::UObject(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
define_utypes!(
|
||||||
|
UObject => "Object",
|
||||||
|
UField => "Field",
|
||||||
|
UEnum => "Enum",
|
||||||
|
UStruct => "Struct",
|
||||||
|
UScriptStruct => "ScriptStruct",
|
||||||
|
UClass => "Class",
|
||||||
|
UProperty => "Property",
|
||||||
|
UFunction => "Function",
|
||||||
|
UNumericProperty => "NumericProperty",
|
||||||
|
UByteProperty => "ByteProperty",
|
||||||
|
UUInt16Property => "UInt16Property",
|
||||||
|
UUInt32Property => "UInt32Property",
|
||||||
|
UUInt64Property => "UInt64Property",
|
||||||
|
UInt8Property => "Int8Property",
|
||||||
|
UInt16Property => "Int16Property",
|
||||||
|
UIntProperty => "IntProperty", // i32
|
||||||
|
UInt64Property => "Int64Property",
|
||||||
|
UFloatProperty => "FloatProperty",
|
||||||
|
UDoubleProperty => "DoubleProperty",
|
||||||
|
UBoolProperty => "BoolProperty",
|
||||||
|
UObjectPropertyBase => "ObjectPropertyBase",
|
||||||
|
UObjectProperty => "ObjectProperty",
|
||||||
|
UClassProperty => "ClassProperty",
|
||||||
|
UInterfaceProperty => "InterfaceProperty",
|
||||||
|
UWeakObjectProperty => "WeakObjectProperty",
|
||||||
|
ULazyObjectProperty => "LazyObjectProperty",
|
||||||
|
UAssetObjectProperty => "AssetObjectProperty",
|
||||||
|
UAssetClassProperty => "AssetClassProperty",
|
||||||
|
USoftObjectProperty => "SoftObjectProperty",
|
||||||
|
UNameProperty => "NameProperty",
|
||||||
|
UStructProperty => "StructProperty",
|
||||||
|
UStrProperty => "StrProperty",
|
||||||
|
UTextProperty => "TextProperty",
|
||||||
|
UArrayProperty => "ArrayProperty",
|
||||||
|
UMapProperty => "MapProperty",
|
||||||
|
UDelegateProperty => "DelegateProperty",
|
||||||
|
UMulticastDelegateProperty => "MulticastDelegateProperty",
|
||||||
|
UEnumProperty => "EnumProperty"
|
||||||
|
);
|
||||||
|
// impl_const_trait_for!(
|
||||||
|
// traits::UFieldTrait: UField,
|
||||||
|
// UEnum,
|
||||||
|
// UStruct,
|
||||||
|
// UClass,
|
||||||
|
// UProperty
|
||||||
|
// );
|
||||||
|
|
||||||
|
// impl_const_trait_for!(traits::UStructTrait: UStruct, UClass);
|
||||||
|
// impl_const_trait_for!(traits::UEnumTrait: UEnum);
|
||||||
|
// impl_const_trait_for!(traits::UPropertyTrait: UProperty);
|
||||||
|
|
||||||
|
impl UObject {
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
const fn raw_ptr(&self) -> *const () {
|
||||||
|
unsafe { self.0.as_ref().get() as _ }
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn raw_mut(&self) -> *mut () {
|
||||||
|
unsafe { self.0.as_ref().get() as _ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||||
|
pub enum ECppForm {
|
||||||
|
Regular,
|
||||||
|
Namespaced,
|
||||||
|
EnumClass,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UEnum {
|
||||||
|
pub fn cpp_form(&self) -> Option<ECppForm> {
|
||||||
|
match *traits::UEnumTrait::cpp_form_raw(self) {
|
||||||
|
0 => Some(ECppForm::Regular),
|
||||||
|
1 => Some(ECppForm::Namespaced),
|
||||||
|
2 => Some(ECppForm::EnumClass),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod traits {
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
use crate::core_types::{FName, FString, TArray};
|
||||||
|
|
||||||
|
use super::{EObjectFlags, VTbl};
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait AsUObject {
|
||||||
|
fn as_uobject(&self) -> super::UObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UObjectTrait: ~const AsUObject {
|
||||||
|
fn vtbl(&self) -> &VTbl {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(0).cast() }
|
||||||
|
}
|
||||||
|
fn object_flags(&self) -> &EObjectFlags {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(8).cast() }
|
||||||
|
}
|
||||||
|
fn internal_index(&self) -> &u32 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(12).cast() }
|
||||||
|
}
|
||||||
|
fn class(&self) -> &Option<super::UClass> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(16).cast() }
|
||||||
|
}
|
||||||
|
fn name(&self) -> &FName {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(24).cast() }
|
||||||
|
}
|
||||||
|
fn outer(&self) -> &Option<super::UObject> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(32).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UFieldTrait: ~const AsUObject {
|
||||||
|
fn next(&self) -> &Option<super::UField> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(40).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UEnumTrait: ~const AsUObject {
|
||||||
|
fn cpp_type(&self) -> &FString {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(48).cast() }
|
||||||
|
}
|
||||||
|
fn names(&self) -> &TArray<FName> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(64).cast() }
|
||||||
|
}
|
||||||
|
fn cpp_form_raw(&self) -> &u32 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(80).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> const UFieldTrait for T where T: ~const UEnumTrait {}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UStructTrait: ~const UFieldTrait {
|
||||||
|
fn super_field(&self) -> &Option<super::UStruct> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(48).cast() }
|
||||||
|
}
|
||||||
|
fn children(&self) -> &Option<super::UField> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(56).cast() }
|
||||||
|
}
|
||||||
|
fn property_size(&self) -> &u32 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(64).cast() }
|
||||||
|
}
|
||||||
|
fn min_alignment(&self) -> &u32 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(68).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UScriptStructTrait: ~const UStructTrait {}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UClassTrait: ~const UStructTrait {}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UFunctionTrait: ~const UStructTrait {
|
||||||
|
fn function_flags(&self) -> &u32 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(144).cast() }
|
||||||
|
}
|
||||||
|
fn rep_offset(&self) -> &u16 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(148).cast() }
|
||||||
|
}
|
||||||
|
fn num_params(&self) -> &u8 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(150).cast() }
|
||||||
|
}
|
||||||
|
fn params_size(&self) -> &u16 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(152).cast() }
|
||||||
|
}
|
||||||
|
fn return_value_offset(&self) -> &u16 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(154).cast() }
|
||||||
|
}
|
||||||
|
fn rpc_id(&self) -> &u16 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(156).cast() }
|
||||||
|
}
|
||||||
|
fn rpc_response_id(&self) -> &u16 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(158).cast() }
|
||||||
|
}
|
||||||
|
fn first_property_to_init(&self) -> &Option<super::UProperty> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(160).cast() }
|
||||||
|
}
|
||||||
|
fn func(&self) -> &Option<NonNull<()>> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(168).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UPropertyTrait: ~const UFieldTrait {
|
||||||
|
fn array_dim(&self) -> &i32 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(48).cast() }
|
||||||
|
}
|
||||||
|
fn element_size(&self) -> &i32 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(52).cast() }
|
||||||
|
}
|
||||||
|
fn property_flags(&self) -> &u64 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(56).cast() }
|
||||||
|
}
|
||||||
|
fn rep_index(&self) -> &i16 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(64).cast() }
|
||||||
|
}
|
||||||
|
fn rep_notify_function(&self) -> &FName {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(68).cast() }
|
||||||
|
}
|
||||||
|
fn offset(&self) -> &i32 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(76).cast() }
|
||||||
|
}
|
||||||
|
fn property_link_next(&self) -> &Option<super::UProperty> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(80).cast() }
|
||||||
|
}
|
||||||
|
fn next_ref(&self) -> &Option<super::UProperty> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(88).cast() }
|
||||||
|
}
|
||||||
|
fn destructor_link_next(&self) -> &Option<super::UProperty> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(96).cast() }
|
||||||
|
}
|
||||||
|
fn post_construct_link_next(&self) -> &Option<super::UProperty> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(104).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UBytePropertyTrait: ~const UPropertyTrait {
|
||||||
|
fn uenum(&self) -> &Option<super::UEnum> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UBoolPropertyTrait: ~const UPropertyTrait {
|
||||||
|
fn field_size(&self) -> &u8 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
fn byte_offset(&self) -> &u8 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(113).cast() }
|
||||||
|
}
|
||||||
|
fn byte_mask(&self) -> &u8 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(114).cast() }
|
||||||
|
}
|
||||||
|
fn field_mask(&self) -> &u8 {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(115).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UObjectPropertyBaseTrait: ~const UPropertyTrait {
|
||||||
|
fn property_class(&self) -> &Option<super::UClass> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UInterfacePropertyTrait: ~const UPropertyTrait {
|
||||||
|
fn interface_class(&self) -> &Option<super::UClass> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UStructPropertyTrait: ~const UPropertyTrait {
|
||||||
|
fn ustruct(&self) -> &Option<super::UStruct> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UArrayPropertyTrait: ~const UPropertyTrait {
|
||||||
|
fn inner(&self) -> &Option<super::UClass> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UMapPropertyTrait: ~const UPropertyTrait {
|
||||||
|
fn key_prop(&self) -> &Option<super::UProperty> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
fn value_prop(&self) -> &Option<super::UProperty> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(120).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UClassPropertyTrait: ~const UObjectPropertyBaseTrait {
|
||||||
|
fn meta_class(&self) -> &Option<super::UClass> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(120).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UAssetClassPropertyTrait: ~const UObjectPropertyBaseTrait {
|
||||||
|
fn meta_class(&self) -> &Option<super::UClass> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(120).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UDelegatePropertyTrait: ~const UPropertyTrait {
|
||||||
|
fn signature_function(&self) -> &Option<super::UFunction> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
pub trait UEnumPropertyTrait: ~const UPropertyTrait {
|
||||||
|
fn underlying_type(&self) -> &Option<super::UProperty> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(112).cast() }
|
||||||
|
}
|
||||||
|
fn uenum(&self) -> &Option<super::UEnum> {
|
||||||
|
unsafe { &*self.as_uobject().raw_ptr().offset(120).cast() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue