handle possibility of missing static class (UMapProperty)
This commit is contained in:
parent
674a54afb9
commit
99a3effc4c
|
@ -170,10 +170,34 @@ macro_rules! define_utypes {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct $ty(NonNull<UnsafeCell<()>>);
|
pub struct $ty(NonNull<UnsafeCell<()>>);
|
||||||
|
|
||||||
impl $ty {
|
impl traits::StaticClass for $ty {
|
||||||
pub const fn static_class_name() -> &'static str {
|
fn static_class_name() -> &'static str {
|
||||||
concat!("Class CoreUObject.", $name)
|
concat!("Class CoreUObject.", $name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn static_class() -> Option<UClass> {
|
||||||
|
use crate::global_tables::objects::{FindClass, GOBJECTS};
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
// this is something that we always do in C/C++ but unfortinately requires a blanket impl Sync + Send on all UObject types..
|
||||||
|
static CLASS: OnceCell<Option<UClass>> = OnceCell::new();
|
||||||
|
|
||||||
|
*CLASS.get_or_init(|| {
|
||||||
|
let class = match GOBJECTS
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.as_objects()
|
||||||
|
.unwrap()
|
||||||
|
.find_class(Self::static_class_name()) {
|
||||||
|
Some(class) => {Some(class)},
|
||||||
|
None => {
|
||||||
|
log::error!("static class \"{}\" not found!", Self::static_class_name());
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
log::info!("class for {} is {:?}", Self::static_class_name(), class);
|
||||||
|
class
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_asuobject!($ty);
|
impl_asuobject!($ty);
|
||||||
|
@ -192,6 +216,30 @@ macro_rules! define_utypes {
|
||||||
fn static_class_name() -> &'static str {
|
fn static_class_name() -> &'static str {
|
||||||
concat!("Class CoreUObject.", $name)
|
concat!("Class CoreUObject.", $name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn static_class() -> Option<UClass> {
|
||||||
|
use crate::global_tables::objects::{FindClass, GOBJECTS};
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
// this is something that we always do in C/C++ but unfortinately requires a blanket impl Sync + Send on all UObject types..
|
||||||
|
static CLASS: OnceCell<Option<UClass>> = OnceCell::new();
|
||||||
|
|
||||||
|
*CLASS.get_or_init(|| {
|
||||||
|
let class = match GOBJECTS
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.as_objects()
|
||||||
|
.unwrap()
|
||||||
|
.find_class(Self::static_class_name()) {
|
||||||
|
Some(class) => {Some(class)},
|
||||||
|
None => {
|
||||||
|
log::error!("static class \"{}\" not found!", Self::static_class_name());
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
log::info!("class for {} is {:?}", Self::static_class_name(), class);
|
||||||
|
class
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_asuobject!($ty);
|
impl_asuobject!($ty);
|
||||||
|
@ -453,15 +501,19 @@ impl UAnyType {
|
||||||
// remember to order this from most specialized to least.
|
// remember to order this from most specialized to least.
|
||||||
// specifically: a UClass is also a UStruct, so check for UClass first,
|
// specifically: a UClass is also a UStruct, so check for UClass first,
|
||||||
// then for any other subtypes of UStruct, then for UStruct
|
// then for any other subtypes of UStruct, then for UStruct
|
||||||
if uobject.is_a(&UEnum::static_class()) {
|
if uobject.is_a_maybe(&UClass::static_class()) {
|
||||||
Self::UEnum(unsafe { uobject.cast() })
|
|
||||||
} else if uobject.is_a(&UClass::static_class()) {
|
|
||||||
Self::UClass(unsafe { uobject.cast() })
|
Self::UClass(unsafe { uobject.cast() })
|
||||||
} else if uobject.is_a(&UScriptStruct::static_class()) {
|
} else if uobject.is_a_maybe(&UProperty::static_class()) {
|
||||||
|
Self::UProperty(unsafe { uobject.cast() })
|
||||||
|
} else if uobject.is_a_maybe(&UFunction::static_class()) {
|
||||||
|
Self::UFunction(unsafe { uobject.cast() })
|
||||||
|
} else if uobject.is_a_maybe(&UScriptStruct::static_class()) {
|
||||||
Self::UScriptStruct(unsafe { uobject.cast() })
|
Self::UScriptStruct(unsafe { uobject.cast() })
|
||||||
} else if uobject.is_a(&UStruct::static_class()) {
|
} else if uobject.is_a_maybe(&UEnum::static_class()) {
|
||||||
|
Self::UEnum(unsafe { uobject.cast() })
|
||||||
|
} else if uobject.is_a_maybe(&UStruct::static_class()) {
|
||||||
Self::UStruct(unsafe { uobject.cast() })
|
Self::UStruct(unsafe { uobject.cast() })
|
||||||
} else if uobject.is_a(&UField::static_class()) {
|
} else if uobject.is_a_maybe(&UField::static_class()) {
|
||||||
Self::UField(unsafe { uobject.cast() })
|
Self::UField(unsafe { uobject.cast() })
|
||||||
} else {
|
} else {
|
||||||
Self::UObject(uobject)
|
Self::UObject(uobject)
|
||||||
|
@ -497,30 +549,15 @@ pub mod traits {
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use once_cell::sync::OnceCell;
|
|
||||||
|
|
||||||
use crate::fname::FName;
|
use crate::fname::FName;
|
||||||
use crate::global_tables::objects::{FindClass, GOBJECTS};
|
|
||||||
use crate::tarray::{FString, TArray};
|
use crate::tarray::{FString, TArray};
|
||||||
|
|
||||||
use super::{EObjectFlags, VTbl};
|
use super::{EObjectFlags, VTbl};
|
||||||
|
|
||||||
pub trait StaticClass {
|
pub trait StaticClass {
|
||||||
fn static_class_name() -> &'static str;
|
fn static_class_name() -> &'static str;
|
||||||
fn static_class() -> super::UClass {
|
fn static_class() -> Option<super::UClass>;
|
||||||
// this is something that we always do in C/C++ but unfortinately requires a blanket impl Sync + Send on all UObject types..
|
|
||||||
static CLASS: OnceCell<super::UClass> = OnceCell::new();
|
|
||||||
|
|
||||||
*CLASS.get_or_init(|| {
|
|
||||||
GOBJECTS
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.as_objects()
|
|
||||||
.unwrap()
|
|
||||||
.find_class(Self::static_class_name())
|
|
||||||
.expect("static class not found!")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
|
@ -601,6 +638,13 @@ pub mod traits {
|
||||||
.map(|class| class.iter_super_classes().contains(other))
|
.map(|class| class.iter_super_classes().contains(other))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_a_maybe(&self, other: &Option<super::UClass>) -> bool {
|
||||||
|
other
|
||||||
|
.as_ref()
|
||||||
|
.map(|class| self.is_a(class))
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> UObjectNonConst for T where T: UObjectTrait {}
|
impl<T> UObjectNonConst for T where T: UObjectTrait {}
|
||||||
|
|
Loading…
Reference in a new issue