Files
UnrealEngineUWP/Engine/Source/Runtime/CoreUObject/Tests/ObjectHandleTest.cpp

685 lines
35 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#if WITH_LOW_LEVEL_TESTS
#include "ObjectPtrTestClass.h"
#include "UObject/ObjectHandle.h"
#include "UObject/ObjectPtr.h"
#include "UObject/Package.h"
#include "UObject/ObjectResource.h"
#include "UObject/MetaData.h"
#include "HAL/PlatformProperties.h"
#include "ObjectRefTrackingTestBase.h"
#include "IO/IoDispatcher.h"
#include "TestHarness.h"
#include "UObject/ObjectRef.h"
#include "UObject/ObjectPathId.h"
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#include "UObject/PropertyBagRepository.h"
static_assert(sizeof(FObjectHandle) == sizeof(void*), "FObjectHandle type must always compile to something equivalent to a pointer size.");
class FObjectHandleTestBase : public FObjectRefTrackingTestBase
{
public:
protected:
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
void TestResolveFailure(UE::CoreUObject::Private::FPackedObjectRef PackedRef)
{
FSnapshotObjectRefMetrics ObjectRefMetrics(*this);
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);
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, bExpectSubRefReads /*bAllowAdditionalReads*/);
ObjectRefMetrics.TestNumFailedResolves(TEXT("NumFailedResolves should not change after a successful resolve attempt"), 0);
}
void TestResolveFailure(const ANSICHAR* PackageName, const ANSICHAR* ObjectName)
{
FSnapshotObjectRefMetrics ObjectRefMetrics(*this);
FObjectRef TargetRef(FName(PackageName), NAME_None, NAME_None, UE::CoreUObject::Private::FObjectPathId(ObjectName));
const UObject* ResolvedObject = TargetRef.Resolve();
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);
Revision 2 (with handling for uninitialized object references): -Compile in lazy resolve functionality for editor binaries -Add "-LazyResolveAllImports" commandline switch to allow lazy RESOLVE of all wrapped object references -Functionality confirmed: load default map in ShooterGame Editor, cook ShooterGame, load LumenReflectiveTest in FortGPUTestbed, load default map and P_Construct in Frosty -Renamed "-DisableLoadingAllImports" to "-LazyLoadAllImports" commandline switch to allow lazy LOAD of all wrapped object references and ensured it works with AsyncLoading code path -Non functional when combined with lazy resolve - will be worked on afterwards -Added CPU timing scopes to measure performance impact of lazy resolve Fixed lazy resolve bugs: -Ensure null check on an unresolved object reference resolves the object reference (a non-null unresolved reference can become a null resolved reference) -Ensure hash of an unresolved object reference resolves the object reference and hashes the resultant address (otherwise we can't reliably ensure hash consistency in the face of object redirection or stale references) -Avoid using package name hash internally as it immediately manifested in hash collisions on a moderately sized project -Ensure StaticFindObjectFastInternal instead of StaticFindObjectFast to ensure we can find/resolve not fully loaded objects -Ensure UObjectRedirectors are handled when resolving wrapped object pointers -Ensure we handle the possibility that a package has been partially loaded and we may not find our target object within it because the object hasn't been created yet Automated testing: -Adding hash consistency and redirector resolve tests to ObjectPtr unit tests #rb devin.doucette [CL 15571874 by Zousar Shaker in ue5-main branch]
2021-03-02 14:39:53 -04:00
}
#endif
};
TEST_CASE_METHOD(FObjectHandleTestBase, "CoreUObject::FObjectHandle::Null Behavior", "[CoreUObject][ObjectHandle]")
{
FObjectHandle TargetHandle = UE::CoreUObject::Private::MakeObjectHandle(nullptr);
TEST_TRUE(TEXT("Handle to target is null"), IsObjectHandleNull(TargetHandle));
TEST_TRUE(TEXT("Handle to target is resolved"), IsObjectHandleResolved(TargetHandle));
FSnapshotObjectRefMetrics ObjectRefMetrics(*this);
UObject* ResolvedObject = UE::CoreUObject::Private::ResolveObjectHandle(TargetHandle);
TEST_EQUAL(TEXT("Resolved object is equal to original object"), (UObject*)nullptr, ResolvedObject);
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);
}
TEST_CASE_METHOD(FObjectHandleTestBase, "CoreUObject::FObjectHandle::Pointer Behavior", "[CoreUObject][ObjectHandle]")
{
FObjectHandle TargetHandle = UE::CoreUObject::Private::MakeObjectHandle((UObject*)0x0042);
TEST_FALSE(TEXT("Handle to target is null"), IsObjectHandleNull(TargetHandle));
TEST_TRUE(TEXT("Handle to target is resolved"), IsObjectHandleResolved(TargetHandle));
FSnapshotObjectRefMetrics ObjectRefMetrics(*this);
UObject* ResolvedObject = UE::CoreUObject::Private::ResolveObjectHandle(TargetHandle);
TEST_EQUAL(TEXT("Resolved object is equal to original object"), (UObject*)0x0042, ResolvedObject);
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);
}
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
TEST_CASE_METHOD(FObjectHandleTestBase, "CoreUObject::FObjectHandle::Resolve Engine Content Target", "[CoreUObject][ObjectHandle]")
{
const FName TestPackageName(TEXT("/Engine/Test/ObjectPtrDefaultSerialize/Transient"));
UPackage* TestPackage = NewObject<UPackage>(nullptr, TestPackageName, RF_Transient);
TestPackage->AddToRoot();
UObject* TestSoftObject = NewObject<UObjectPtrTestClass>(TestPackage, TEXT("DefaultSerializeObject"));
UObject* TestSubObject = NewObject<UObjectPtrTestClass>(TestSoftObject, TEXT("SubObject"));
ON_SCOPE_EXIT{
TestPackage->RemoveFromRoot();
};
TestResolvableNonNull("/Engine/Test/ObjectPtrDefaultSerialize/Transient", "DefaultSerializeObject.SubObject", true);
TestResolvableNonNull("/Engine/Test/ObjectPtrDefaultSerialize/Transient", "DefaultSerializeObject", false);
}
// 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]")
{
// Confirm we don't successfully resolve an incorrect reference to engine content
TestResolveFailure("/Engine/EngineResources/NonExistentPackageName_0", "DefaultTexture");
const FName TestPackageName(TEXT("/Engine/Test/ObjectPtrDefaultSerialize/Transient"));
UPackage* TestPackage = NewObject<UPackage>(nullptr, TestPackageName, RF_Transient);
TestPackage->AddToRoot();
UObject* TestSoftObject = NewObject<UObjectPtrTestClass>(TestPackage, TEXT("DefaultSerializeObject"));
ON_SCOPE_EXIT{
TestPackage->RemoveFromRoot();
};
TestResolveFailure("/Engine/Test/ObjectPtrDefaultSerialize/Transient", "DefaultSerializeObject_DoesNotExist");
}
TEST_CASE_METHOD(FObjectHandleTestBase, "CoreUObject::FObjectHandle::Resolve Script Target", "[CoreUObject][ObjectHandle]")
{
// Confirm we successfully resolve a correct reference to engine content
TestResolvableNonNull("/Script/CoreUObject", "MetaData", true);
}
#endif
TEST_CASE_METHOD(FObjectHandleTestBase, "CoreUObject::TObjectPtr::HandleNullGetClass", "[CoreUObject][ObjectHandle]")
{
TObjectPtr<UObject> Ptr = nullptr;
TEST_TRUE(TEXT("TObjectPtr.GetClass should return null on a null object"), Ptr.GetClass() == nullptr);
}
#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();
};
FObjectPtr Test;
FObjectPtr PackagePtr(MakeUnresolvedHandle(TestPackage));
FObjectPtr Obj1Ptr(MakeUnresolvedHandle(Obj1));
CHECK(!PackagePtr.IsResolved());
CHECK(TestPackage->GetPathName() == PackagePtr.GetPathName());
CHECK(TestPackage->GetFName() == PackagePtr.GetFName());
CHECK(TestPackage->GetName() == PackagePtr.GetName());
CHECK(TestPackage->GetFullName() == PackagePtr.GetFullName());
CHECK(!PackagePtr.IsResolved());
CHECK(!Obj1Ptr.IsResolved());
CHECK(Obj1->GetPathName() == Obj1Ptr.GetPathName());
CHECK(Obj1->GetFName() == Obj1Ptr.GetFName());
CHECK(Obj1->GetName() == Obj1Ptr.GetName());
CHECK(Obj1->GetFullName() == Obj1Ptr.GetFullName());
CHECK(!Obj1Ptr.IsResolved());
}
#endif
#if UE_WITH_OBJECT_HANDLE_TRACKING || UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
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);
FObjectRef ObjectRef(Obj1);
CHECK(ObjectImport.ClassPackage == ObjectRef.ClassPackageName);
CHECK(ObjectImport.ClassName == ObjectRef.ClassName);
CHECK(TestPackage->GetFName() == ObjectRef.PackageName);
}
{
FObjectImport ObjectImport(Inner1);
FObjectRef ObjectRef(Inner1);
CHECK(ObjectImport.ClassPackage == ObjectRef.ClassPackageName);
CHECK(ObjectImport.ClassName == ObjectRef.ClassName);
CHECK(TestPackage->GetFName() == ObjectRef.PackageName);
}
}
#endif
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
TEST_CASE_METHOD(FObjectHandleTestBase, "CoreUObject::TObjectPtr::Null Behavior", "[CoreUObject][ObjectHandle]")
{
TObjectPtr<UObject> Ptr = nullptr;
UObjectPtrTestClass* TestObject = nullptr;
uint32 ResolveCount = 0;
auto ResolveDelegate = [&ResolveCount](const FObjectRef& SourceRef, UPackage* ObjectPackage, UObject* Object)
{
++ResolveCount;
};
auto Handle = UE::CoreUObject::AddObjectHandleReferenceResolvedCallback(ResolveDelegate);
ON_SCOPE_EXIT
{
UE::CoreUObject::RemoveObjectHandleReferenceResolvedCallback(Handle);
};
//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);
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 });
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"));
TestObject = NewObject<UObjectPtrTestClass>(TestPackage, TestObjectName, RF_Transient);
TObjectPtr<UObject> TestNotLazyObject = NewObject<UObjectPtrNotLazyTestClass>(TestPackage, TEXT("NotLazy"), RF_Transient);
//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
FObjectPtr FPtr(MakeUnresolvedHandle(TestObject));
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
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);
//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);
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);
TestObject = static_cast<UObjectPtrTestClass*>(Ptr.Get());
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);
support for TObjectPtr handling renames and GetTypeHash(TObjectPtr) no long has to resolve GetTypeHash will create a packaged object ref for hashing if the class is defined as lazy load otherwise raw pointer is hashed a map was added for moved objects and ObjectPathId can be a WeakObjectPtr the map allows UObjects to be mapped back to packed object refs #rb zousar.shaker https://p4-swarm.epicgames.net/reviews/23356491 #preflight 63b5de641c35d1cbdbccecf7 #preflight 63b70406e26e31879b8aa6d3 code cleanup of ObjectHandle made ObjectPathId to private trimmed down the public API as much as possible https://p4-swarm.epicgames.net/reviews/23658342 #rb zousar.shaker #preflight 63c5c8922a6acaf1625fcf25 #[robomerge] FNMain changed ObjectHandleTracking to use Functions instead of delegates as the performance of delegate is poor https://p4-swarm.epicgames.net/reviews/23751084 #rb zousar.shaker #preflight 63c9ae14d45afa2a8fc37d9d changed FObjectPropertyBase::CheckValidObject to not resolve FObjectPtr fields to do validation this is needed for feature work with validation of accessing asset pointers during serialization https://p4-swarm.epicgames.net/reviews/23782822 #rb zousar.shaker #[fyi] francis.hurteau #preflight 63cf06efd83c1837b14e2aeb fix for ObjectHandleTracking initialization. order of global variable initialization was problematic move globals into a struct added a singleton for the struct to do lazy initialization https://p4-swarm.epicgames.net/reviews/23877016 #rb zousar.shaker #preflight 63d308a7f626715201408881 changed `FClassProperty::Identical` to use TObjectPtr to avoid causing unnecessary reads #rb zousar.shaker #preflight 63d804493656ea96dc13d296 changed FObjectProperty::SerializeItem to not cause object handle reads #preflight 63d837e91f0aa8a2897477ee #ushell-cherrypick of 23589497 by joe.pribele #ushell-cherrypick of 23734208 by joe.pribele #ushell-cherrypick of 23781117 by joe.pribele #ushell-cherrypick of 23823212 by joe.pribele #ushell-cherrypick of 23878025 by joe.pribele #ushell-cherrypick of 23912609 by joe.pribele #ushell-cherrypick of 23916733 by joe.pribele [CL 24493715 by joe pribele in ue5-main branch]
2023-03-02 20:28:39 -05:00
}
#endif
Revision 2 (with handling for uninitialized object references): -Compile in lazy resolve functionality for editor binaries -Add "-LazyResolveAllImports" commandline switch to allow lazy RESOLVE of all wrapped object references -Functionality confirmed: load default map in ShooterGame Editor, cook ShooterGame, load LumenReflectiveTest in FortGPUTestbed, load default map and P_Construct in Frosty -Renamed "-DisableLoadingAllImports" to "-LazyLoadAllImports" commandline switch to allow lazy LOAD of all wrapped object references and ensured it works with AsyncLoading code path -Non functional when combined with lazy resolve - will be worked on afterwards -Added CPU timing scopes to measure performance impact of lazy resolve Fixed lazy resolve bugs: -Ensure null check on an unresolved object reference resolves the object reference (a non-null unresolved reference can become a null resolved reference) -Ensure hash of an unresolved object reference resolves the object reference and hashes the resultant address (otherwise we can't reliably ensure hash consistency in the face of object redirection or stale references) -Avoid using package name hash internally as it immediately manifested in hash collisions on a moderately sized project -Ensure StaticFindObjectFastInternal instead of StaticFindObjectFast to ensure we can find/resolve not fully loaded objects -Ensure UObjectRedirectors are handled when resolving wrapped object pointers -Ensure we handle the possibility that a package has been partially loaded and we may not find our target object within it because the object hasn't been created yet Automated testing: -Adding hash consistency and redirector resolve tests to ObjectPtr unit tests #rb devin.doucette [CL 15571874 by Zousar Shaker in ue5-main branch]
2021-03-02 14:39:53 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
TEST_CASE_METHOD(FObjectHandleTestBase, "CoreUObject::FObjectHandle::Resolve Malformed Handle", "[CoreUObject][ObjectHandle]")
Revision 2 (with handling for uninitialized object references): -Compile in lazy resolve functionality for editor binaries -Add "-LazyResolveAllImports" commandline switch to allow lazy RESOLVE of all wrapped object references -Functionality confirmed: load default map in ShooterGame Editor, cook ShooterGame, load LumenReflectiveTest in FortGPUTestbed, load default map and P_Construct in Frosty -Renamed "-DisableLoadingAllImports" to "-LazyLoadAllImports" commandline switch to allow lazy LOAD of all wrapped object references and ensured it works with AsyncLoading code path -Non functional when combined with lazy resolve - will be worked on afterwards -Added CPU timing scopes to measure performance impact of lazy resolve Fixed lazy resolve bugs: -Ensure null check on an unresolved object reference resolves the object reference (a non-null unresolved reference can become a null resolved reference) -Ensure hash of an unresolved object reference resolves the object reference and hashes the resultant address (otherwise we can't reliably ensure hash consistency in the face of object redirection or stale references) -Avoid using package name hash internally as it immediately manifested in hash collisions on a moderately sized project -Ensure StaticFindObjectFastInternal instead of StaticFindObjectFast to ensure we can find/resolve not fully loaded objects -Ensure UObjectRedirectors are handled when resolving wrapped object pointers -Ensure we handle the possibility that a package has been partially loaded and we may not find our target object within it because the object hasn't been created yet Automated testing: -Adding hash consistency and redirector resolve tests to ObjectPtr unit tests #rb devin.doucette [CL 15571874 by Zousar Shaker in ue5-main branch]
2021-03-02 14:39:53 -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
TestResolveFailure(UE::CoreUObject::Private::FPackedObjectRef { 0xFFFF'FFFF'FFFF'FFFFull });
TestResolveFailure(UE::CoreUObject::Private::FPackedObjectRef { 0xEFEF'EFEF'EFEF'EFEFull });
Revision 2 (with handling for uninitialized object references): -Compile in lazy resolve functionality for editor binaries -Add "-LazyResolveAllImports" commandline switch to allow lazy RESOLVE of all wrapped object references -Functionality confirmed: load default map in ShooterGame Editor, cook ShooterGame, load LumenReflectiveTest in FortGPUTestbed, load default map and P_Construct in Frosty -Renamed "-DisableLoadingAllImports" to "-LazyLoadAllImports" commandline switch to allow lazy LOAD of all wrapped object references and ensured it works with AsyncLoading code path -Non functional when combined with lazy resolve - will be worked on afterwards -Added CPU timing scopes to measure performance impact of lazy resolve Fixed lazy resolve bugs: -Ensure null check on an unresolved object reference resolves the object reference (a non-null unresolved reference can become a null resolved reference) -Ensure hash of an unresolved object reference resolves the object reference and hashes the resultant address (otherwise we can't reliably ensure hash consistency in the face of object redirection or stale references) -Avoid using package name hash internally as it immediately manifested in hash collisions on a moderately sized project -Ensure StaticFindObjectFastInternal instead of StaticFindObjectFast to ensure we can find/resolve not fully loaded objects -Ensure UObjectRedirectors are handled when resolving wrapped object pointers -Ensure we handle the possibility that a package has been partially loaded and we may not find our target object within it because the object hasn't been created yet Automated testing: -Adding hash consistency and redirector resolve tests to ObjectPtr unit tests #rb devin.doucette [CL 15571874 by Zousar Shaker in ue5-main branch]
2021-03-02 14:39:53 -04:00
}
#endif // UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
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);
CHECK(GetTypeHash(DummyObjectHandle) == GetTypeHash(&DummyObjectWithInvalidIndex));
}
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
#if UE_WITH_OBJECT_HANDLE_TYPE_SAFETY
[UE]: More revisions to placeholder property bag type import/export serialization support during map asset loads in the editor. Change summary: - Modified ObjectPtr_Private::IsObjectPtrEqualToRawPtrOfRelatedType() to include a non-resolving NULL check for LHS. This allows unsafe type object pointers to equate to NULL object pointers (in addition to nullptr) - e.g. for compiled paths that do implicit type conversions from nullptr to TObjectPtr(nullptr). Also updated the unit test to reflect this behavior change. - Replaced FPropertyBagRepository::IsPropertyBagPlaceholderType() with IsPropertyBagPlaceholderObject(). - No longer setting RF_HasPlaceholderType on placeholder import type CDOs. This allows UObject initializers to evaluate/dereference the CDO ptr normally as a UObject*, even if created with a placeholder type. - Replaced direct RF_HasPlaceholderType flag queries with FPropertyBagRepository::IsPropertyBagPlaceholderObject() instead for placeholder export object queries in FLinkerLoad. This remains inclusive of the CDO. - Now appending RF_HasPlaceholderType onto the ObjectFlags member for export entries created from placeholder type imports. The flag will be cleared if/when the correct instance is patched back into the export table (e.g. at reinstancing time). - Modified FLinkerLoad::TryCreatePlaceholderTypeForExport() to remove the check for 'bSerializeUnknownProperty'. This does not get set until after we've created the placeholder type when we attempt to Preload() the export that's using it. - Modified FLinkerLoad::Serialize() to virtualize serialization when loading a property bag for an object with a missing type import that was serialized with an asset version older than EUnrealEngineObjectUE5Version::SCRIPT_SERIALIZATION_OFFSET. - Modified FLinkerLoad::Preload() to include an asset version check for when serialization of placeholder exports can be safely narrowed to SerializeScriptProperties(). For older asset versions, any non-TPS data serialization is now virtualized instead. - A warning is now emitted by FLinkerLoad::operator<<() when returning NULL for placeholder export object refs in those cases where we are not able to enforce its type safety at runtime. This now includes reflected properties that might serialize a reference to a placeholder type's CDO, which should be an unlikely edge case that we'll now report on here. - Re-enabled unit tests for object handle/pointer type safety (ObjectHandleTests.cpp). - Added a "stress test" method for object pointers to assist with A/B testing and perf analysis (ObjectPtrTests.cpp). - Modified natvis to extend the TObjectPtr format to display as 'nullptr' for pointers to placeholder export types. Intent is to minimize confusion while debugging since object pointers don't allow access to unsafe type objects directly. - Added a CVar to control whether or not we will create placeholder exports as serialization targets when import types are missing on map load (SceneGraph.EnablePropertyBagPlaceholderObjectSupport). Also can be enabled at launch via command line (-EnablePropertyBagPlaceholderObjects) for iteration purposes. Currently the CVar/feature defaults to off (experimental/WiP). #jira UE-197358 #rb Francis.Hurteau [CL 31447968 by phillip kavan in ue5-main branch]
2024-02-13 16:53:52 -05:00
TEST_CASE_METHOD(FObjectHandleTestBase, "CoreUObject::FObjectHandle::Type Safety", "[CoreUObject][ObjectHandle]")
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
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();
};
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
// construct an unsafe class type
UClass* TestUnsafeClass = UE::FPropertyBagRepository::CreatePropertyBagPlaceholderClass(TestPackage, UClass::StaticClass(), TEXT("TestUnsafeClass"));
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
// construct objects for testing
UObjectPtrTestClass* TestSafeObject = NewObject<UObjectPtrTestClass>(TestPackage, TEXT("TestSafeObject"), RF_Transient);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
UObject* TestUnsafeObject = NewObject<UObject>(TestPackage, TestUnsafeClass, TEXT("TestUnsafeObject"), RF_Transient);
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// invalid address value for testing
UObject* TestInvalidAddress = (UObject*)0xFFFF'FFFF'FFFF'FFFCull;
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
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);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
FObjectHandle TestSafeInvalidAddressHandle = UE::CoreUObject::Private::MakeObjectHandle(TestInvalidAddress);
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
FObjectHandle TestLateResolveSafeObjectHandle = { UE::CoreUObject::Private::MakePackedObjectRef(TestSafeObject).EncodedRef };
FObjectHandle TestLateResolveUnsafeObjectHandle = { UE::CoreUObject::Private::MakePackedObjectRef(TestUnsafeObject).EncodedRef };
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
FObjectHandle TestLateResolveSafeInvalidAddressHandle = { (UE::CoreUObject::Private::FPackedObjectRef { reinterpret_cast<UPTRINT>(TestInvalidAddress) | 1 }).EncodedRef };
FObjectHandle TestLateResolveUnsafeInvalidAddressHandle = { (UE::CoreUObject::Private::FPackedObjectRef { reinterpret_cast<UPTRINT>(TestInvalidAddress) | (1 << UE::CoreUObject::Private::TypeIdShift) | 1 }).EncodedRef };
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
#endif
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
// NULL/type-safe object handles should report as being safe
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
CHECK(IsObjectHandleTypeSafe(NullObjectHandle));
CHECK(IsObjectHandleTypeSafe(TestSafeObjectHandle));
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(IsObjectHandleTypeSafe(TestSafeInvalidAddressHandle));
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
CHECK(IsObjectHandleTypeSafe(TestLateResolveSafeObjectHandle));
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(IsObjectHandleTypeSafe(TestLateResolveSafeInvalidAddressHandle));
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
#endif
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// unsafe type object handles should report as being unsafe
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK_FALSE(IsObjectHandleTypeSafe(TestLateResolveUnsafeObjectHandle));
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK_FALSE(IsObjectHandleTypeSafe(TestLateResolveUnsafeInvalidAddressHandle));
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
// unsafe type object handles should resolve the class to the unsafe type
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK(UE::CoreUObject::Private::ResolveObjectHandleClass(TestLateResolveUnsafeObjectHandle) == TestUnsafeClass);
#endif
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
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
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK(NullObjectHandle != TestLateResolveUnsafeObjectHandle);
CHECK(TestLateResolveUnsafeObjectHandle != NullObjectHandle);
CHECK(TestSafeObjectHandle != TestLateResolveUnsafeObjectHandle);
CHECK(TestLateResolveUnsafeObjectHandle != TestSafeObjectHandle);
CHECK(TestLateResolveSafeObjectHandle != TestLateResolveUnsafeObjectHandle);
CHECK(TestLateResolveUnsafeObjectHandle != TestLateResolveSafeObjectHandle);
CHECK(TestLateResolveUnsafeObjectHandle == TestLateResolveUnsafeObjectHandle);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// CHECK(TestSafeInvalidAddressHandle != TestLateResolveUnsafeInvalidAddressHandle); // note: commented out for now; FObjectHandle::operator==() will call FindExistingPackedObjectRef() when comparing
// CHECK(TestLateResolveUnsafeInvalidAddressHandle != TestSafeInvalidAddressHandle); // resolved to unresolved values, which will then attempt to dereference the resolved address and crash (known issue)
CHECK(TestLateResolveSafeInvalidAddressHandle != TestLateResolveUnsafeInvalidAddressHandle);
CHECK(TestLateResolveUnsafeInvalidAddressHandle != TestLateResolveSafeInvalidAddressHandle);
CHECK(TestLateResolveUnsafeInvalidAddressHandle == TestLateResolveUnsafeInvalidAddressHandle);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
[UE]: More revisions to placeholder property bag type import/export serialization support during map asset loads in the editor. Change summary: - Modified ObjectPtr_Private::IsObjectPtrEqualToRawPtrOfRelatedType() to include a non-resolving NULL check for LHS. This allows unsafe type object pointers to equate to NULL object pointers (in addition to nullptr) - e.g. for compiled paths that do implicit type conversions from nullptr to TObjectPtr(nullptr). Also updated the unit test to reflect this behavior change. - Replaced FPropertyBagRepository::IsPropertyBagPlaceholderType() with IsPropertyBagPlaceholderObject(). - No longer setting RF_HasPlaceholderType on placeholder import type CDOs. This allows UObject initializers to evaluate/dereference the CDO ptr normally as a UObject*, even if created with a placeholder type. - Replaced direct RF_HasPlaceholderType flag queries with FPropertyBagRepository::IsPropertyBagPlaceholderObject() instead for placeholder export object queries in FLinkerLoad. This remains inclusive of the CDO. - Now appending RF_HasPlaceholderType onto the ObjectFlags member for export entries created from placeholder type imports. The flag will be cleared if/when the correct instance is patched back into the export table (e.g. at reinstancing time). - Modified FLinkerLoad::TryCreatePlaceholderTypeForExport() to remove the check for 'bSerializeUnknownProperty'. This does not get set until after we've created the placeholder type when we attempt to Preload() the export that's using it. - Modified FLinkerLoad::Serialize() to virtualize serialization when loading a property bag for an object with a missing type import that was serialized with an asset version older than EUnrealEngineObjectUE5Version::SCRIPT_SERIALIZATION_OFFSET. - Modified FLinkerLoad::Preload() to include an asset version check for when serialization of placeholder exports can be safely narrowed to SerializeScriptProperties(). For older asset versions, any non-TPS data serialization is now virtualized instead. - A warning is now emitted by FLinkerLoad::operator<<() when returning NULL for placeholder export object refs in those cases where we are not able to enforce its type safety at runtime. This now includes reflected properties that might serialize a reference to a placeholder type's CDO, which should be an unlikely edge case that we'll now report on here. - Re-enabled unit tests for object handle/pointer type safety (ObjectHandleTests.cpp). - Added a "stress test" method for object pointers to assist with A/B testing and perf analysis (ObjectPtrTests.cpp). - Modified natvis to extend the TObjectPtr format to display as 'nullptr' for pointers to placeholder export types. Intent is to minimize confusion while debugging since object pointers don't allow access to unsafe type objects directly. - Added a CVar to control whether or not we will create placeholder exports as serialization targets when import types are missing on map load (SceneGraph.EnablePropertyBagPlaceholderObjectSupport). Also can be enabled at launch via command line (-EnablePropertyBagPlaceholderObjects) for iteration purposes. Currently the CVar/feature defaults to off (experimental/WiP). #jira UE-197358 #rb Francis.Hurteau [CL 31447968 by phillip kavan in ue5-main branch]
2024-02-13 16:53:52 -05:00
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
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));
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK_FALSE(IsObjectHandleResolved(TestLateResolveSafeInvalidAddressHandle));
CHECK_FALSE(IsObjectHandleResolved(TestLateResolveUnsafeInvalidAddressHandle));
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// unsafe type object handles should resolve/evaluate to the original object/address, or NULL for an invalid object w/ late resolve
CHECK(UE::CoreUObject::Private::ResolveObjectHandle(TestSafeInvalidAddressHandle) == TestInvalidAddress);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK(UE::CoreUObject::Private::ResolveObjectHandle(TestLateResolveSafeObjectHandle) == TestSafeObject);
CHECK(UE::CoreUObject::Private::ResolveObjectHandle(TestLateResolveUnsafeObjectHandle) == TestUnsafeObject);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(UE::CoreUObject::Private::ResolveObjectHandle(TestLateResolveSafeInvalidAddressHandle) == nullptr);
CHECK(UE::CoreUObject::Private::ResolveObjectHandle(TestLateResolveUnsafeInvalidAddressHandle) == nullptr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// unsafe type object handles should report as NOT being resolved (in order to preserve the bit flag on the underlying packed reference)
CHECK(IsObjectHandleResolved(TestSafeInvalidAddressHandle));
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK(IsObjectHandleResolved(TestLateResolveSafeObjectHandle));
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK_FALSE(IsObjectHandleResolved(TestLateResolveUnsafeObjectHandle));
CHECK(IsObjectHandleResolved(TestLateResolveSafeInvalidAddressHandle));
CHECK_FALSE(IsObjectHandleResolved(TestLateResolveUnsafeInvalidAddressHandle));
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
// construct object pointers for testing intentionally different behaviors of UObject-type vs. non-UObject-type bindings
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
TObjectPtr<UObject> NullObjectPtr(nullptr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
TObjectPtr<UObject> TestSafeObjectPtr(TestUnsafeObject); // type safe pointer to placeholder (bound to UObject type)
TObjectPtr<const UObject> TestSafeConstObjectPtr(TestUnsafeObject); // type safe const pointer to placeholder (bound to UObject type)
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
FObjectPtr TestSafeInvalidObjectPtr_Untyped(TestSafeInvalidAddressHandle);
TObjectPtr<UObject> TestSafeInvalidObjectPtr(TestSafeInvalidObjectPtr_Untyped);
TObjectPtr<const UObject> TestSafeInvalidConstObjectPtr(TestSafeInvalidObjectPtr_Untyped);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// 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 and as such do not update the handle on resolve
FObjectPtr TestLateResolveUnsafeObjectPtr_Untyped(TestLateResolveUnsafeObjectHandle);
TObjectPtr<UObject> TestLateResolveSafeObjectPtr(TestLateResolveUnsafeObjectPtr_Untyped);
TObjectPtr<const UObject> TestLateResolveSafeConstObjectPtr(TestLateResolveUnsafeObjectPtr_Untyped);
TObjectPtr<UObjectPtrTestClass> TestLateResolveUnsafeObjectPtr(TestLateResolveUnsafeObjectPtr_Untyped);
TObjectPtr<const UObjectPtrTestClass> TestLateResolveUnsafeConstObjectPtr(TestLateResolveUnsafeObjectPtr_Untyped);
FObjectPtr TestLateResolveUnsafeInvalidObjectPtr_Untyped(TestLateResolveUnsafeInvalidAddressHandle);
TObjectPtr<UObject> TestLateResolveSafeInvalidObjectPtr(TestLateResolveUnsafeInvalidObjectPtr_Untyped);
TObjectPtr<const UObject> TestLateResolveSafeInvalidConstObjectPtr(TestLateResolveUnsafeInvalidObjectPtr_Untyped);
TObjectPtr<UObjectPtrTestClass> TestLateResolveUnsafeInvalidObjectPtr(TestLateResolveUnsafeInvalidObjectPtr_Untyped);
TObjectPtr<const UObjectPtrTestClass> TestLateResolveUnsafeInvalidConstObjectPtr(TestLateResolveUnsafeInvalidObjectPtr_Untyped);
TArray<TObjectPtr<UObject>> TestLateResolveSafeObjectPtrArray = { TestLateResolveSafeObjectPtr, TestLateResolveSafeInvalidObjectPtr };
TArray<TObjectPtr<UObjectPtrTestClass>> TestLateResolveUnsafeObjectPtrArray = { TestLateResolveUnsafeObjectPtr, TestLateResolveUnsafeInvalidObjectPtr };
TArray<TObjectPtr<const UObject>> TestLateResolveSafeConstObjectPtrArray = { TestLateResolveSafeConstObjectPtr, TestLateResolveSafeInvalidConstObjectPtr };
TArray<TObjectPtr<const UObjectPtrTestClass>> TestLateResolveUnsafeConstObjectPtrArray = { TestLateResolveUnsafeConstObjectPtr, TestLateResolveUnsafeInvalidConstObjectPtr };
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// type safe object pointers should evaluate to true/non-NULL (including invalid pointers)
CHECK(TestSafeObjectPtr);
CHECK(!!TestSafeObjectPtr);
CHECK(NULL != TestSafeObjectPtr);
CHECK(TestSafeObjectPtr != NULL);
CHECK(nullptr != TestSafeObjectPtr);
CHECK(TestSafeObjectPtr != nullptr);
CHECK(TestSafeConstObjectPtr);
CHECK(!!TestSafeConstObjectPtr);
CHECK(NULL != TestSafeConstObjectPtr);
CHECK(TestSafeConstObjectPtr != NULL);
CHECK(nullptr != TestSafeConstObjectPtr);
CHECK(TestSafeConstObjectPtr != nullptr);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(TestSafeInvalidObjectPtr);
CHECK(!!TestSafeInvalidObjectPtr);
CHECK(NULL != TestSafeInvalidObjectPtr);
CHECK(TestSafeInvalidObjectPtr != NULL);
CHECK(nullptr != TestSafeInvalidObjectPtr);
CHECK(TestSafeInvalidObjectPtr != nullptr);
CHECK(TestSafeInvalidConstObjectPtr);
CHECK(!!TestSafeInvalidConstObjectPtr);
CHECK(NULL != TestSafeInvalidConstObjectPtr);
CHECK(TestSafeInvalidConstObjectPtr != NULL);
CHECK(nullptr != TestSafeInvalidConstObjectPtr);
CHECK(TestSafeInvalidConstObjectPtr != nullptr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
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);
CHECK(TestLateResolveSafeConstObjectPtr);
CHECK(!!TestLateResolveSafeConstObjectPtr);
CHECK(NULL != TestLateResolveSafeConstObjectPtr);
CHECK(TestLateResolveSafeConstObjectPtr != NULL);
CHECK(nullptr != TestLateResolveSafeConstObjectPtr);
CHECK(TestLateResolveSafeConstObjectPtr != nullptr);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(TestLateResolveSafeInvalidObjectPtr);
CHECK(!!TestLateResolveSafeInvalidObjectPtr);
CHECK(NULL != TestLateResolveSafeInvalidObjectPtr);
CHECK(TestLateResolveSafeInvalidObjectPtr != NULL);
CHECK(nullptr != TestLateResolveSafeInvalidObjectPtr);
CHECK(TestLateResolveSafeInvalidObjectPtr != nullptr);
CHECK(TestLateResolveSafeInvalidConstObjectPtr);
CHECK(!!TestLateResolveSafeInvalidConstObjectPtr);
CHECK(NULL != TestLateResolveSafeInvalidConstObjectPtr);
CHECK(TestLateResolveSafeInvalidConstObjectPtr != NULL);
CHECK(nullptr != TestLateResolveSafeInvalidConstObjectPtr);
CHECK(TestLateResolveSafeInvalidConstObjectPtr != nullptr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// unsafe type object pointers should evaluate to NULL/false (for type safety)
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK_FALSE(TestLateResolveUnsafeObjectPtr);
CHECK_FALSE(!!TestLateResolveUnsafeObjectPtr);
CHECK(NULL == TestLateResolveUnsafeObjectPtr);
CHECK(TestLateResolveUnsafeObjectPtr == NULL);
CHECK(nullptr == TestLateResolveUnsafeObjectPtr);
CHECK(TestLateResolveUnsafeObjectPtr == nullptr);
CHECK_FALSE(TestLateResolveUnsafeConstObjectPtr);
CHECK_FALSE(!!TestLateResolveUnsafeConstObjectPtr);
CHECK(NULL == TestLateResolveUnsafeConstObjectPtr);
CHECK(TestLateResolveUnsafeConstObjectPtr == NULL);
CHECK(nullptr == TestLateResolveUnsafeConstObjectPtr);
CHECK(TestLateResolveUnsafeConstObjectPtr == nullptr);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK_FALSE(TestLateResolveUnsafeInvalidObjectPtr);
CHECK_FALSE(!!TestLateResolveUnsafeInvalidObjectPtr);
CHECK(NULL == TestLateResolveUnsafeInvalidObjectPtr);
CHECK(TestLateResolveUnsafeInvalidObjectPtr == NULL);
CHECK(nullptr == TestLateResolveUnsafeInvalidObjectPtr);
CHECK(TestLateResolveUnsafeInvalidObjectPtr == nullptr);
CHECK_FALSE(TestLateResolveUnsafeInvalidConstObjectPtr);
CHECK_FALSE(!!TestLateResolveUnsafeInvalidConstObjectPtr);
CHECK(NULL == TestLateResolveUnsafeInvalidConstObjectPtr);
CHECK(TestLateResolveUnsafeInvalidConstObjectPtr == NULL);
CHECK(nullptr == TestLateResolveUnsafeInvalidConstObjectPtr);
CHECK(TestLateResolveUnsafeInvalidConstObjectPtr == nullptr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
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
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(NullObjectPtr == TestLateResolveUnsafeObjectPtr); // note: this intentionally differs from object *handles* (see above)
CHECK(TestLateResolveUnsafeObjectPtr == NullObjectPtr); // see note directly above
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
CHECK(TestSafeObjectPtr != TestLateResolveUnsafeObjectPtr);
CHECK(TestLateResolveUnsafeObjectPtr != TestSafeObjectPtr);
CHECK(NullObjectPtr != TestLateResolveSafeConstObjectPtr);
CHECK(TestLateResolveSafeConstObjectPtr != NullObjectPtr);
CHECK(NullObjectPtr == TestLateResolveUnsafeConstObjectPtr);
CHECK(TestLateResolveUnsafeConstObjectPtr == NullObjectPtr);
CHECK(TestSafeConstObjectPtr != TestLateResolveUnsafeConstObjectPtr);
CHECK(TestLateResolveUnsafeConstObjectPtr != TestSafeConstObjectPtr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
CHECK(TestLateResolveSafeObjectPtr != TestLateResolveUnsafeObjectPtr);
CHECK(TestLateResolveUnsafeObjectPtr != TestLateResolveSafeObjectPtr);
CHECK(TestLateResolveSafeConstObjectPtr != TestLateResolveUnsafeConstObjectPtr);
CHECK(TestLateResolveUnsafeConstObjectPtr != TestLateResolveSafeConstObjectPtr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
CHECK(TestLateResolveUnsafeObjectPtr == TestLateResolveUnsafeObjectPtr);
CHECK(TestLateResolveUnsafeConstObjectPtr == TestLateResolveUnsafeConstObjectPtr);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(NullObjectPtr == TestLateResolveUnsafeInvalidObjectPtr);
CHECK(TestLateResolveUnsafeInvalidObjectPtr == NullObjectPtr);
CHECK(TestSafeInvalidObjectPtr != TestLateResolveUnsafeInvalidObjectPtr); // note: these do not result in a handle-to-handle test because the underlying
CHECK(TestLateResolveUnsafeInvalidObjectPtr != TestSafeInvalidObjectPtr); // handle will resolve to NULL for the late resolve case with an invalid address
CHECK(TestLateResolveSafeInvalidObjectPtr != TestLateResolveUnsafeInvalidObjectPtr);
CHECK(TestLateResolveUnsafeInvalidObjectPtr != TestLateResolveSafeInvalidObjectPtr);
CHECK(TestLateResolveUnsafeInvalidObjectPtr == TestLateResolveUnsafeInvalidObjectPtr);
CHECK(NullObjectPtr == TestLateResolveUnsafeInvalidConstObjectPtr);
CHECK(TestLateResolveUnsafeInvalidConstObjectPtr == NullObjectPtr);
CHECK(TestSafeInvalidConstObjectPtr != TestLateResolveUnsafeInvalidConstObjectPtr);
CHECK(TestLateResolveUnsafeInvalidConstObjectPtr != TestSafeInvalidConstObjectPtr);
CHECK(TestLateResolveSafeInvalidConstObjectPtr != TestLateResolveUnsafeInvalidConstObjectPtr);
CHECK(TestLateResolveUnsafeInvalidConstObjectPtr != TestLateResolveSafeInvalidConstObjectPtr);
CHECK(TestLateResolveUnsafeInvalidConstObjectPtr == TestLateResolveUnsafeInvalidConstObjectPtr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// an unsafe type object should evaluate the object's attributes correctly (applicable only to valid object pointers)
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
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());
CHECK_FALSE(TestLateResolveSafeConstObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveUnsafeConstObjectPtr.IsResolved());
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK_FALSE(TestLateResolveSafeInvalidObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveUnsafeInvalidObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveSafeInvalidConstObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveUnsafeInvalidConstObjectPtr.IsResolved());
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// a type safe object pointer should resolve to a non-NULL value when dereferenced, or NULL for an invalid object w/ late resolve
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
CHECK(TestSafeObjectPtr.Get() == TestUnsafeObject);
CHECK(TestSafeConstObjectPtr.Get() == TestUnsafeObject);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(TestSafeInvalidObjectPtr.Get() == TestInvalidAddress);
CHECK(TestSafeInvalidConstObjectPtr.Get() == TestInvalidAddress);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK(TestLateResolveSafeObjectPtr.Get() == TestUnsafeObject);
CHECK(TestLateResolveSafeConstObjectPtr.Get() == TestUnsafeObject);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(TestLateResolveSafeInvalidObjectPtr.Get() == nullptr);
CHECK(TestLateResolveSafeInvalidConstObjectPtr.Get() == nullptr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// an unsafe type object pointer should resolve to NULL when dereferenced (for type safety)
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK(TestLateResolveUnsafeObjectPtr.Get() == nullptr);
CHECK(TestLateResolveUnsafeConstObjectPtr.Get() == nullptr);
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(TestLateResolveUnsafeInvalidObjectPtr.Get() == nullptr);
CHECK(TestLateResolveUnsafeInvalidConstObjectPtr.Get() == nullptr);
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
// unsafe type object pointers should report as NOT being resolved; all others as resolved
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
CHECK(TestSafeObjectPtr.IsResolved());
CHECK(TestSafeConstObjectPtr.IsResolved());
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK(TestSafeInvalidObjectPtr.IsResolved());
CHECK(TestSafeInvalidConstObjectPtr.IsResolved());
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
Further revise TObjectPtr to avoid indirection by keeping references to placeholder-typed objects unresolved. Change summary: - Reduced IsObjectHandleTypeSafe() to just a simple bit test. The LSB must also be set to require that it's a packed ref. - Modified ResolveObjectHandleNoRead()/ResolveObjectHandleNoReadNoCheck() to update the handle only if type safe. - Modified ObjectPtr_Private::Get() to return NULL without first resolving the handle (for pointers bound to UObject subtypes). - Modified FLinkerLoad::operator<<() to serialize placeholder-typed object references as an "unsafe" packed reference only if the pointer type is unsafe. - Modified TObjectPtr::GetInternalRef() to assert if the handle is not resolved. This will catch an attempt to return an unsafe pointer as a packed reference. - Modified ToRawPtrArrayUnsafe() to assert if any item in the array is not resolved. This will catch an attempt to treat a packed reference as the element type. - Modified TContainerElementTypeCompatibility::ReinterpretRange()/ReinterpretRangeContiguous() to assert if any element of the pointer array is not resolved. - Modified ToRawPtrTArrayUnsafe() to reinterpret the pointer array through the type compatibility layer to catch any attempt to treat a packed reference as the element type. - Revised TObjectPtr natvis to reduce the placeholder intrinsic query down to just a single bit test. - Removed 'GObjectIndexToPackedObjectRefDebug' as it is no longer required for natvis support. - Revised FObjectHandle/TObjectPtr type safety unit tests to validate the unresolved state of placeholder-typed references as well as include invalid address inputs to ensure we're only using pointer semantics. #jira UE-215308 #rb Francis.Hurteau, Zousar.Shaker [CL 33975641 by phillip kavan in ue5-main branch]
2024-05-29 11:43:30 -04:00
CHECK_FALSE(TestLateResolveSafeObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveSafeConstObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveSafeInvalidObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveUnsafeObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveUnsafeConstObjectPtr.IsResolved());
CHECK_FALSE(TestLateResolveUnsafeInvalidObjectPtr.IsResolved());
#endif
// unsafe type object pointers should not convert to raw pointer / array
#if UE_WITH_OBJECT_HANDLE_LATE_RESOLVE
CHECK(ToRawPtr(TestLateResolveSafeObjectPtr) == TestUnsafeObject);
CHECK(ToRawPtr(TestLateResolveSafeConstObjectPtr) == TestUnsafeObject);
CHECK(ToRawPtr(TestLateResolveUnsafeObjectPtr) == nullptr);
CHECK(ToRawPtr(TestLateResolveUnsafeConstObjectPtr) == nullptr);
CHECK(ToRawPtr(TestLateResolveSafeInvalidObjectPtr) == nullptr);
CHECK(ToRawPtr(TestLateResolveUnsafeInvalidObjectPtr) == nullptr);
{
SKIP(); // comment this out to run the tests below (they should assert as they will not be resolved)
ToRawPtrTArrayUnsafe(TestLateResolveSafeObjectPtrArray);
ToRawPtrTArrayUnsafe(TestLateResolveSafeConstObjectPtrArray);
ToRawPtrTArrayUnsafe(TestLateResolveUnsafeObjectPtrArray);
ToRawPtrTArrayUnsafe(TestLateResolveUnsafeConstObjectPtrArray);
}
Revise TObjectPtr to use pointer semantics for type safety checks (editor only). Notes: - This replaces the previous solution that relied on indirection. - This solution relies on packed ref handles which requires late resolve features to also be enabled. Change summary: - Modified FPropertyBagRepository::IsPropertyBagPlaceholderType()/IsPropertyBagPlaceholderObject() to make the parameter read-only. - Re-enabled UE_WITH_OBJECT_HANDLE_TYPE_SAFETY for the editor context. This will unblock testing of IDO w/ placeholder type features. - Modified UE::CoreUObject::Private::Pack() to include a new "type" trait bit in the packed object handle reference. If set, it will signal that the reference is also a placeholder-typed object. - Modified UE::CoreUObject::Private::MakePackedObjectRef() to include a check for whether or not the given object reference is also a placeholder-typed object, and allow this case to pass. - Added UE::CoreUObject::Private::IsObjectHandleTypeSafeNoReadNoCheck(). This allows the implementation of IsObjectHandleTypeSafe() to rely on packed reference semantics, which are implemented as internal inline definitions. - Modified FLinkerLoad serialization of FObjectPtr values to register a packed object reference mapping for placeholder-typed objects. Note: This requires late resolve features to also be enabled. - Modified the TObjectPtr equality test to handle the case when only the RHS side is NULL. This can occur if the RHS is a non-UObject-type bound ptr to a placeholder object while the LHS is not. - Revised all object handle/ptr unit tests for type safety. Ensured that TObjectPtr stress tests are still in line both with/without type safety enabled. - Added a GObjectIndexToPackedObjectRefDebug global ptr to assist with debugger visualization of resolved placeholder-typed object references to allow for removal of RF_HasPlaceholderType. - Updated VS natvis file to revise queries for IsPlaceholderObject() on non-UObject-typed TObjectPtr values (removed ObjectFlags check and replaced w/ GObjectIndexToPackedObjectRefDebug). - Deprecated/removed all usage of RF_HasPlaceholderType (no longer required). - Removed FPropertyBagRepository::PropertyBagPlaceholderTypeRegistry and decoupled the current (static) API from the repo singleton instance. - (Minor) Fixed up some handle tracking unit tests in ObjectPropertyTest.cpp that did not compile with UE_WITH_OBJECT_HANDLE_LATE_RESOLVE disabled. #jira UE-212508, UE-197358 #rb Zousar.Shaker [CL 33397676 by phillip kavan in ue5-main branch]
2024-05-02 11:25:44 -04:00
#endif
Create placeholder types/objects for package exports when type imports are missing/unresolved on editor map loads. Notes: - This allows the export to deserialize its tagged property stream (TPS) data into a property bag (when enabled), while also keeping references to the object in place. - The export can still be serialized to the same package on save with its TPS data still intact. In that case, we will serialize the property bag back into the package as a "normal" TPS data stream. - Serialized references to placeholder objects are resolved as NULL. For FObjectPtr types, the value is resolved as NULL when dereferenced (for type safety), but is still serialized as a non-NULL reference to the original object (even if placeholder). - Placeholders will not be created on load unless FUObjectSerializeContext::bSerializeUnknownProperty is set to TRUE in the serialization context. Otherwise, we immediately resolve the export as NULL, and its data is lost on load (previous behavior). Change summary: - Added FPropertyBagRepository::PropertyBagTypeRegistry (w/ thread-safe implementation). Currently using ARO to manage placeholder type object lifetime. - Added FPropertyBagRepository::AddPropertyBagPlaceholderType()/IsPropertyBagPlaceholderType(). - Modified FLinkerLoad::CreateExport() to instance a "placeholder" package/object if the export is missing its type import on load. Otherwise falls back to returning NULL (previous behavior). - Added UE_WITH_OBJECT_HANDLE_TYPE_SAFETY along with IsObjectHandleTypeSafe(). - Added UE::CoreUObject::Private::HasAnyFlags() to ObjectFwd.h (using int32 for the param here as the enum isn't defined at this level). Similar to internal APIs added for late resolve; avoid having to include Object.h. - Added RF_HasPlaceholderType (reclaimed an unused bit). This allows FObjectPtr to do a faster query at resolve time for type safety when referencing a placeholder object (i.e. it will return NULL). - Modified FObjectPtr::Get() and IsNull() variants to include an extra check for type safety. Right now this is only enabled in an editor build context. - Modified FLinkerLoad::Preload() to narrow the serialization scope to the export's TPS data *only* (since the original base type is unknown, we need to skip any natively-serialized data that might also exist in the stream). - Modified FLinkerLoad serialization of raw UObject* values to return NULL in the case of a placeholder object (for type safety at runtime). - Modified FLinkerLoad serialization of FObjectPtr values to return NULL in the case of a placeholder object only if type safety features are disabled on FObjectPtr/FObjectHandle. - Extended the LowLevel core NULL ptr tests to include additional tests for "unsafe type" objects wrapped by an FObjectPtr/TObjectPtr. #jira UE-197358 #rb Francis.Hurteau [CL 31258090 by phillip kavan in ue5-main branch]
2024-02-07 10:34:24 -05:00
}
#endif
#endif