// 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(BlueprintAction)) // { // ClassField = FieldNodeSpawner->GetField(); // } return ClassField; } //------------------------------------------------------------------------------ UFunction const* FBlueprintNodeSpawnerUtils::GetAssociatedFunction(UBlueprintNodeSpawner const* BlueprintAction) { UFunction const* Function = nullptr; if (UBlueprintFunctionNodeSpawner const* FuncNodeSpawner = Cast(BlueprintAction)) { Function = FuncNodeSpawner->GetFunction(); } else if (UBlueprintEventNodeSpawner const* EventSpawner = Cast(BlueprintAction)) { Function = EventSpawner->GetEventFunction(); } return Function; } //------------------------------------------------------------------------------ FProperty const* FBlueprintNodeSpawnerUtils::GetAssociatedProperty(UBlueprintNodeSpawner const* BlueprintAction) { FProperty const* Property = nullptr; if (UBlueprintDelegateNodeSpawner const* PropertySpawner = Cast(BlueprintAction)) { Property = PropertySpawner->GetDelegateProperty(); } else if (UBlueprintVariableNodeSpawner const* VarSpawner = Cast(BlueprintAction)) { Property = VarSpawner->GetVarProperty(); } else if (UBlueprintBoundEventNodeSpawner const* BoundSpawner = Cast(BlueprintAction)) { Property = BoundSpawner->GetEventDelegate(); } return Property; } //------------------------------------------------------------------------------ UClass* FBlueprintNodeSpawnerUtils::GetBindingClass(FBindingObject Binding) { UClass* BindingClass = nullptr; if (Binding.IsUObject()) { BindingClass = Binding.Get()->GetClass(); } else if (const FObjectProperty* ObjProperty = Binding.Get()) { 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; }