// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "UObject/ObjectMacros.h" #include "UObject/UnrealType.h" /** * Meant to represent a specific object property that is setup to reference a * instanced sub-object. Tracks the property hierarchy used to reach the * property, so that we can easily retrieve instanced sub-objects from a * container object. */ struct UE_DEPRECATED(5.6, "Deprecated; this type is no longer in use.") FInstancedPropertyPath { private: struct FPropertyLink { FPropertyLink(const FProperty* Property, int32 ArrayIndexIn, bool bIsMapValueIn) : PropertyPtr(Property), ArrayIndex(ArrayIndexIn), bIsMapValue(bIsMapValueIn) {} const FProperty* PropertyPtr; int32 ArrayIndex; bool bIsMapValue; }; public: //-------------------------------------------------------------------------- FInstancedPropertyPath(FProperty* RootProperty, int32 ArrayIndex = INDEX_NONE, bool bIsMapValue = false) { Push(RootProperty, ArrayIndex, bIsMapValue); } //-------------------------------------------------------------------------- void Push(const FProperty* Property, int32 ArrayIndex = INDEX_NONE, bool bIsMapValue = false) { PropertyChain.Add(FPropertyLink(Property, ArrayIndex, bIsMapValue)); } //-------------------------------------------------------------------------- void Pop() { PropertyChain.RemoveAt(PropertyChain.Num() - 1); } //-------------------------------------------------------------------------- const FProperty* Head() const { return PropertyChain.Last().PropertyPtr; } //-------------------------------------------------------------------------- COREUOBJECT_API UObject* Resolve(const UObject* Container) const; private: TArray PropertyChain; }; PRAGMA_DISABLE_DEPRECATION_WARNINGS /** * Can be used as a raw sub-object pointer, but also contains a * FInstancedPropertyPath to identify the property that this sub-object is * referenced by. Paired together for ease of use (so API users don't have to manage a map). */ struct UE_DEPRECATED(5.6, "Deprecated; this type is no longer in use.") FInstancedSubObjRef { FInstancedSubObjRef(UObject* SubObj, const FInstancedPropertyPath& PropertyPathIn) : SubObjInstance(SubObj) , PropertyPath(PropertyPathIn) {} //-------------------------------------------------------------------------- operator UObject*() const { return SubObjInstance; } //-------------------------------------------------------------------------- UObject* operator->() const { return SubObjInstance; } //-------------------------------------------------------------------------- friend uint32 GetTypeHash(const FInstancedSubObjRef& SubObjRef) { return GetTypeHash((UObject*)SubObjRef); } UObject* SubObjInstance; FInstancedPropertyPath PropertyPath; }; /** * Contains a set of utility functions useful for searching out and identifying * instanced sub-objects contained within a specific outer object. (DEPRECATED) */ class FFindInstancedReferenceSubobjectHelper { public: template UE_DEPRECATED(5.6, "Deprecated; use GetObjectsWithOuter() instead, or use TPropertyValueIterator and check for the CPF_InstancedReference flag if you specifically need this functionality.") static void GetInstancedSubObjects(const UObject* Container, T& OutObjects) { const UClass* ContainerClass = Container->GetClass(); for (FProperty* Prop = ContainerClass->RefLink; Prop; Prop = Prop->NextRef) { for (int32 ArrayIdx = 0; ArrayIdx < Prop->ArrayDim; ++ArrayIdx) { FInstancedPropertyPath RootPropertyPath(Prop, ArrayIdx); const uint8* ValuePtr = Prop->ContainerPtrToValuePtr(Container, ArrayIdx); ForEachInstancedSubObject(RootPropertyPath, ValuePtr, [&OutObjects](const FInstancedSubObjRef& Ref, const void*){ OutObjects.Add(Ref); }); } } } template UE_DEPRECATED(5.6, "Deprecated; use GetObjectsWithOuter() instead, or recursively use a TPropertyValueIterator and check for the CPF_InstancedReference flag if you specifically need this functionality.") static void GetInstancedSubObjectsRecursive(const UObject* Container, T& OutObjects) { const UClass* ContainerClass = Container->GetClass(); for (FProperty* Prop = ContainerClass->RefLink; Prop; Prop = Prop->NextRef) { for (int32 ArrayIdx = 0; ArrayIdx < Prop->ArrayDim; ++ArrayIdx) { FInstancedPropertyPath RootPropertyPath(Prop, ArrayIdx); const uint8* ValuePtr = Prop->ContainerPtrToValuePtr(Container, ArrayIdx); ForEachInstancedSubObject(RootPropertyPath, ValuePtr, [&OutObjects](const FInstancedSubObjRef& Ref, const void*) { if (!OutObjects.Contains(Ref)) { OutObjects.Add(Ref); GetInstancedSubObjectsRecursive(Ref.SubObjInstance, OutObjects); } }); } } } UE_DEPRECATED(5.6, "Deprecated; this method was originally implemented for internal use only.") static COREUOBJECT_API void Duplicate( UObject* OldObject, UObject* NewObject, TMap& ReferenceReplacementMap, TArray& DuplicatedObjects, TMap* OptionalMappings); template UE_DEPRECATED(5.6, "Deprecated; use a container helper (e.g. FScriptArrayHelper) instead if you need to iterate over the values of a container property given its value address.") static void ForEachInstancedSubObject(FInstancedPropertyPath& PropertyPath, T ContainerAddress, TFunctionRef ObjRefFunc); }; PRAGMA_ENABLE_DEPRECATION_WARNINGS