//------------------------------------------------------------------------------ static void BlueprintActionDatabaseImpl::AddBlueprintGraphActions(UBlueprint const* const Blueprint, FActionList& ActionListOut) { using namespace FBlueprintNodeSpawnerFactory; // for MakeMacroNodeSpawner() for (auto GraphIt = Blueprint->MacroGraphs.CreateConstIterator(); GraphIt; ++GraphIt) { ActionListOut.Add(MakeMacroNodeSpawner(*GraphIt)); } // local variables for (auto GraphIt = Blueprint->FunctionGraphs.CreateConstIterator(); GraphIt; ++GraphIt) { UEdGraph* FunctionGraph = (*GraphIt); TArray<UK2Node_FunctionEntry*> GraphEntryNodes; FunctionGraph->GetNodesOfClass<UK2Node_FunctionEntry>(GraphEntryNodes); for (UK2Node_FunctionEntry* FunctionEntry : GraphEntryNodes) { for (FBPVariableDescription const& LocalVar : FunctionEntry->LocalVariables) { UBlueprintNodeSpawner* GetVarSpawner = UBlueprintVariableNodeSpawner::Create(UK2Node_VariableGet::StaticClass(), FunctionGraph, LocalVar); ActionListOut.Add(GetVarSpawner); UBlueprintNodeSpawner* SetVarSpawner = UBlueprintVariableNodeSpawner::Create(UK2Node_VariableSet::StaticClass(), FunctionGraph, LocalVar); ActionListOut.Add(SetVarSpawner); } } } }
//------------------------------------------------------------------------------ static void BlueprintActionDatabaseImpl::AddClassCastActions(UClass* Class, FActionList& ActionListOut) { Class = Class->GetAuthoritativeClass(); check(Class); UEdGraphSchema_K2 const* K2Schema = GetDefault<UEdGraphSchema_K2>(); bool bIsCastPermitted = UEdGraphSchema_K2::IsAllowableBlueprintVariableType(Class); if (bIsCastPermitted) { auto CustomizeCastNodeLambda = [](UEdGraphNode* NewNode, bool bIsTemplateNode, UClass* TargetType) { UK2Node_DynamicCast* CastNode = CastChecked<UK2Node_DynamicCast>(NewNode); CastNode->TargetType = TargetType; }; UBlueprintNodeSpawner* CastObjNodeSpawner = UBlueprintNodeSpawner::Create<UK2Node_DynamicCast>(); CastObjNodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(CustomizeCastNodeLambda, Class); ActionListOut.Add(CastObjNodeSpawner); UBlueprintNodeSpawner* CastClassNodeSpawner = UBlueprintNodeSpawner::Create<UK2Node_ClassDynamicCast>(); CastClassNodeSpawner->CustomizeNodeDelegate = CastObjNodeSpawner->CustomizeNodeDelegate; ActionListOut.Add(CastClassNodeSpawner); } }
//------------------------------------------------------------------------------ static void BlueprintActionDatabaseImpl::AddClassPropertyActions(UClass const* const Class, FActionList& ActionListOut) { using namespace FBlueprintNodeSpawnerFactory; // for MakeDelegateNodeSpawner() bool const bIsComponent = Class->IsChildOf<UActorComponent>(); bool const bIsActorClass = Class->IsChildOf<AActor>(); // loop over all the properties in the specified class; exclude-super because // we can always get the super properties by looking up that class separateHavely for (TFieldIterator<UProperty> PropertyIt(Class, EFieldIteratorFlags::ExcludeSuper); PropertyIt; ++PropertyIt) { UProperty* Property = *PropertyIt; if (!IsPropertyBlueprintVisible(Property)) { continue; } bool const bIsDelegate = Property->IsA(UMulticastDelegateProperty::StaticClass()); if (bIsDelegate) { UMulticastDelegateProperty* DelegateProperty = CastChecked<UMulticastDelegateProperty>(Property); if (DelegateProperty->HasAnyPropertyFlags(CPF_BlueprintAssignable)) { UBlueprintNodeSpawner* AddSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_AddDelegate::StaticClass(), DelegateProperty); ActionListOut.Add(AddSpawner); UBlueprintNodeSpawner* AssignSpawner = MakeAssignDelegateNodeSpawner(DelegateProperty); ActionListOut.Add(AssignSpawner); } if (DelegateProperty->HasAnyPropertyFlags(CPF_BlueprintCallable)) { UBlueprintNodeSpawner* CallSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_CallDelegate::StaticClass(), DelegateProperty); ActionListOut.Add(CallSpawner); } UBlueprintNodeSpawner* RemoveSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_RemoveDelegate::StaticClass(), DelegateProperty); ActionListOut.Add(RemoveSpawner); UBlueprintNodeSpawner* ClearSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_ClearDelegate::StaticClass(), DelegateProperty); ActionListOut.Add(ClearSpawner); if (bIsComponent) { ActionListOut.Add(MakeComponentBoundEventSpawner(DelegateProperty)); } else if (bIsActorClass) { ActionListOut.Add(MakeActorBoundEventSpawner(DelegateProperty)); } } else { UBlueprintVariableNodeSpawner* GetterSpawner = UBlueprintVariableNodeSpawner::Create(UK2Node_VariableGet::StaticClass(), Property); ActionListOut.Add(GetterSpawner); UBlueprintVariableNodeSpawner* SetterSpawner = UBlueprintVariableNodeSpawner::Create(UK2Node_VariableSet::StaticClass(), Property); ActionListOut.Add(SetterSpawner); } } }
//------------------------------------------------------------------------------ static void BlueprintActionDatabaseImpl::AddClassFunctionActions(UClass const* const Class, FActionList& ActionListOut) { using namespace FBlueprintNodeSpawnerFactory; // for MakeMessageNodeSpawner() check(Class != nullptr); // loop over all the functions in the specified class; exclude-super because // we can always get the super functions by looking up that class separately for (TFieldIterator<UFunction> FunctionIt(Class, EFieldIteratorFlags::ExcludeSuper); FunctionIt; ++FunctionIt) { UFunction* Function = *FunctionIt; bool const bIsInheritedFunction = BlueprintActionDatabaseImpl::IsInheritedBlueprintFunction(Function); if (bIsInheritedFunction) { // inherited functions will be captured when the parent class is ran // through this function (no need to duplicate) continue; } bool const bIsBpInterfaceFunc = BlueprintActionDatabaseImpl::IsBlueprintInterfaceFunction(Function); if (UEdGraphSchema_K2::FunctionCanBePlacedAsEvent(Function) && !bIsBpInterfaceFunc) { if (UBlueprintEventNodeSpawner* NodeSpawner = UBlueprintEventNodeSpawner::Create(Function)) { ActionListOut.Add(NodeSpawner); } } if (UEdGraphSchema_K2::CanUserKismetCallFunction(Function)) { // @TODO: if this is a Blueprint, and this function is from a // Blueprint "implemented interface", then we don't need to // include it (the function is accounted for in from the // interface class). UBlueprintFunctionNodeSpawner* FuncSpawner = UBlueprintFunctionNodeSpawner::Create(Function); ActionListOut.Add(FuncSpawner); if (FKismetEditorUtilities::IsClassABlueprintInterface(Class)) { FuncSpawner->DefaultMenuSignature.MenuName = FText::Format(LOCTEXT("InterfaceCallMenuName", "{0} (Interface Call)"), FuncSpawner->DefaultMenuSignature.MenuName); ActionListOut.Add(MakeMessageNodeSpawner(Function)); } } } }
//------------------------------------------------------------------------------ static void BlueprintActionDatabaseImpl::AddSkeletonActions(const USkeleton& Skeleton, FActionList& ActionListOut) { for (int32 I = 0; I < Skeleton.AnimationNotifies.Num(); ++I) { FName NotifyName = Skeleton.AnimationNotifies[I]; FString Label = NotifyName.ToString(); FString SignatureName = FString::Printf(TEXT("AnimNotify_%s"), *Label); ActionListOut.Add(FBlueprintNodeSpawnerFactory::MakeAnimOwnedEventSpawner(FName(*SignatureName), FEditorCategoryUtils::GetCommonCategory(FCommonEditorCategory::AnimNotify))); } }
//------------------------------------------------------------------------------ static void BlueprintActionDatabaseImpl::AddAnimBlueprintGraphActions(UAnimBlueprint const* AnimBlueprint, FActionList& ActionListOut) { if (UAnimBlueprintGeneratedClass* GeneratedClass = AnimBlueprint->GetAnimBlueprintGeneratedClass()) { for (int32 NotifyIdx = 0; NotifyIdx < GeneratedClass->AnimNotifies.Num(); NotifyIdx++) { FName NotifyName = GeneratedClass->AnimNotifies[NotifyIdx].NotifyName; if (NotifyName != NAME_None) { FString Label = NotifyName.ToString(); FString SignatureName = FString::Printf(TEXT("AnimNotify_%s"), *Label); ActionListOut.Add(FBlueprintNodeSpawnerFactory::MakeAnimOwnedEventSpawner(FName(*SignatureName), FEditorCategoryUtils::GetCommonCategory(FCommonEditorCategory::AnimNotify))); } } } }