Files
UnrealEngine/Engine/Source/Editor/BlueprintGraph/Private/BlueprintNodeSpawnerUtils.cpp
2025-05-18 13:04:45 +08:00

120 lines
3.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "BlueprintNodeSpawnerUtils.h"
#include "BlueprintBoundEventNodeSpawner.h"
#include "BlueprintDelegateNodeSpawner.h"
#include "BlueprintEventNodeSpawner.h"
#include "BlueprintFunctionNodeSpawner.h"
#include "BlueprintNodeSpawner.h"
#include "BlueprintVariableNodeSpawner.h"
#include "Misc/AssertionMacros.h"
#include "Templates/Casts.h"
#include "UObject/Class.h"
#include "UObject/Object.h"
#include "UObject/ObjectMacros.h"
#include "UObject/UObjectGlobals.h"
#include "UObject/UnrealType.h"
//------------------------------------------------------------------------------
FFieldVariant FBlueprintNodeSpawnerUtils::GetAssociatedField(UBlueprintNodeSpawner const* BlueprintAction)
{
FFieldVariant ClassField;
if (UFunction const* Function = GetAssociatedFunction(BlueprintAction))
{
ClassField = Function;
}
else if (FProperty const* Property = GetAssociatedProperty(BlueprintAction))
{
ClassField = Property;
}
// @TODO: have to fix up some of the filter cases to ignore structs/enums
// else if (UBlueprintFieldNodeSpawner const* FieldNodeSpawner = Cast<UBlueprintFieldNodeSpawner>(BlueprintAction))
// {
// ClassField = FieldNodeSpawner->GetField();
// }
return ClassField;
}
//------------------------------------------------------------------------------
UFunction const* FBlueprintNodeSpawnerUtils::GetAssociatedFunction(UBlueprintNodeSpawner const* BlueprintAction)
{
UFunction const* Function = nullptr;
if (UBlueprintFunctionNodeSpawner const* FuncNodeSpawner = Cast<UBlueprintFunctionNodeSpawner>(BlueprintAction))
{
Function = FuncNodeSpawner->GetFunction();
}
else if (UBlueprintEventNodeSpawner const* EventSpawner = Cast<UBlueprintEventNodeSpawner>(BlueprintAction))
{
Function = EventSpawner->GetEventFunction();
}
return Function;
}
//------------------------------------------------------------------------------
FProperty const* FBlueprintNodeSpawnerUtils::GetAssociatedProperty(UBlueprintNodeSpawner const* BlueprintAction)
{
FProperty const* Property = nullptr;
if (UBlueprintDelegateNodeSpawner const* PropertySpawner = Cast<UBlueprintDelegateNodeSpawner>(BlueprintAction))
{
Property = PropertySpawner->GetDelegateProperty();
}
else if (UBlueprintVariableNodeSpawner const* VarSpawner = Cast<UBlueprintVariableNodeSpawner>(BlueprintAction))
{
Property = VarSpawner->GetVarProperty();
}
else if (UBlueprintBoundEventNodeSpawner const* BoundSpawner = Cast<UBlueprintBoundEventNodeSpawner>(BlueprintAction))
{
Property = BoundSpawner->GetEventDelegate();
}
return Property;
}
//------------------------------------------------------------------------------
UClass* FBlueprintNodeSpawnerUtils::GetBindingClass(FBindingObject Binding)
{
UClass* BindingClass = nullptr;
if (Binding.IsUObject())
{
BindingClass = Binding.Get<UObject>()->GetClass();
}
else if (const FObjectProperty* ObjProperty = Binding.Get<FObjectProperty>())
{
BindingClass = ObjProperty->PropertyClass;
}
else
{
check(false); // Can the binding object be an FProperty?
}
return BindingClass;
}
//------------------------------------------------------------------------------
bool FBlueprintNodeSpawnerUtils::IsStaleFieldAction(UBlueprintNodeSpawner const* BlueprintAction)
{
bool bHasStaleAssociatedField= false;
UClass* ClassOwner = nullptr;
if (const UFunction* AssociatedFunction = GetAssociatedFunction(BlueprintAction))
{
ClassOwner = AssociatedFunction->GetOwnerClass();
}
else if (const FProperty* AssociatedProperty = GetAssociatedProperty(BlueprintAction))
{
ClassOwner = AssociatedProperty->GetOwnerClass();
}
if (ClassOwner != nullptr)
{
// check to see if this field belongs to a TRASH or REINST class,
// maybe to a class that was thrown out because of a hot-reload?
bHasStaleAssociatedField = ClassOwner->HasAnyClassFlags(CLASS_NewerVersionExists) || (ClassOwner->GetOutermost() == GetTransientPackage());
}
return bHasStaleAssociatedField;
}