using pointer types now for every coreuobject type
This commit is contained in:
parent
724939e5da
commit
f8f183c420
|
@ -1,6 +1,6 @@
|
|||
use std::{ops::Index, ptr::NonNull, sync::RwLock};
|
||||
|
||||
use crate::core_types::FName;
|
||||
use crate::fname::FName;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref GNAMES: RwLock<GNames> = RwLock::new(GNames::new());
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
use std::{ops::Index, ptr::NonNull, sync::RwLock};
|
||||
use std::{cell::UnsafeCell, ops::Index, ptr::NonNull, sync::RwLock};
|
||||
|
||||
use rayon::prelude::ParallelIterator;
|
||||
|
||||
use crate::types;
|
||||
use crate::v2_types::{
|
||||
self,
|
||||
traits::{AsUObject, UObjectTrait},
|
||||
};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref GOBJECTS: RwLock<GObjects> = RwLock::new(GObjects::new());
|
||||
|
@ -10,7 +13,7 @@ lazy_static::lazy_static! {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct GObjects {
|
||||
objects: Option<NonNull<ObjectArray>>,
|
||||
objects: Option<NonNull<UnsafeCell<ObjectArray>>>,
|
||||
}
|
||||
|
||||
impl GObjects {
|
||||
|
@ -19,11 +22,12 @@ impl GObjects {
|
|||
}
|
||||
|
||||
pub fn set_objects(&mut self, objects: NonNull<ObjectArray>) {
|
||||
self.objects = Some(objects);
|
||||
self.objects = Some(objects.cast());
|
||||
}
|
||||
|
||||
pub fn as_objects(&self) -> Option<&ObjectArray> {
|
||||
self.objects.map(|objects| unsafe { objects.as_ref() })
|
||||
self.objects
|
||||
.map(|objects| unsafe { &*objects.as_ref().get() })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +37,7 @@ unsafe impl Sync for GObjects {}
|
|||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectArrayItem {
|
||||
object: Option<NonNull<crate::core_types::UObject>>,
|
||||
object: Option<v2_types::UObject>,
|
||||
sn: u32,
|
||||
}
|
||||
|
||||
|
@ -41,8 +45,8 @@ unsafe impl Send for ObjectArrayItem {}
|
|||
unsafe impl Sync for ObjectArrayItem {}
|
||||
|
||||
impl ObjectArrayItem {
|
||||
pub fn object(&self) -> Option<types::UObject> {
|
||||
types::UObject::maybe_new(self.object)
|
||||
pub fn object(&self) -> Option<v2_types::UObject> {
|
||||
self.object
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,22 +237,28 @@ pub mod par_iter {
|
|||
}
|
||||
|
||||
pub trait FindClass {
|
||||
fn find_class<S>(&self, class_name: S) -> Option<types::UClass>
|
||||
fn find_class<S>(&self, class_name: S) -> Option<v2_types::UClass>
|
||||
where
|
||||
S: Into<String>;
|
||||
}
|
||||
|
||||
impl FindClass for ObjectArray {
|
||||
fn find_class<S>(&self, class_name: S) -> Option<types::UClass>
|
||||
fn find_class<S>(&self, class_name: S) -> Option<v2_types::UClass>
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
use crate::v2_types::traits::UObjectNonConst;
|
||||
let class_name = class_name.into();
|
||||
|
||||
self.iter()
|
||||
.filter_map(|item| item.object())
|
||||
.filter(|object| object.get_full_name().unwrap() == class_name)
|
||||
.map(|object| types::UClass::new(unsafe { object.cast() }))
|
||||
.filter(|object| {
|
||||
object
|
||||
.get_full_name()
|
||||
.map(|name| name == class_name)
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.map(|object| (unsafe { object.cast() }))
|
||||
.next()
|
||||
}
|
||||
}
|
||||
|
|
43
src/lib.rs
43
src/lib.rs
|
@ -1,10 +1,10 @@
|
|||
#![feature(const_trait_impl, const_ptr_as_ref, const_nonnull_new)]
|
||||
|
||||
mod core_types;
|
||||
// mod core_types;
|
||||
pub mod fname;
|
||||
pub mod global_tables;
|
||||
pub mod tarray;
|
||||
pub mod types;
|
||||
// pub mod types;
|
||||
pub mod v2_types;
|
||||
|
||||
pub mod sdk {
|
||||
|
@ -19,17 +19,12 @@ pub mod sdk {
|
|||
|
||||
use crate::{
|
||||
global_tables::objects::{FindClass, GOBJECTS},
|
||||
types::{traits::AsUObject, UAnyType, UClass, UEnum, UObject},
|
||||
v2_types::{
|
||||
traits::{AsUObject, UEnumTrait, UObjectNonConst, UObjectTrait},
|
||||
UAnyType, UClass, UEnum, UObject,
|
||||
},
|
||||
};
|
||||
|
||||
pub const UOBJECT: &'static str = "Class CoreUObject.Object";
|
||||
pub const UCLASS: &'static str = "Class CoreUObject.Class";
|
||||
pub const UFUNCTION: &'static str = "Class CoreUObject.Function";
|
||||
pub const UFIELD: &'static str = "Class CoreUObject.Field";
|
||||
pub const UENUM: &'static str = "Class CoreUObject.Enum";
|
||||
pub const USTRUCT: &'static str = "Class CoreUObject.Struct";
|
||||
pub const USCRIPTSTRUCT: &'static str = "Class CoreUObject.ScriptStruct";
|
||||
|
||||
struct ClassCache {
|
||||
classes: Mutex<HashMap<String, UClass>>,
|
||||
}
|
||||
|
@ -41,24 +36,6 @@ pub mod sdk {
|
|||
}
|
||||
}
|
||||
|
||||
fn identify_uobject(&self, object: UObject) -> UAnyType {
|
||||
if object.is_a(&self.find_class(UENUM).expect("uenum")) {
|
||||
UAnyType::UEnum(object.into())
|
||||
} else if object.is_a(&self.find_class(UFIELD).expect("ufield")) {
|
||||
UAnyType::UField(object.into())
|
||||
} else if object.is_a(&self.find_class(USTRUCT).expect("ustruct")) {
|
||||
UAnyType::UStruct(object.into())
|
||||
} else if object.is_a(&self.find_class(UFUNCTION).expect("ufunction")) {
|
||||
UAnyType::UFunction(object.into())
|
||||
} else if object.is_a(&self.find_class(UCLASS).expect("uclass")) {
|
||||
UAnyType::UClass(object.into())
|
||||
} else if object.is_a(&self.find_class(USCRIPTSTRUCT).expect("uscriptstruct")) {
|
||||
UAnyType::UScriptStruct(object.into())
|
||||
} else {
|
||||
UAnyType::UObject(object)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cache_class(&mut self, class: UClass) -> anyhow::Result<()> {
|
||||
let name = class.get_full_name()?;
|
||||
self.classes.lock().unwrap().insert(name, class);
|
||||
|
@ -109,7 +86,7 @@ pub mod sdk {
|
|||
// ensure item contains object
|
||||
.filter_map(|item| item.object())
|
||||
// get package object
|
||||
.filter_map(|obj| obj.outermost().map(|pkg| (pkg, obj)))
|
||||
.map(|obj| (obj.package_object(), obj))
|
||||
.fold(
|
||||
HashMap::<UObject, Vec<UObject>>::new(),
|
||||
|mut acc, (pkg, obj)| {
|
||||
|
@ -153,7 +130,7 @@ pub mod sdk {
|
|||
.cache_class(object.class().expect("object had no class?"))
|
||||
.context("object not of any base type?")?;
|
||||
|
||||
let ty = cache.identify_uobject(object);
|
||||
let ty = UAnyType::from_uobject(object.as_uobject());
|
||||
log::debug!("ty: {ty:?}");
|
||||
|
||||
match ty {
|
||||
|
@ -161,13 +138,11 @@ pub mod sdk {
|
|||
UAnyType::UClass(_) => {}
|
||||
UAnyType::UField(_) => {}
|
||||
UAnyType::UScriptStruct(_) => {}
|
||||
UAnyType::UProperty(_) => {}
|
||||
UAnyType::UEnum(obj) => {
|
||||
let enm = Self::process_enum(obj)?;
|
||||
log::info!("enum: {enm}");
|
||||
}
|
||||
UAnyType::UStruct(_) => {}
|
||||
UAnyType::UFunction(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,7 +152,7 @@ pub mod sdk {
|
|||
fn process_enum(enm: UEnum) -> anyhow::Result<Enum> {
|
||||
// get all the variants
|
||||
let values = enm
|
||||
.get_names()
|
||||
.names()
|
||||
.iter()
|
||||
.enumerate()
|
||||
// canonicalize the names into valid rust
|
||||
|
|
|
@ -6,7 +6,13 @@
|
|||
//! 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, marker::PhantomData, ptr::NonNull};
|
||||
use std::{
|
||||
cell::UnsafeCell,
|
||||
fmt::{Debug, Display},
|
||||
hash::Hash,
|
||||
marker::PhantomData,
|
||||
ptr::NonNull,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
|
@ -178,14 +184,33 @@ define_utypes!(
|
|||
UEnumProperty where UFieldTrait, UStructTrait, UPropertyTrait,UEnumPropertyTrait => "EnumProperty"
|
||||
);
|
||||
|
||||
impl Hash for UObject {
|
||||
fn hash<H: ~const std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for UObject {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "UObject {{")?;
|
||||
writeln!(f, "\tvtbl: {:?}", self.vtbl())?;
|
||||
writeln!(f, "\tobject_flags{:?}", self.object_flags())?;
|
||||
writeln!(f, "\tinternal_index{:?}", self.internal_index())?;
|
||||
writeln!(f, "\tclass{:?}", self.class())?;
|
||||
writeln!(f, "\tname{:?}", &self.get_name_or_default())?;
|
||||
writeln!(f, "\touter{:?}", self.outer())?;
|
||||
writeln!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
impl UObject {
|
||||
#![allow(dead_code)]
|
||||
|
||||
const fn raw_ptr(&self) -> *const () {
|
||||
const fn raw_ptr(&self) -> *const u8 {
|
||||
unsafe { self.0.as_ref().get() as _ }
|
||||
}
|
||||
|
||||
const fn raw_mut(&self) -> *mut () {
|
||||
const fn raw_mut(&self) -> *mut u8 {
|
||||
unsafe { self.0.as_ref().get() as _ }
|
||||
}
|
||||
|
||||
|
@ -316,8 +341,61 @@ impl<'a> Iterator for ChildIter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum UAnyType {
|
||||
UObject(UObject),
|
||||
UClass(UClass),
|
||||
UField(UField),
|
||||
UScriptStruct(UScriptStruct),
|
||||
UEnum(UEnum),
|
||||
UStruct(UStruct),
|
||||
}
|
||||
|
||||
impl UAnyType {
|
||||
pub fn from_uobject(uobject: UObject) -> Self {
|
||||
// remember to order this from most specialized to least.
|
||||
// specifically: a UClass is also a UStruct, so check for UClass first,
|
||||
// then for any other subtypes of UStruct, then for UStruct
|
||||
if uobject.is_a(&UEnum::static_class()) {
|
||||
Self::UEnum(unsafe { uobject.cast() })
|
||||
} else if uobject.is_a(&UClass::static_class()) {
|
||||
Self::UClass(unsafe { uobject.cast() })
|
||||
} else if uobject.is_a(&UScriptStruct::static_class()) {
|
||||
Self::UScriptStruct(unsafe { uobject.cast() })
|
||||
} else if uobject.is_a(&UStruct::static_class()) {
|
||||
Self::UStruct(unsafe { uobject.cast() })
|
||||
} else if uobject.is_a(&UField::static_class()) {
|
||||
Self::UField(unsafe { uobject.cast() })
|
||||
} else {
|
||||
Self::UObject(uobject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsUObject for UAnyType {
|
||||
fn as_uobject(&self) -> self::UObject {
|
||||
match self {
|
||||
UAnyType::UObject(obj) => obj.as_uobject(),
|
||||
UAnyType::UClass(obj) => obj.as_uobject(),
|
||||
UAnyType::UField(obj) => obj.as_uobject(),
|
||||
UAnyType::UScriptStruct(obj) => obj.as_uobject(),
|
||||
UAnyType::UEnum(obj) => obj.as_uobject(),
|
||||
UAnyType::UStruct(obj) => obj.as_uobject(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_raw(raw: *mut ()) -> Option<Self> {
|
||||
UObject::from_raw(raw).map(|obj| Self::from_uobject(obj))
|
||||
}
|
||||
|
||||
fn from_nonnull(raw: NonNull<UnsafeCell<()>>) -> Self {
|
||||
Self::from_uobject(UObject::from_nonnull(raw))
|
||||
}
|
||||
}
|
||||
|
||||
use traits::*;
|
||||
mod traits {
|
||||
pub mod traits {
|
||||
use std::cell::UnsafeCell;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
|
@ -338,17 +416,13 @@ mod traits {
|
|||
static CLASS: OnceCell<super::UClass> = OnceCell::new();
|
||||
|
||||
*CLASS.get_or_init(|| {
|
||||
super::UClass(
|
||||
GOBJECTS
|
||||
.read()
|
||||
.unwrap()
|
||||
.as_objects()
|
||||
.unwrap()
|
||||
.find_class(Self::static_class_name())
|
||||
.expect("static class not found!")
|
||||
.inner
|
||||
.cast(),
|
||||
)
|
||||
GOBJECTS
|
||||
.read()
|
||||
.unwrap()
|
||||
.as_objects()
|
||||
.unwrap()
|
||||
.find_class(Self::static_class_name())
|
||||
.expect("static class not found!")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue