2020-10-21 17:56:05 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
2022-04-20 14:24:59 -04:00
# if WITH_LOW_LEVEL_TESTS
2023-01-05 12:27:16 -05:00
# include "ObjectPtrTestClass.h"
2020-10-21 17:56:05 -04:00
# include "UObject/ObjectHandle.h"
2022-09-13 12:24:17 -04:00
# include "UObject/ObjectPtr.h"
2023-01-05 12:27:16 -05:00
# include "UObject/Package.h"
# include "UObject/ObjectResource.h"
2022-10-06 19:49:55 -04:00
# include "UObject/MetaData.h"
2020-10-21 17:56:05 -04:00
# include "HAL/PlatformProperties.h"
# include "ObjectRefTrackingTestBase.h"
2021-01-11 11:17:58 -04:00
# include "IO/IoDispatcher.h"
2022-04-07 10:34:55 -04:00
# include "TestHarness.h"
2023-01-16 19:20:47 -05:00
# include "UObject/ObjectRef.h"
# include "UObject/ObjectPathId.h"
2024-05-02 11:25:44 -04:00
# include "UObject/PropertyBagRepository.h"
2022-04-07 10:34:55 -04:00
2020-10-21 17:56:05 -04:00
static_assert ( sizeof ( FObjectHandle ) = = sizeof ( void * ) , " FObjectHandle type must always compile to something equivalent to a pointer size. " ) ;
class FObjectHandleTestBase : public FObjectRefTrackingTestBase
{
public :
2022-03-31 07:45:37 -04:00
2020-10-21 17:56:05 -04:00
protected :
2023-01-16 19:20:47 -05:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
void TestResolveFailure ( UE : : CoreUObject : : Private : : FPackedObjectRef PackedRef )
2020-10-21 17:56:05 -04:00
{
FSnapshotObjectRefMetrics ObjectRefMetrics ( * this ) ;
2023-01-16 19:20:47 -05:00
FObjectHandle TargetHandle = { PackedRef . EncodedRef } ;
UObject * ResolvedObject = FObjectPtr ( TargetHandle ) . Get ( ) ;
ObjectRefMetrics . TestNumResolves ( TEXT ( " NumResolves should be incremented by one after a resolve attempt " ) , 1 ) ;
ObjectRefMetrics . TestNumReads ( TEXT ( " NumReads should be incremented by one after a resolve attempt " ) , 1 ) ;
CHECK ( ResolvedObject = = nullptr ) ;
ObjectRefMetrics . TestNumFailedResolves ( TEXT ( " NumFailedResolves should be incremented by one after a failed resolve attempt " ) , 1 ) ;
}
# endif
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE || UE_WITH_OBJECT_HANDLE_TRACKING
void TestResolvableNonNull ( const ANSICHAR * PackageName , const ANSICHAR * ObjectName , bool bExpectSubRefReads )
{
FSnapshotObjectRefMetrics ObjectRefMetrics ( * this ) ;
FObjectRef TargetRef ( FName ( PackageName ) , NAME_None , NAME_None , UE : : CoreUObject : : Private : : FObjectPathId ( ObjectName ) ) ;
UObject * ResolvedObject = TargetRef . Resolve ( ) ;
FObjectPtr Ptr ( ResolvedObject ) ;
Ptr . Get ( ) ;
TEST_TRUE ( TEXT ( " expected not null " ) , ResolvedObject ! = nullptr ) ;
2020-10-21 17:56:05 -04:00
ObjectRefMetrics . TestNumResolves ( TEXT ( " NumResolves should be incremented by one after a resolve attempt " ) , 1 ) ;
2021-02-03 18:50:08 -04:00
ObjectRefMetrics . TestNumReads ( TEXT ( " NumReads should be incremented by one after a resolve attempt " ) , 1 , bExpectSubRefReads /*bAllowAdditionalReads*/ ) ;
2020-10-21 17:56:05 -04:00
ObjectRefMetrics . TestNumFailedResolves ( TEXT ( " NumFailedResolves should not change after a successful resolve attempt " ) , 0 ) ;
}
2023-01-16 19:20:47 -05:00
void TestResolveFailure ( const ANSICHAR * PackageName , const ANSICHAR * ObjectName )
2020-10-21 17:56:05 -04:00
{
FSnapshotObjectRefMetrics ObjectRefMetrics ( * this ) ;
2023-01-16 19:20:47 -05:00
FObjectRef TargetRef ( FName ( PackageName ) , NAME_None , NAME_None , UE : : CoreUObject : : Private : : FObjectPathId ( ObjectName ) ) ;
const UObject * ResolvedObject = TargetRef . Resolve ( ) ;
2020-10-21 17:56:05 -04:00
ObjectRefMetrics . TestNumResolves ( TEXT ( " NumResolves should be incremented by one after a resolve attempt " ) , 1 ) ;
ObjectRefMetrics . TestNumReads ( TEXT ( " NumReads should be incremented by one after a resolve attempt " ) , 1 ) ;
2023-01-16 19:20:47 -05:00
CHECK ( ResolvedObject = = nullptr ) ;
2020-10-21 17:56:05 -04:00
ObjectRefMetrics . TestNumFailedResolves ( TEXT ( " NumFailedResolves should be incremented by one after a failed resolve attempt " ) , 1 ) ;
2021-03-02 14:39:53 -04:00
}
2023-01-16 19:20:47 -05:00
# endif
2020-10-21 17:56:05 -04:00
} ;
2022-04-07 10:34:55 -04:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::FObjectHandle::Null Behavior " , " [CoreUObject][ObjectHandle] " )
2020-10-21 17:56:05 -04:00
{
2023-01-16 19:20:47 -05:00
FObjectHandle TargetHandle = UE : : CoreUObject : : Private : : MakeObjectHandle ( nullptr ) ;
2020-10-21 17:56:05 -04:00
2022-03-31 07:45:37 -04:00
TEST_TRUE ( TEXT ( " Handle to target is null " ) , IsObjectHandleNull ( TargetHandle ) ) ;
TEST_TRUE ( TEXT ( " Handle to target is resolved " ) , IsObjectHandleResolved ( TargetHandle ) ) ;
2020-10-21 17:56:05 -04:00
FSnapshotObjectRefMetrics ObjectRefMetrics ( * this ) ;
2023-01-16 19:20:47 -05:00
UObject * ResolvedObject = UE : : CoreUObject : : Private : : ResolveObjectHandle ( TargetHandle ) ;
2020-10-21 17:56:05 -04:00
2022-03-31 07:45:37 -04:00
TEST_EQUAL ( TEXT ( " Resolved object is equal to original object " ) , ( UObject * ) nullptr , ResolvedObject ) ;
2020-10-21 17:56:05 -04:00
ObjectRefMetrics . TestNumFailedResolves ( TEXT ( " NumFailedResolves should not change after a resolve attempt on a null handle " ) , 0 ) ;
ObjectRefMetrics . TestNumResolves ( TEXT ( " NumResolves should not change after a resolve attempt on a null handle " ) , 0 ) ;
ObjectRefMetrics . TestNumReads ( TEXT ( " NumReads should be incremented by one after a resolve attempt on a null handle " ) , 1 ) ;
}
2022-04-07 10:34:55 -04:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::FObjectHandle::Pointer Behavior " , " [CoreUObject][ObjectHandle] " )
2020-10-21 17:56:05 -04:00
{
2023-01-16 19:20:47 -05:00
FObjectHandle TargetHandle = UE : : CoreUObject : : Private : : MakeObjectHandle ( ( UObject * ) 0x0042 ) ;
2020-10-21 17:56:05 -04:00
2022-03-31 07:45:37 -04:00
TEST_FALSE ( TEXT ( " Handle to target is null " ) , IsObjectHandleNull ( TargetHandle ) ) ;
TEST_TRUE ( TEXT ( " Handle to target is resolved " ) , IsObjectHandleResolved ( TargetHandle ) ) ;
2020-10-21 17:56:05 -04:00
FSnapshotObjectRefMetrics ObjectRefMetrics ( * this ) ;
2023-01-16 19:20:47 -05:00
UObject * ResolvedObject = UE : : CoreUObject : : Private : : ResolveObjectHandle ( TargetHandle ) ;
2020-10-21 17:56:05 -04:00
2022-03-31 07:45:37 -04:00
TEST_EQUAL ( TEXT ( " Resolved object is equal to original object " ) , ( UObject * ) 0x0042 , ResolvedObject ) ;
2020-10-21 17:56:05 -04:00
ObjectRefMetrics . TestNumResolves ( TEXT ( " NumResolves should not change after a resolve attempt on a pointer handle " ) , 0 ) ;
ObjectRefMetrics . TestNumFailedResolves ( TEXT ( " NumFailedResolves should not change after a resolve attempt on a pointer handle " ) , 0 ) ;
ObjectRefMetrics . TestNumReads ( TEXT ( " NumReads should be incremented by one after a resolve attempt on a pointer handle " ) , 1 ) ;
}
2023-01-16 19:20:47 -05:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2022-08-16 15:53:22 -04:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::FObjectHandle::Resolve Engine Content Target " , " [CoreUObject][ObjectHandle] " )
2020-10-21 17:56:05 -04:00
{
2022-08-16 15:53:22 -04:00
const FName TestPackageName ( TEXT ( " /Engine/Test/ObjectPtrDefaultSerialize/Transient " ) ) ;
UPackage * TestPackage = NewObject < UPackage > ( nullptr , TestPackageName , RF_Transient ) ;
TestPackage - > AddToRoot ( ) ;
2023-01-05 12:27:16 -05:00
UObject * TestSoftObject = NewObject < UObjectPtrTestClass > ( TestPackage , TEXT ( " DefaultSerializeObject " ) ) ;
UObject * TestSubObject = NewObject < UObjectPtrTestClass > ( TestSoftObject , TEXT ( " SubObject " ) ) ;
2022-08-16 15:53:22 -04:00
ON_SCOPE_EXIT {
TestPackage - > RemoveFromRoot ( ) ;
} ;
2020-10-21 17:56:05 -04:00
2023-01-16 19:20:47 -05:00
TestResolvableNonNull ( " /Engine/Test/ObjectPtrDefaultSerialize/Transient " , " DefaultSerializeObject.SubObject " , true ) ;
TestResolvableNonNull ( " /Engine/Test/ObjectPtrDefaultSerialize/Transient " , " DefaultSerializeObject " , false ) ;
2020-10-21 17:56:05 -04:00
}
2023-01-16 19:20:47 -05:00
2022-08-19 16:12:42 -04:00
// TODO: Disabled until warnings and errors related to loading a non-existent package have been fixed.
DISABLED_TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::FObjectHandle::Resolve Non Existent Target " , " [CoreUObject][ObjectHandle] " )
2020-10-21 17:56:05 -04:00
{
// Confirm we don't successfully resolve an incorrect reference to engine content
TestResolveFailure ( " /Engine/EngineResources/NonExistentPackageName_0 " , " DefaultTexture " ) ;
2022-08-16 15:53:22 -04:00
const FName TestPackageName ( TEXT ( " /Engine/Test/ObjectPtrDefaultSerialize/Transient " ) ) ;
UPackage * TestPackage = NewObject < UPackage > ( nullptr , TestPackageName , RF_Transient ) ;
TestPackage - > AddToRoot ( ) ;
2023-01-05 12:27:16 -05:00
UObject * TestSoftObject = NewObject < UObjectPtrTestClass > ( TestPackage , TEXT ( " DefaultSerializeObject " ) ) ;
2022-08-16 15:53:22 -04:00
ON_SCOPE_EXIT {
TestPackage - > RemoveFromRoot ( ) ;
} ;
TestResolveFailure ( " /Engine/Test/ObjectPtrDefaultSerialize/Transient " , " DefaultSerializeObject_DoesNotExist " ) ;
2020-10-21 17:56:05 -04:00
}
2022-08-16 15:53:22 -04:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::FObjectHandle::Resolve Script Target " , " [CoreUObject][ObjectHandle] " )
2020-10-21 17:56:05 -04:00
{
// Confirm we successfully resolve a correct reference to engine content
2023-01-16 19:20:47 -05:00
TestResolvableNonNull ( " /Script/CoreUObject " , " MetaData " , true ) ;
2020-10-21 17:56:05 -04:00
}
2023-01-16 19:20:47 -05:00
# endif
2023-01-05 12:27:16 -05:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::TObjectPtr::HandleNullGetClass " , " [CoreUObject][ObjectHandle] " )
2022-09-13 12:24:17 -04:00
{
TObjectPtr < UObject > Ptr = nullptr ;
TEST_TRUE ( TEXT ( " TObjectPtr.GetClass should return null on a null object " ) , Ptr . GetClass ( ) = = nullptr ) ;
}
2023-01-05 12:27:16 -05:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
TEST_CASE ( " CoreUObject::FObjectHandle::Names " )
{
const FName TestPackageName ( TEXT ( " /Engine/Test/PackageResolve/Transient " ) ) ;
UPackage * TestPackage = NewObject < UPackage > ( nullptr , TestPackageName , RF_Transient ) ;
TestPackage - > AddToRoot ( ) ;
UObject * Obj1 = NewObject < UObjectPtrTestClass > ( TestPackage , TEXT ( " DefaultSerializeObject " ) ) ;
ON_SCOPE_EXIT {
TestPackage - > RemoveFromRoot ( ) ;
} ;
2023-06-01 18:45:09 -04:00
FObjectPtr Test ;
2023-01-16 19:20:47 -05:00
FObjectPtr PackagePtr ( MakeUnresolvedHandle ( TestPackage ) ) ;
FObjectPtr Obj1Ptr ( MakeUnresolvedHandle ( Obj1 ) ) ;
2023-01-05 12:27:16 -05:00
CHECK ( ! PackagePtr . IsResolved ( ) ) ;
CHECK ( TestPackage - > GetPathName ( ) = = PackagePtr . GetPathName ( ) ) ;
CHECK ( TestPackage - > GetFName ( ) = = PackagePtr . GetFName ( ) ) ;
CHECK ( TestPackage - > GetName ( ) = = PackagePtr . GetName ( ) ) ;
2023-06-01 18:45:09 -04:00
CHECK ( TestPackage - > GetFullName ( ) = = PackagePtr . GetFullName ( ) ) ;
2023-01-05 12:27:16 -05:00
CHECK ( ! PackagePtr . IsResolved ( ) ) ;
CHECK ( ! Obj1Ptr . IsResolved ( ) ) ;
CHECK ( Obj1 - > GetPathName ( ) = = Obj1Ptr . GetPathName ( ) ) ;
CHECK ( Obj1 - > GetFName ( ) = = Obj1Ptr . GetFName ( ) ) ;
CHECK ( Obj1 - > GetName ( ) = = Obj1Ptr . GetName ( ) ) ;
2023-06-01 18:45:09 -04:00
CHECK ( Obj1 - > GetFullName ( ) = = Obj1Ptr . GetFullName ( ) ) ;
2023-01-05 12:27:16 -05:00
CHECK ( ! Obj1Ptr . IsResolved ( ) ) ;
}
# endif
2023-01-16 19:20:47 -05:00
# if UE_WITH_OBJECT_HANDLE_TRACKING || UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2023-01-05 12:27:16 -05:00
TEST_CASE ( " CoreUObject::ObjectRef " )
{
const FName TestPackageName ( TEXT ( " /Engine/Test/ObjectRef/Transient " ) ) ;
UPackage * TestPackage = NewObject < UPackage > ( nullptr , TestPackageName , RF_Transient ) ;
TestPackage - > AddToRoot ( ) ;
UObject * Obj1 = NewObject < UObjectPtrTestClass > ( TestPackage , TEXT ( " DefaultSerializeObject " ) ) ;
UObject * Inner1 = NewObject < UObjectPtrTestClass > ( Obj1 , TEXT ( " Inner " ) ) ;
ON_SCOPE_EXIT {
TestPackage - > RemoveFromRoot ( ) ;
} ;
{
FObjectImport ObjectImport ( Obj1 ) ;
2023-01-16 19:20:47 -05:00
FObjectRef ObjectRef ( Obj1 ) ;
2023-01-05 12:27:16 -05:00
CHECK ( ObjectImport . ClassPackage = = ObjectRef . ClassPackageName ) ;
CHECK ( ObjectImport . ClassName = = ObjectRef . ClassName ) ;
CHECK ( TestPackage - > GetFName ( ) = = ObjectRef . PackageName ) ;
}
{
FObjectImport ObjectImport ( Inner1 ) ;
2023-01-16 19:20:47 -05:00
FObjectRef ObjectRef ( Inner1 ) ;
2023-01-05 12:27:16 -05:00
CHECK ( ObjectImport . ClassPackage = = ObjectRef . ClassPackageName ) ;
CHECK ( ObjectImport . ClassName = = ObjectRef . ClassName ) ;
CHECK ( TestPackage - > GetFName ( ) = = ObjectRef . PackageName ) ;
}
}
2023-01-16 19:20:47 -05:00
# endif
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2022-10-07 13:42:37 -04:00
2022-10-06 19:49:55 -04:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::TObjectPtr::Null Behavior " , " [CoreUObject][ObjectHandle] " )
{
TObjectPtr < UObject > Ptr = nullptr ;
2023-01-05 12:27:16 -05:00
UObjectPtrTestClass * TestObject = nullptr ;
2022-10-06 19:49:55 -04:00
uint32 ResolveCount = 0 ;
2023-01-19 16:34:29 -05:00
auto ResolveDelegate = [ & ResolveCount ] ( const FObjectRef & SourceRef , UPackage * ObjectPackage , UObject * Object )
2022-10-06 19:49:55 -04:00
{
+ + ResolveCount ;
2023-01-19 16:34:29 -05:00
} ;
auto Handle = UE : : CoreUObject : : AddObjectHandleReferenceResolvedCallback ( ResolveDelegate ) ;
ON_SCOPE_EXIT
{
UE : : CoreUObject : : RemoveObjectHandleReferenceResolvedCallback ( Handle ) ;
} ;
2022-10-06 19:49:55 -04:00
//compare against all flavours of nullptr, should not try and resolve this pointer
CHECK ( Ptr = = nullptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( nullptr = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( Ptr ! = nullptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( nullptr ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( ! Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
//using an if otherwise the macros try to convert to a pointer and not use the bool operator
if ( Ptr )
{
CHECK ( false ) ;
}
else
{
CHECK ( true ) ;
}
CHECK ( ResolveCount = = 0u ) ;
CHECK ( Ptr = = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( TestObject = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( Ptr ! = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( TestObject ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
2023-01-16 19:20:47 -05:00
FObjectRef TargetRef ( FName ( " SomePackage " ) , FName ( " ClassPackageName " ) , FName ( " ClassName " ) , UE : : CoreUObject : : Private : : FObjectPathId ( " ObjectName " ) ) ;
UE : : CoreUObject : : Private : : FPackedObjectRef PackedObjectRef = UE : : CoreUObject : : Private : : MakePackedObjectRef ( TargetRef ) ;
FObjectPtr ObjectPtr ( { PackedObjectRef . EncodedRef } ) ;
2022-10-06 19:49:55 -04:00
REQUIRE ( ! ObjectPtr . IsResolved ( ) ) ; //make sure not resolved
//an unresolved pointers compared against nullptr should still not resolve
Ptr = * reinterpret_cast < TObjectPtr < UObject > * > ( & ObjectPtr ) ;
CHECK_FALSE ( Ptr = = nullptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( nullptr = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( Ptr ! = nullptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( nullptr ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( ! Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
//using an if otherwise the macros try to convert to a pointer and not use the bool operator
if ( Ptr )
{
CHECK ( true ) ;
}
else
{
CHECK ( false ) ;
}
CHECK ( ResolveCount = = 0u ) ;
//test an unresolve pointer against a null raw pointer
CHECK_FALSE ( Ptr = = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( TestObject = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( Ptr ! = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( TestObject ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
//creating a real object for something that can resolve
const FName TestPackageName ( TEXT ( " /Engine/Test/ObjectPtrDefaultSerialize/Transient " ) ) ;
UPackage * TestPackage = NewObject < UPackage > ( nullptr , TestPackageName , RF_Transient ) ;
TestPackage - > AddToRoot ( ) ;
const FName TestObjectName ( TEXT ( " MyObject " ) ) ;
2023-01-05 12:27:16 -05:00
TestObject = NewObject < UObjectPtrTestClass > ( TestPackage , TestObjectName , RF_Transient ) ;
TObjectPtr < UObject > TestNotLazyObject = NewObject < UObjectPtrNotLazyTestClass > ( TestPackage , TEXT ( " NotLazy " ) , RF_Transient ) ;
2022-10-06 19:49:55 -04:00
2023-01-05 12:27:16 -05:00
//compare resolved ptr against nullptr
TObjectPtr < UObject > ResolvedPtr = TestObject ;
CHECK ( ResolvedPtr . IsResolved ( ) ) ;
CHECK ( Ptr ! = ResolvedPtr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( ResolvedPtr ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( Ptr = = ResolvedPtr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( ResolvedPtr = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
//compare unresolved against nullptr
2023-01-16 19:20:47 -05:00
FObjectPtr FPtr ( MakeUnresolvedHandle ( TestObject ) ) ;
2023-01-05 12:27:16 -05:00
TObjectPtr < UObject > UnResolvedPtr = * reinterpret_cast < TObjectPtr < UObject > * > ( & FPtr ) ;
CHECK ( ! UnResolvedPtr . IsResolved ( ) ) ;
CHECK_FALSE ( Ptr = = UnResolvedPtr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( UnResolvedPtr = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( Ptr ! = UnResolvedPtr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( UnResolvedPtr ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
//compare unresolved against resolved not equal
CHECK_FALSE ( TestNotLazyObject = = UnResolvedPtr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( UnResolvedPtr = = TestNotLazyObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( TestNotLazyObject ! = UnResolvedPtr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( UnResolvedPtr ! = TestNotLazyObject ) ; CHECK ( ResolveCount = = 0u ) ;
//compare resolved against naked pointer
2022-10-06 19:49:55 -04:00
Ptr = TestObject ;
REQUIRE ( Ptr . IsResolved ( ) ) ;
CHECK ( Ptr = = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( TestObject = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( Ptr ! = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( TestObject ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
2023-01-05 12:27:16 -05:00
//compare resolved pointer and unresolved of the same object
CHECK ( Ptr = = UnResolvedPtr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( UnResolvedPtr = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( Ptr ! = UnResolvedPtr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( UnResolvedPtr ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
2022-10-06 19:49:55 -04:00
TestObject = nullptr ;
CHECK_FALSE ( Ptr = = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( TestObject = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( Ptr ! = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( TestObject ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
2023-01-05 12:27:16 -05:00
TestObject = static_cast < UObjectPtrTestClass * > ( Ptr . Get ( ) ) ;
2022-10-06 19:49:55 -04:00
Ptr = nullptr ;
CHECK_FALSE ( Ptr = = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK_FALSE ( TestObject = = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( Ptr ! = TestObject ) ; CHECK ( ResolveCount = = 0u ) ;
CHECK ( TestObject ! = Ptr ) ; CHECK ( ResolveCount = = 0u ) ;
2023-03-02 20:28:39 -05:00
2022-10-06 19:49:55 -04:00
}
2022-10-07 13:42:37 -04:00
# endif
2021-03-02 14:39:53 -04:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2022-03-31 07:45:37 -04:00
2022-04-07 10:34:55 -04:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::FObjectHandle::Resolve Malformed Handle " , " [CoreUObject][ObjectHandle] " )
2021-03-02 14:39:53 -04:00
{
2023-06-01 18:45:09 -04:00
// make one packed ref guarantee something is in the object handle index
FObjectRef TargetRef ( FName ( " /Test/DummyPackage " ) , FName ( " ClassPackageName " ) , FName ( " ClassName " ) , UE : : CoreUObject : : Private : : FObjectPathId ( " DummyObjectName " ) ) ;
UE : : CoreUObject : : Private : : MakePackedObjectRef ( TargetRef ) ;
uint32 ObjectId = ~ 0u ;
UPTRINT PackedId = ObjectId < < 1 | 1 ;
UE : : CoreUObject : : Private : : FPackedObjectRef PackedObjectRef = { PackedId } ;
TestResolveFailure ( PackedObjectRef ) ; // packed ref has a valid package id but invalid object id
2023-01-16 19:20:47 -05:00
TestResolveFailure ( UE : : CoreUObject : : Private : : FPackedObjectRef { 0xFFFF'FFFF'FFFF'FFFFull } ) ;
TestResolveFailure ( UE : : CoreUObject : : Private : : FPackedObjectRef { 0xEFEF'EFEF'EFEF'EFEFull } ) ;
2021-03-02 14:39:53 -04:00
}
# endif // UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2022-04-20 14:24:59 -04:00
2023-04-26 19:52:36 -04:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::FObjectHandle::Hash Object Without Index " , " [CoreUObject][ObjectHandle] " )
{
UObject DummyObjectWithInvalidIndex ( EC_StaticConstructor , RF_NoFlags ) ;
CHECK ( DummyObjectWithInvalidIndex . GetUniqueID ( ) = = - 1 ) ;
FObjectHandle DummyObjectHandle = UE : : CoreUObject : : Private : : MakeObjectHandle ( & DummyObjectWithInvalidIndex ) ;
2023-04-26 19:53:27 -04:00
CHECK ( GetTypeHash ( DummyObjectHandle ) = = GetTypeHash ( & DummyObjectWithInvalidIndex ) ) ;
2023-04-26 19:52:36 -04:00
}
2024-02-07 10:34:24 -05:00
# if UE_WITH_OBJECT_HANDLE_TYPE_SAFETY
2024-02-13 16:53:52 -05:00
TEST_CASE_METHOD ( FObjectHandleTestBase , " CoreUObject::FObjectHandle::Type Safety " , " [CoreUObject][ObjectHandle] " )
2024-02-07 10:34:24 -05:00
{
const FName TestPackageName ( TEXT ( " /Engine/Test/ObjectHandle/TypeSafety/Transient " ) ) ;
UPackage * TestPackage = NewObject < UPackage > ( nullptr , TestPackageName , RF_Transient ) ;
TestPackage - > AddToRoot ( ) ;
ON_SCOPE_EXIT
{
TestPackage - > RemoveFromRoot ( ) ;
} ;
2024-05-02 11:25:44 -04:00
// construct an unsafe class type
UClass * TestUnsafeClass = UE : : FPropertyBagRepository : : CreatePropertyBagPlaceholderClass ( TestPackage , UClass : : StaticClass ( ) , TEXT ( " TestUnsafeClass " ) ) ;
2024-02-07 10:34:24 -05:00
// construct objects for testing
2024-03-22 11:12:08 -04:00
UObjectPtrTestClass * TestSafeObject = NewObject < UObjectPtrTestClass > ( TestPackage , TEXT ( " TestSafeObject " ) , RF_Transient ) ;
2024-05-02 11:25:44 -04:00
UObject * TestUnsafeObject = NewObject < UObject > ( TestPackage , TestUnsafeClass , TEXT ( " TestUnsafeObject " ) , RF_Transient ) ;
2024-02-07 10:34:24 -05:00
// construct object handles for testing
FObjectHandle NullObjectHandle = UE : : CoreUObject : : Private : : MakeObjectHandle ( nullptr ) ;
FObjectHandle TestSafeObjectHandle = UE : : CoreUObject : : Private : : MakeObjectHandle ( TestSafeObject ) ;
FObjectHandle TestUnsafeObjectHandle = UE : : CoreUObject : : Private : : MakeObjectHandle ( TestUnsafeObject ) ;
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2024-05-02 11:25:44 -04:00
FObjectHandle TestLateResolveSafeObjectHandle = { UE : : CoreUObject : : Private : : MakePackedObjectRef ( TestSafeObject ) . EncodedRef } ;
FObjectHandle TestLateResolveUnsafeObjectHandle = { UE : : CoreUObject : : Private : : MakePackedObjectRef ( TestUnsafeObject ) . EncodedRef } ;
2024-02-07 10:34:24 -05:00
# endif
2024-05-02 11:25:44 -04:00
// NULL/type-safe object handles should report as being safe
2024-02-07 10:34:24 -05:00
CHECK ( IsObjectHandleTypeSafe ( NullObjectHandle ) ) ;
CHECK ( IsObjectHandleTypeSafe ( TestSafeObjectHandle ) ) ;
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2024-05-02 11:25:44 -04:00
CHECK ( IsObjectHandleTypeSafe ( TestLateResolveSafeObjectHandle ) ) ;
2024-02-07 10:34:24 -05:00
# endif
2024-05-02 11:25:44 -04:00
// unsafe type object handles should report as being unsafe, but only when late resolve is enabled (required for support)
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2024-02-07 10:34:24 -05:00
CHECK_FALSE ( IsObjectHandleTypeSafe ( TestUnsafeObjectHandle ) ) ;
2024-05-02 11:25:44 -04:00
CHECK_FALSE ( IsObjectHandleTypeSafe ( TestLateResolveUnsafeObjectHandle ) ) ;
# else
CHECK ( IsObjectHandleTypeSafe ( TestUnsafeObjectHandle ) ) ;
# endif
2024-02-07 10:34:24 -05:00
2024-05-02 11:25:44 -04:00
// unsafe type object handles should resolve the class to the unsafe type
CHECK ( UE : : CoreUObject : : Private : : ResolveObjectHandleClass ( TestUnsafeObjectHandle ) = = TestUnsafeClass ) ;
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( UE : : CoreUObject : : Private : : ResolveObjectHandleClass ( TestLateResolveUnsafeObjectHandle ) = = TestUnsafeClass ) ;
# endif
2024-02-07 10:34:24 -05:00
2024-05-02 11:25:44 -04:00
// an unsafe type object handle should not equate to other unsafe type object handles (including NULL), except for itself
CHECK ( NullObjectHandle ! = TestUnsafeObjectHandle ) ; // note: this behavior intentionally differs from object *pointers* (see below)
2024-02-13 16:53:52 -05:00
CHECK ( TestUnsafeObjectHandle ! = NullObjectHandle ) ; // see note directly above
CHECK ( TestSafeObjectHandle ! = TestUnsafeObjectHandle ) ;
CHECK ( TestUnsafeObjectHandle ! = TestSafeObjectHandle ) ;
CHECK ( TestUnsafeObjectHandle = = TestUnsafeObjectHandle ) ;
2024-05-02 11:25:44 -04:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( NullObjectHandle ! = TestLateResolveUnsafeObjectHandle ) ;
CHECK ( TestLateResolveUnsafeObjectHandle ! = NullObjectHandle ) ;
CHECK ( TestSafeObjectHandle ! = TestLateResolveUnsafeObjectHandle ) ;
CHECK ( TestLateResolveUnsafeObjectHandle ! = TestSafeObjectHandle ) ;
CHECK ( TestUnsafeObjectHandle = = TestLateResolveUnsafeObjectHandle ) ;
CHECK ( TestLateResolveUnsafeObjectHandle = = TestUnsafeObjectHandle ) ;
CHECK ( TestLateResolveSafeObjectHandle ! = TestLateResolveUnsafeObjectHandle ) ;
CHECK ( TestLateResolveUnsafeObjectHandle ! = TestLateResolveSafeObjectHandle ) ;
CHECK ( TestLateResolveUnsafeObjectHandle = = TestLateResolveUnsafeObjectHandle ) ;
# endif
2024-02-13 16:53:52 -05:00
2024-05-02 11:25:44 -04:00
// the type safety and class queries above should not have resolved an object handle that's using late resolve
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK_FALSE ( IsObjectHandleResolved ( TestLateResolveSafeObjectHandle ) ) ;
CHECK_FALSE ( IsObjectHandleResolved ( TestLateResolveUnsafeObjectHandle ) ) ;
# endif
2024-03-22 11:12:08 -04:00
2024-05-02 11:25:44 -04:00
// unsafe type object handles should resolve/evaluate to the original type object
CHECK ( UE : : CoreUObject : : Private : : ResolveObjectHandle ( TestSafeObjectHandle ) = = TestSafeObject ) ;
CHECK ( UE : : CoreUObject : : Private : : ResolveObjectHandle ( TestUnsafeObjectHandle ) = = TestUnsafeObject ) ;
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( UE : : CoreUObject : : Private : : ResolveObjectHandle ( TestLateResolveSafeObjectHandle ) = = TestSafeObject ) ;
CHECK ( UE : : CoreUObject : : Private : : ResolveObjectHandle ( TestLateResolveUnsafeObjectHandle ) = = TestUnsafeObject ) ;
# endif
// all handles should now report as being resolved
CHECK ( IsObjectHandleResolved ( NullObjectHandle ) ) ;
CHECK ( IsObjectHandleResolved ( TestSafeObjectHandle ) ) ;
CHECK ( IsObjectHandleResolved ( TestUnsafeObjectHandle ) ) ;
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( IsObjectHandleResolved ( TestLateResolveSafeObjectHandle ) ) ;
CHECK ( IsObjectHandleResolved ( TestLateResolveUnsafeObjectHandle ) ) ;
# endif
// construct object pointers for testing intentionally different behaviors of UObject-type vs. non-UObject-type bindings
2024-02-07 10:34:24 -05:00
TObjectPtr < UObject > NullObjectPtr ( nullptr ) ;
2024-05-02 11:25:44 -04:00
TObjectPtr < UObject > TestSafeObjectPtr ( TestUnsafeObject ) ; // type safe pointer to placeholder (bound to UObject type)
2024-05-14 20:34:55 -04:00
TObjectPtr < const UObject > TestSafeConstObjectPtr ( TestUnsafeObject ) ; // type safe const pointer to placeholder (bound to UObject type)
2024-03-22 11:12:08 -04:00
FObjectPtr TestUnsafeObjectPtr_Untyped ( TestUnsafeObject ) ;
2024-05-02 11:25:44 -04:00
TObjectPtr < UObjectPtrTestClass > TestUnsafeObjectPtr ( TestUnsafeObjectPtr_Untyped ) ; // unsafe pointer to placeholder object (bound to non-UObject type)
2024-05-14 20:34:55 -04:00
TObjectPtr < const UObjectPtrTestClass > TestUnsafeConstObjectPtr ( TestUnsafeObjectPtr_Untyped ) ; // unsafe const pointer to placeholder object (bound to non-UObject type)
2024-05-02 11:25:44 -04:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
// note: "safe" in this context means the pointer should be type safe because it's bound to the UObject base type, but both reference the same "unsafe" object
TObjectPtr < UObject > TestLateResolveSafeObjectPtr ( FObjectPtr ( { UE : : CoreUObject : : Private : : MakePackedObjectRef ( TestUnsafeObject ) . EncodedRef } ) ) ;
2024-05-14 20:34:55 -04:00
TObjectPtr < const UObject > TestLateResolveSafeConstObjectPtr ( FObjectPtr ( { UE : : CoreUObject : : Private : : MakePackedObjectRef ( TestUnsafeObject ) . EncodedRef } ) ) ;
2024-05-02 11:25:44 -04:00
TObjectPtr < UObjectPtrTestClass > TestLateResolveUnsafeObjectPtr ( FObjectPtr ( { UE : : CoreUObject : : Private : : MakePackedObjectRef ( TestUnsafeObject ) . EncodedRef } ) ) ;
2024-05-14 20:34:55 -04:00
TObjectPtr < const UObjectPtrTestClass > TestLateResolveUnsafeConstObjectPtr ( FObjectPtr ( { UE : : CoreUObject : : Private : : MakePackedObjectRef ( TestUnsafeObject ) . EncodedRef } ) ) ;
2024-05-02 11:25:44 -04:00
# endif
// an unsafe packed object reference should now exist with the unsafe type bit set for an unsafe object reference
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( ( UE : : CoreUObject : : Private : : FindExistingPackedObjectRef ( TestUnsafeObject ) . EncodedRef & ( 1 < < UE : : CoreUObject : : Private : : TypeIdShift ) ) ! = 0 ) ;
# endif
2024-03-22 11:12:08 -04:00
// type safe object pointers should evaluate to true/non-NULL
CHECK ( TestSafeObjectPtr ) ;
CHECK ( ! ! TestSafeObjectPtr ) ;
CHECK ( NULL ! = TestSafeObjectPtr ) ;
CHECK ( TestSafeObjectPtr ! = NULL ) ;
CHECK ( nullptr ! = TestSafeObjectPtr ) ;
CHECK ( TestSafeObjectPtr ! = nullptr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestSafeConstObjectPtr ) ;
CHECK ( ! ! TestSafeConstObjectPtr ) ;
CHECK ( NULL ! = TestSafeConstObjectPtr ) ;
CHECK ( TestSafeConstObjectPtr ! = NULL ) ;
CHECK ( nullptr ! = TestSafeConstObjectPtr ) ;
CHECK ( TestSafeConstObjectPtr ! = nullptr ) ;
2024-05-02 11:25:44 -04:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( TestLateResolveSafeObjectPtr ) ;
CHECK ( ! ! TestLateResolveSafeObjectPtr ) ;
CHECK ( NULL ! = TestLateResolveSafeObjectPtr ) ;
CHECK ( TestLateResolveSafeObjectPtr ! = NULL ) ;
CHECK ( nullptr ! = TestLateResolveSafeObjectPtr ) ;
CHECK ( TestLateResolveSafeObjectPtr ! = nullptr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestLateResolveSafeConstObjectPtr ) ;
CHECK ( ! ! TestLateResolveSafeConstObjectPtr ) ;
CHECK ( NULL ! = TestLateResolveSafeConstObjectPtr ) ;
CHECK ( TestLateResolveSafeConstObjectPtr ! = NULL ) ;
CHECK ( nullptr ! = TestLateResolveSafeConstObjectPtr ) ;
CHECK ( TestLateResolveSafeConstObjectPtr ! = nullptr ) ;
2024-05-02 11:25:44 -04:00
# endif
2024-02-07 10:34:24 -05:00
2024-05-02 11:25:44 -04:00
// unsafe type object pointers should evaluate to NULL/false (for type safety), but only when late resolve is enabled (required for support)
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK_FALSE ( TestUnsafeObjectPtr ) ;
2024-02-07 10:34:24 -05:00
CHECK_FALSE ( ! ! TestUnsafeObjectPtr ) ;
2024-02-13 16:53:52 -05:00
CHECK ( NULL = = TestUnsafeObjectPtr ) ;
CHECK ( TestUnsafeObjectPtr = = NULL ) ;
2024-02-07 10:34:24 -05:00
CHECK ( nullptr = = TestUnsafeObjectPtr ) ;
CHECK ( TestUnsafeObjectPtr = = nullptr ) ;
2024-05-14 20:34:55 -04:00
CHECK_FALSE ( TestUnsafeConstObjectPtr ) ;
CHECK_FALSE ( ! ! TestUnsafeConstObjectPtr ) ;
CHECK ( NULL = = TestUnsafeConstObjectPtr ) ;
CHECK ( TestUnsafeConstObjectPtr = = NULL ) ;
CHECK ( nullptr = = TestUnsafeConstObjectPtr ) ;
CHECK ( TestUnsafeConstObjectPtr = = nullptr ) ;
2024-05-02 11:25:44 -04:00
CHECK_FALSE ( TestLateResolveUnsafeObjectPtr ) ;
CHECK_FALSE ( ! ! TestLateResolveUnsafeObjectPtr ) ;
CHECK ( NULL = = TestLateResolveUnsafeObjectPtr ) ;
CHECK ( TestLateResolveUnsafeObjectPtr = = NULL ) ;
CHECK ( nullptr = = TestLateResolveUnsafeObjectPtr ) ;
CHECK ( TestLateResolveUnsafeObjectPtr = = nullptr ) ;
2024-05-14 20:34:55 -04:00
CHECK_FALSE ( TestLateResolveUnsafeConstObjectPtr ) ;
CHECK_FALSE ( ! ! TestLateResolveUnsafeConstObjectPtr ) ;
CHECK ( NULL = = TestLateResolveUnsafeConstObjectPtr ) ;
CHECK ( TestLateResolveUnsafeConstObjectPtr = = NULL ) ;
CHECK ( nullptr = = TestLateResolveUnsafeConstObjectPtr ) ;
CHECK ( TestLateResolveUnsafeConstObjectPtr = = nullptr ) ;
2024-05-02 11:25:44 -04:00
# else
CHECK ( TestUnsafeObjectPtr ) ;
CHECK ( ! ! TestUnsafeObjectPtr ) ;
CHECK ( NULL ! = TestUnsafeObjectPtr ) ;
CHECK ( TestUnsafeObjectPtr ! = NULL ) ;
CHECK ( nullptr ! = TestUnsafeObjectPtr ) ;
CHECK ( TestUnsafeObjectPtr ! = nullptr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestUnsafeConstObjectPtr ) ;
CHECK ( ! ! TestUnsafeConstObjectPtr ) ;
CHECK ( NULL ! = TestUnsafeConstObjectPtr ) ;
CHECK ( TestUnsafeConstObjectPtr ! = NULL ) ;
CHECK ( nullptr ! = TestUnsafeConstObjectPtr ) ;
CHECK ( TestUnsafeConstObjectPtr ! = nullptr ) ;
2024-05-02 11:25:44 -04:00
# endif
2024-02-07 10:34:24 -05:00
2024-05-02 11:25:44 -04:00
// an unsafe type object pointer should not equate to other unsafe type object pointers, excluding NULL and itself
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( NullObjectPtr = = TestUnsafeObjectPtr ) ; // note: this intentionally differs from object *handles* (see above), and depends on late resolve
2024-02-13 16:53:52 -05:00
CHECK ( TestUnsafeObjectPtr = = NullObjectPtr ) ; // see note directly above
2024-05-14 20:34:55 -04:00
CHECK ( NullObjectPtr = = TestUnsafeConstObjectPtr ) ;
CHECK ( TestUnsafeConstObjectPtr = = NullObjectPtr ) ;
2024-05-02 11:25:44 -04:00
CHECK ( NullObjectPtr ! = TestLateResolveSafeObjectPtr ) ;
CHECK ( TestLateResolveSafeObjectPtr ! = NullObjectPtr ) ;
CHECK ( NullObjectPtr = = TestLateResolveUnsafeObjectPtr ) ;
CHECK ( TestLateResolveUnsafeObjectPtr = = NullObjectPtr ) ;
CHECK ( TestSafeObjectPtr ! = TestLateResolveUnsafeObjectPtr ) ;
CHECK ( TestLateResolveUnsafeObjectPtr ! = TestSafeObjectPtr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( NullObjectPtr ! = TestLateResolveSafeConstObjectPtr ) ;
CHECK ( TestLateResolveSafeConstObjectPtr ! = NullObjectPtr ) ;
CHECK ( NullObjectPtr = = TestLateResolveUnsafeConstObjectPtr ) ;
CHECK ( TestLateResolveUnsafeConstObjectPtr = = NullObjectPtr ) ;
CHECK ( TestSafeConstObjectPtr ! = TestLateResolveUnsafeConstObjectPtr ) ;
CHECK ( TestLateResolveUnsafeConstObjectPtr ! = TestSafeConstObjectPtr ) ;
2024-05-02 11:25:44 -04:00
CHECK ( TestUnsafeObjectPtr = = TestLateResolveUnsafeObjectPtr ) ;
CHECK ( TestLateResolveUnsafeObjectPtr = = TestUnsafeObjectPtr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestUnsafeConstObjectPtr = = TestLateResolveUnsafeConstObjectPtr ) ;
CHECK ( TestLateResolveUnsafeConstObjectPtr = = TestUnsafeConstObjectPtr ) ;
2024-05-02 11:25:44 -04:00
CHECK ( TestLateResolveSafeObjectPtr ! = TestLateResolveUnsafeObjectPtr ) ;
CHECK ( TestLateResolveUnsafeObjectPtr ! = TestLateResolveSafeObjectPtr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestLateResolveSafeConstObjectPtr ! = TestLateResolveUnsafeConstObjectPtr ) ;
CHECK ( TestLateResolveUnsafeConstObjectPtr ! = TestLateResolveSafeConstObjectPtr ) ;
2024-05-02 11:25:44 -04:00
CHECK ( TestLateResolveUnsafeObjectPtr = = TestLateResolveUnsafeObjectPtr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestLateResolveUnsafeConstObjectPtr = = TestLateResolveUnsafeConstObjectPtr ) ;
2024-05-02 11:25:44 -04:00
# else
CHECK ( NullObjectPtr ! = TestUnsafeObjectPtr ) ; // note: if late resolve is disabled, these will no longer be equivalent
CHECK ( TestUnsafeObjectPtr ! = NullObjectPtr ) ; // see note directly above
2024-05-14 20:34:55 -04:00
CHECK ( NullObjectPtr ! = TestUnsafeConstObjectPtr ) ;
CHECK ( TestUnsafeConstObjectPtr ! = NullObjectPtr ) ;
2024-05-02 11:25:44 -04:00
# endif
2024-02-07 10:34:24 -05:00
// an unsafe type object should evaluate the object's attributes correctly
CHECK ( TestUnsafeObjectPtr . GetName ( ) = = TestUnsafeObject - > GetName ( ) ) ;
CHECK ( TestUnsafeObjectPtr . GetFName ( ) = = TestUnsafeObject - > GetFName ( ) ) ;
CHECK ( TestUnsafeObjectPtr . GetPathName ( ) = = TestUnsafeObject - > GetPathName ( ) ) ;
CHECK ( TestUnsafeObjectPtr . GetFullName ( ) = = TestUnsafeObject - > GetFullName ( ) ) ;
CHECK ( TestUnsafeObjectPtr . GetOuter ( ) = = TestUnsafeObject - > GetOuter ( ) ) ;
2024-03-22 11:12:08 -04:00
CHECK ( TestUnsafeObjectPtr . GetClass ( ) = = TestUnsafeObject - > GetClass ( ) ) ;
2024-02-07 10:34:24 -05:00
CHECK ( TestUnsafeObjectPtr . GetPackage ( ) = = TestUnsafeObject - > GetPackage ( ) ) ;
2024-05-02 11:25:44 -04:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( TestLateResolveUnsafeObjectPtr . GetName ( ) = = TestUnsafeObject - > GetName ( ) ) ;
CHECK ( TestLateResolveUnsafeObjectPtr . GetFName ( ) = = TestUnsafeObject - > GetFName ( ) ) ;
CHECK ( TestLateResolveUnsafeObjectPtr . GetPathName ( ) = = TestUnsafeObject - > GetPathName ( ) ) ;
CHECK ( TestLateResolveUnsafeObjectPtr . GetFullName ( ) = = TestUnsafeObject - > GetFullName ( ) ) ;
CHECK ( TestLateResolveUnsafeObjectPtr . GetOuter ( ) = = TestUnsafeObject - > GetOuter ( ) ) ;
CHECK ( TestLateResolveUnsafeObjectPtr . GetClass ( ) = = TestUnsafeObject - > GetClass ( ) ) ;
CHECK ( TestLateResolveUnsafeObjectPtr . GetPackage ( ) = = TestUnsafeObject - > GetPackage ( ) ) ;
# endif
// the type safety and queries above should not have resolved an object pointer that's using late resolve
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK_FALSE ( TestLateResolveSafeObjectPtr . IsResolved ( ) ) ;
CHECK_FALSE ( TestLateResolveUnsafeObjectPtr . IsResolved ( ) ) ;
2024-05-14 20:34:55 -04:00
CHECK_FALSE ( TestLateResolveSafeConstObjectPtr . IsResolved ( ) ) ;
CHECK_FALSE ( TestLateResolveUnsafeConstObjectPtr . IsResolved ( ) ) ;
2024-05-02 11:25:44 -04:00
# endif
2024-02-07 10:34:24 -05:00
2024-03-22 11:12:08 -04:00
// a type safe object pointer should resolve to a non-NULL value when dereferenced
2024-05-02 11:25:44 -04:00
CHECK ( TestSafeObjectPtr . Get ( ) = = TestUnsafeObject ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestSafeConstObjectPtr . Get ( ) = = TestUnsafeObject ) ;
2024-05-02 11:25:44 -04:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( TestLateResolveSafeObjectPtr . Get ( ) = = TestUnsafeObject ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestLateResolveSafeConstObjectPtr . Get ( ) = = TestUnsafeObject ) ;
2024-05-02 11:25:44 -04:00
# endif
2024-02-07 10:34:24 -05:00
2024-05-02 11:25:44 -04:00
// an unsafe type object pointer should resolve to NULL when dereferenced (for type safety), but only when late resolve is enabled (required for support)
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
2024-02-07 10:34:24 -05:00
CHECK ( TestUnsafeObjectPtr . Get ( ) = = nullptr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestUnsafeConstObjectPtr . Get ( ) = = nullptr ) ;
2024-05-02 11:25:44 -04:00
CHECK ( TestLateResolveUnsafeObjectPtr . Get ( ) = = nullptr ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestLateResolveUnsafeConstObjectPtr . Get ( ) = = nullptr ) ;
2024-05-02 11:25:44 -04:00
# else
CHECK ( TestUnsafeObjectPtr . Get ( ) = = TestUnsafeObject ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestUnsafeConstObjectPtr . Get ( ) = = TestUnsafeObject ) ;
2024-05-02 11:25:44 -04:00
# endif
// all pointers should now be resolved
CHECK ( TestSafeObjectPtr . IsResolved ( ) ) ;
CHECK ( TestUnsafeObjectPtr . IsResolved ( ) ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestSafeConstObjectPtr . IsResolved ( ) ) ;
CHECK ( TestUnsafeConstObjectPtr . IsResolved ( ) ) ;
2024-05-02 11:25:44 -04:00
# if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK ( TestLateResolveSafeObjectPtr . IsResolved ( ) ) ;
CHECK ( TestLateResolveUnsafeObjectPtr . IsResolved ( ) ) ;
2024-05-14 20:34:55 -04:00
CHECK ( TestLateResolveSafeConstObjectPtr . IsResolved ( ) ) ;
CHECK ( TestLateResolveUnsafeConstObjectPtr . IsResolved ( ) ) ;
2024-05-02 11:25:44 -04:00
# endif
2024-02-07 10:34:24 -05:00
}
# endif
2023-01-05 12:27:16 -05:00
# endif