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]
Additional changes:
- Consolidated TObjectPtr natvis into a single visualizer block with an additional IsDerivedObjectType() intrinsic.
- Updated type safety unit test coverage to include 'const UObject' pointer types.
#jira UE-214693
#rb Francis.Hurteau, Zousar.Shaker
[CL 33643044 by phillip kavan in ue5-main branch]
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]
Notes:
- For placeholder-typed objects, TObjectPtr<UObject> is considered to be type safe since placeholder types are based on UObject.
- This means we can avoid having to check for and indirectly resolve placeholders via the ptr's internal object handle in these cases.
#jira UE-209831
#rb Francis.Hurteau, Zousar.Shaker
[CL 32434610 by phillip kavan in ue5-main branch]
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]
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]
changed how the Object Handle index stores info to be able to get the class of the outer objects
Packages dont' store a ObjectPathId or ClassDescriptor as it is always known
https://p4-swarm.epicgames.net/reviews/25378953
#rb zousar.shaker
#preflight 64791957e25209b6cbbb45fc
[CL 25747367 by joe pribele in ue5-main branch]
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]
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
[CL 23734208 by joe pribele in ue5-main branch]
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
[CL 23589497 by joe pribele in ue5-main branch]
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
#preflight 638fad1b5624e6da5e166024
[CL 23416765 by joe pribele in ue5-main branch]
added ifdef to FObjectPathId to enabled for WITH_LOW_LEVEL_TESTS
changed ObjectHandleTest to use test data to avoid having to working with cooked, non-cooked or editor only data
#rb zousar.shaker
#p4v-preflight-copy 21321644
#preflight 62fbef15fd15f5152dcfe38e
[CL 21412488 by joe pribele in ue5-main branch]
- test-specific targets and modules are constructed by RulesAssembly which removes a lot of spaghetti code
- no more excluding the Tests folder by default which is guaranteed to mislead users #fyi Jon.Nabozny
- test compilation in Tests is controlled through WITH_LOW_LEVEL_TESTS
- preparation code for switching tests between Catch2 / TestAutomation Fmwk
Nightly LLT PF 6260431391376845adeb4c40
#rnx
#preflight 62602d50dd47b4ad2173c30b
[CL 19834665 by chris constantinescu in ue5-main branch]
Correcting tests commited in CL 19498448 that were converted and tagged [Smoke] but weren't marked with EAUtomationTestFlags::SmokeFilter in the original source.
EditorBulkDataTests was left unconverted, moved back to original Private/Tests/Serialization folder
ObjectPtrTest -> CoreUObject::TObjectPtr::Soft Object Path fails at line 197 on non-desktop platforms but it didn't failed before the conversion.
#preflight 624eee0a2c01f9c6da9446e0
#rb Devin.Doucette
[CL 19668909 by chris constantinescu in ue5-main branch]
Not all were converted because they were designed for packaged applications whereas low level tests are designed to run as "native" non-packaged applications.
- reporting support for non-desktop platforms, for the moment Catch2 report type "console" is used that is sent to a .out file
- most number of tests possible running multi platform, slower tests excluded on incremental builds
- slow tests are moved to run on the monolithic build
- Catch2 report failure event listener such that Horde detects them as build errors. Must add new Horde matcher for Catch2 failures
#rb Mark.Lintott
#preflight 623c8de389625f0612dabd64
[CL 19498448 by chris constantinescu in ue5-main branch]