Files
UnrealEngineUWP/Engine/Source/Editor/PropertyEditor/Private/PropertyEditorUtils.cpp
ben hoffman 18eb67c78c Implement GetOptions for UPARAM and add it for ByProfile traces
#rb dave.jones2

#ushell-cherrypick of 27593453 by kristof.morva1

[CL 27597870 by ben hoffman in ue5-main branch]
2023-09-05 11:33:21 -04:00

71 lines
2.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "PropertyEditorUtils.h"
#include "PropertyPathHelpers.h"
namespace PropertyEditorUtils
{
void GetPropertyOptions(TArray<UObject*>& InOutContainers, FString& InOutPropertyPath,
TArray<TSharedPtr<FString>>& InOutOptions)
{
// Check for external function references
if (InOutPropertyPath.Contains(TEXT(".")))
{
InOutContainers.Empty();
UFunction* GetOptionsFunction = FindObject<UFunction>(nullptr, *InOutPropertyPath, true);
if (ensureMsgf(GetOptionsFunction && GetOptionsFunction->HasAnyFunctionFlags(EFunctionFlags::FUNC_Static), TEXT("Invalid GetOptions: %s"), *InOutPropertyPath))
{
UObject* GetOptionsCDO = GetOptionsFunction->GetOuterUClass()->GetDefaultObject();
GetOptionsFunction->GetName(InOutPropertyPath);
InOutContainers.Add(GetOptionsCDO);
}
}
if (InOutContainers.Num() > 0)
{
TArray<FString> OptionIntersection;
TSet<FString> OptionIntersectionSet;
for (UObject* Target : InOutContainers)
{
TArray<FString> StringOptions;
{
FEditorScriptExecutionGuard ScriptExecutionGuard;
FCachedPropertyPath Path(InOutPropertyPath);
if (!PropertyPathHelpers::GetPropertyValue(Target, Path, StringOptions))
{
TArray<FName> NameOptions;
if (PropertyPathHelpers::GetPropertyValue(Target, Path, NameOptions))
{
Algo::Transform(NameOptions, StringOptions, [](const FName& InName) { return InName.ToString(); });
}
}
}
// If this is the first time there won't be any options.
if (OptionIntersection.Num() == 0)
{
OptionIntersection = StringOptions;
OptionIntersectionSet = TSet<FString>(StringOptions);
}
else
{
TSet<FString> StringOptionsSet(StringOptions);
OptionIntersectionSet = StringOptionsSet.Intersect(OptionIntersectionSet);
OptionIntersection.RemoveAll([&OptionIntersectionSet](const FString& Option){ return !OptionIntersectionSet.Contains(Option); });
}
// If we're out of possible intersected options, we can stop.
if (OptionIntersection.Num() == 0)
{
break;
}
}
Algo::Transform(OptionIntersection, InOutOptions, [](const FString& InString) { return MakeShared<FString>(InString); });
}
}
}