From cc604de64b666f996715d7780384214011b85f38 Mon Sep 17 00:00:00 2001 From: Alex Mein Date: Tue, 18 Feb 2025 21:47:22 +0000 Subject: [PATCH 1/5] Added missing calls to parent class Cleanup method --- Source/Flow/Private/Nodes/Actor/FlowNode_ComponentObserver.cpp | 2 ++ Source/Flow/Private/Nodes/Actor/FlowNode_PlayLevelSequence.cpp | 2 ++ Source/Flow/Private/Nodes/Graph/FlowNode_SubGraph.cpp | 2 ++ Source/Flow/Private/Nodes/Route/FlowNode_Counter.cpp | 2 ++ Source/Flow/Private/Nodes/Route/FlowNode_ExecutionMultiGate.cpp | 2 ++ Source/Flow/Private/Nodes/Route/FlowNode_ExecutionSequence.cpp | 2 ++ Source/Flow/Private/Nodes/Route/FlowNode_Timer.cpp | 2 ++ 7 files changed, 14 insertions(+) diff --git a/Source/Flow/Private/Nodes/Actor/FlowNode_ComponentObserver.cpp b/Source/Flow/Private/Nodes/Actor/FlowNode_ComponentObserver.cpp index 3020836a3..10d2ef8d3 100644 --- a/Source/Flow/Private/Nodes/Actor/FlowNode_ComponentObserver.cpp +++ b/Source/Flow/Private/Nodes/Actor/FlowNode_ComponentObserver.cpp @@ -145,6 +145,8 @@ void UFlowNode_ComponentObserver::Cleanup() RegisteredActors.Empty(); SuccessCount = 0; + + Super::Cleanup(); } #if WITH_EDITOR diff --git a/Source/Flow/Private/Nodes/Actor/FlowNode_PlayLevelSequence.cpp b/Source/Flow/Private/Nodes/Actor/FlowNode_PlayLevelSequence.cpp index 70fc34b31..9cfbd4f2b 100644 --- a/Source/Flow/Private/Nodes/Actor/FlowNode_PlayLevelSequence.cpp +++ b/Source/Flow/Private/Nodes/Actor/FlowNode_PlayLevelSequence.cpp @@ -300,6 +300,8 @@ void UFlowNode_PlayLevelSequence::Cleanup() #if ENABLE_VISUAL_LOG UE_VLOG(this, LogFlow, Log, TEXT("Finished playback: %s"), *Sequence.ToString()); #endif + + Super::Cleanup(); } FString UFlowNode_PlayLevelSequence::GetPlaybackProgress() const diff --git a/Source/Flow/Private/Nodes/Graph/FlowNode_SubGraph.cpp b/Source/Flow/Private/Nodes/Graph/FlowNode_SubGraph.cpp index 6c0e374a0..047737d36 100644 --- a/Source/Flow/Private/Nodes/Graph/FlowNode_SubGraph.cpp +++ b/Source/Flow/Private/Nodes/Graph/FlowNode_SubGraph.cpp @@ -86,6 +86,8 @@ void UFlowNode_SubGraph::Cleanup() { GetFlowSubsystem()->RemoveSubFlow(this, EFlowFinishPolicy::Keep); } + + Super::Cleanup(); } void UFlowNode_SubGraph::ForceFinishNode() diff --git a/Source/Flow/Private/Nodes/Route/FlowNode_Counter.cpp b/Source/Flow/Private/Nodes/Route/FlowNode_Counter.cpp index f6a4cd701..43f94de55 100644 --- a/Source/Flow/Private/Nodes/Route/FlowNode_Counter.cpp +++ b/Source/Flow/Private/Nodes/Route/FlowNode_Counter.cpp @@ -65,6 +65,8 @@ void UFlowNode_Counter::ExecuteInput(const FName& PinName) void UFlowNode_Counter::Cleanup() { CurrentSum = 0; + + Super::Cleanup(); } #if WITH_EDITOR diff --git a/Source/Flow/Private/Nodes/Route/FlowNode_ExecutionMultiGate.cpp b/Source/Flow/Private/Nodes/Route/FlowNode_ExecutionMultiGate.cpp index a7e05289e..ca16183b3 100644 --- a/Source/Flow/Private/Nodes/Route/FlowNode_ExecutionMultiGate.cpp +++ b/Source/Flow/Private/Nodes/Route/FlowNode_ExecutionMultiGate.cpp @@ -96,6 +96,8 @@ void UFlowNode_ExecutionMultiGate::Cleanup() { NextOutput = 0; Completed.Reset(); + + Super::Cleanup(); } #if WITH_EDITOR diff --git a/Source/Flow/Private/Nodes/Route/FlowNode_ExecutionSequence.cpp b/Source/Flow/Private/Nodes/Route/FlowNode_ExecutionSequence.cpp index 386dbaa81..4dc8509ea 100644 --- a/Source/Flow/Private/Nodes/Route/FlowNode_ExecutionSequence.cpp +++ b/Source/Flow/Private/Nodes/Route/FlowNode_ExecutionSequence.cpp @@ -42,6 +42,8 @@ void UFlowNode_ExecutionSequence::OnLoad_Implementation() void UFlowNode_ExecutionSequence::Cleanup() { ExecutedConnections.Empty(); + + Super::Cleanup(); } void UFlowNode_ExecutionSequence::ExecuteNewConnections() diff --git a/Source/Flow/Private/Nodes/Route/FlowNode_Timer.cpp b/Source/Flow/Private/Nodes/Route/FlowNode_Timer.cpp index 184862c39..2e842dd9c 100644 --- a/Source/Flow/Private/Nodes/Route/FlowNode_Timer.cpp +++ b/Source/Flow/Private/Nodes/Route/FlowNode_Timer.cpp @@ -155,6 +155,8 @@ void UFlowNode_Timer::Cleanup() StepTimerHandle.Invalidate(); SumOfSteps = 0.0f; + + Super::Cleanup(); } void UFlowNode_Timer::OnSave_Implementation() From b3c7e759a219c7903eb2d60413de8a230fdf25d8 Mon Sep 17 00:00:00 2001 From: Rhillion Date: Wed, 19 Feb 2025 16:37:07 +0000 Subject: [PATCH 2/5] Added addon descriptions to node descriptions, with editor settings option to disable --- Source/Flow/Private/Nodes/FlowNodeBase.cpp | 14 ++++++++++++++ Source/Flow/Public/Nodes/FlowNodeBase.h | 3 +++ .../Private/Graph/Nodes/FlowGraphNode.cpp | 4 ++++ .../Public/Graph/FlowGraphEditorSettings.h | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/Source/Flow/Private/Nodes/FlowNodeBase.cpp b/Source/Flow/Private/Nodes/FlowNodeBase.cpp index fe646b4b0..b1393a2f4 100644 --- a/Source/Flow/Private/Nodes/FlowNodeBase.cpp +++ b/Source/Flow/Private/Nodes/FlowNodeBase.cpp @@ -784,6 +784,20 @@ FString UFlowNodeBase::GetNodeDescription() const { return K2_GetNodeDescription(); } + +FString UFlowNodeBase::GetNodeDescriptionWithAddons() const +{ + FString Description = GetNodeDescription(); + FString AddonDescriptions = FString::JoinBy(AddOns, + LINE_TERMINATOR, + [](const UFlowNodeBase* Addon) { return Addon->GetNodeDescriptionWithAddons(); }); + if (!AddonDescriptions.IsEmpty()) + { + return Description.Append(LINE_TERMINATOR).Append(AddonDescriptions); + } + + return Description; +} #endif void UFlowNodeBase::SetNodeConfigText(const FText& NodeConfigText) diff --git a/Source/Flow/Public/Nodes/FlowNodeBase.h b/Source/Flow/Public/Nodes/FlowNodeBase.h index a9efca067..ed957efcb 100644 --- a/Source/Flow/Public/Nodes/FlowNodeBase.h +++ b/Source/Flow/Public/Nodes/FlowNodeBase.h @@ -382,6 +382,9 @@ class FLOW_API UFlowNodeBase public: // Short summary of node's content - displayed over node as NodeInfoPopup virtual FString GetNodeDescription() const; + + // Complex summary of node's content including its addons + FString GetNodeDescriptionWithAddons() const; #endif protected: diff --git a/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp b/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp index d24aab90b..17c8c2c22 100644 --- a/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp +++ b/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp @@ -711,6 +711,10 @@ FString UFlowGraphNode::GetNodeDescription() const { if (NodeInstance && (GEditor->PlayWorld == nullptr || UFlowGraphEditorSettings::Get()->bShowNodeDescriptionWhilePlaying)) { + if (UFlowGraphEditorSettings::Get()->bShowAddonNodeDescriptions) + { + return NodeInstance->GetNodeDescriptionWithAddons(); + } return NodeInstance->GetNodeDescription(); } diff --git a/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h b/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h index 6e3546702..f45a1f7aa 100644 --- a/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h +++ b/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h @@ -52,6 +52,10 @@ class FLOWEDITOR_API UFlowGraphEditorSettings : public UDeveloperSettings UPROPERTY(config, EditAnywhere, Category = "Nodes", meta = (EditCondition = "bShowSubGraphPreview")) FVector2D SubGraphPreviewSize; + + // Display descriptions from attached addons in node descriptions + UPROPERTY(EditAnywhere, config, Category = "Nodes") + bool bShowAddonNodeDescriptions = true; /** Enable hot reload for native flow nodes? * WARNING: hot reload can easily crash the editor and you can lose progress */ From eef4d694fe63a2dc554bea98e5d11990a6d7702a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Justy=C5=84ski?= Date: Wed, 28 Jan 2026 18:33:18 +0100 Subject: [PATCH 3/5] bad merge fix --- Source/Flow/Private/Nodes/FlowNodeBase.cpp | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/Source/Flow/Private/Nodes/FlowNodeBase.cpp b/Source/Flow/Private/Nodes/FlowNodeBase.cpp index 45e8faf69..9a2d972cc 100644 --- a/Source/Flow/Private/Nodes/FlowNodeBase.cpp +++ b/Source/Flow/Private/Nodes/FlowNodeBase.cpp @@ -743,8 +743,100 @@ FString UFlowNodeBase::GetNodeDescriptionWithAddons() const return Description; } +bool UFlowNodeBase::CanModifyFlowDataPinType() const +{ + return !IsPlacedInFlowAsset() || IsFlowNamedPropertiesSupplier(); +} + +bool UFlowNodeBase::ShowFlowDataPinValueInputPinCheckbox() const +{ + const bool bIsPlacedInFlowAsset = IsPlacedInFlowAsset(); + return !bIsPlacedInFlowAsset; +} + +bool UFlowNodeBase::ShowFlowDataPinValueClassFilter(const FFlowDataPinValue* Value) const +{ + const bool bIsPlacedInFlowAsset = IsPlacedInFlowAsset(); + const bool bIsFlowNamedPropertiesSupplier = IsFlowNamedPropertiesSupplier(); + return !bIsPlacedInFlowAsset || bIsFlowNamedPropertiesSupplier; +} + +bool UFlowNodeBase::CanEditFlowDataPinValueClassFilter(const FFlowDataPinValue* Value) const +{ + const bool bIsPlacedInFlowAsset = IsPlacedInFlowAsset(); + const bool bIsFlowNamedPropertiesSupplier = IsFlowNamedPropertiesSupplier(); + return !bIsPlacedInFlowAsset || bIsFlowNamedPropertiesSupplier; +} + +bool UFlowNodeBase::IsPlacedInFlowAsset() const +{ + return GetFlowAsset() != nullptr; +} + +bool UFlowNodeBase::IsFlowNamedPropertiesSupplier() const +{ + return Implements(); +} #endif +FText UFlowNodeBase::K2_GetNodeTitle_Implementation() const +{ +#if WITH_EDITOR + if (GetClass()->ClassGeneratedBy) + { + const FString& BlueprintTitle = Cast(GetClass()->ClassGeneratedBy)->BlueprintDisplayName; + if (!BlueprintTitle.IsEmpty()) + { + return FText::FromString(BlueprintTitle); + } + } + + static const FName NAME_DisplayName(TEXT("DisplayName")); + if (bDisplayNodeTitleWithoutPrefix && !GetClass()->HasMetaData(NAME_DisplayName)) + { + return GetGeneratedDisplayName(); + } + + return GetClass()->GetDisplayNameText(); +#else + return FText::GetEmpty(); +#endif +} + +FText UFlowNodeBase::K2_GetNodeToolTip_Implementation() const +{ +#if WITH_EDITOR + if (GetClass()->ClassGeneratedBy) + { + const FString& BlueprintToolTip = Cast(GetClass()->ClassGeneratedBy)->BlueprintDescription; + if (!BlueprintToolTip.IsEmpty()) + { + return FText::FromString(BlueprintToolTip); + } + } + + static const FName NAME_Tooltip(TEXT("Tooltip")); + if (bDisplayNodeTitleWithoutPrefix && !GetClass()->HasMetaData(NAME_Tooltip)) + { + return GetGeneratedDisplayName(); + } + + // GetClass()->GetToolTipText() can return meta = (DisplayName = ... ), but ignore BlueprintDisplayName even if it is BP Node + if (GetClass()->ClassGeneratedBy) + { + const FString& BlueprintTitle = Cast(GetClass()->ClassGeneratedBy)->BlueprintDisplayName; + if (!BlueprintTitle.IsEmpty()) + { + return FText::FromString(BlueprintTitle); + } + } + + return GetClass()->GetToolTipText(); +#else + return FText::GetEmpty(); +#endif +} + FText UFlowNodeBase::GetNodeConfigText() const { #if WITH_EDITORONLY_DATA From 2bd91ddade0cb2e9713feceb67d8b65afa4eff70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Justy=C5=84ski?= Date: Wed, 28 Jan 2026 18:33:47 +0100 Subject: [PATCH 4/5] formatting fix --- Source/Flow/Private/Nodes/FlowNodeBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Flow/Private/Nodes/FlowNodeBase.cpp b/Source/Flow/Private/Nodes/FlowNodeBase.cpp index 9a2d972cc..eee269607 100644 --- a/Source/Flow/Private/Nodes/FlowNodeBase.cpp +++ b/Source/Flow/Private/Nodes/FlowNodeBase.cpp @@ -743,6 +743,7 @@ FString UFlowNodeBase::GetNodeDescriptionWithAddons() const return Description; } + bool UFlowNodeBase::CanModifyFlowDataPinType() const { return !IsPlacedInFlowAsset() || IsFlowNamedPropertiesSupplier(); From 9c13dc5be094ebb343ae972c061f5c9f815ce970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Justy=C5=84ski?= Date: Sun, 15 Feb 2026 13:28:47 +0100 Subject: [PATCH 5/5] simplified code a bit --- Source/Flow/Private/Nodes/FlowNodeBase.cpp | 16 +++------- Source/Flow/Public/Nodes/FlowNodeBase.h | 2 +- .../Private/Graph/FlowGraphEditorSettings.cpp | 1 + .../Private/Graph/Nodes/FlowGraphNode.cpp | 31 ++++++++++++------- .../Public/Graph/FlowGraphEditorSettings.h | 10 +++--- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/Source/Flow/Private/Nodes/FlowNodeBase.cpp b/Source/Flow/Private/Nodes/FlowNodeBase.cpp index eee269607..9a8a8864b 100644 --- a/Source/Flow/Private/Nodes/FlowNodeBase.cpp +++ b/Source/Flow/Private/Nodes/FlowNodeBase.cpp @@ -730,18 +730,12 @@ FString UFlowNodeBase::GetNodeDescription() const return K2_GetNodeDescription(); } -FString UFlowNodeBase::GetNodeDescriptionWithAddons() const +FString UFlowNodeBase::GetAddOnDescriptions() const { - FString Description = GetNodeDescription(); - FString AddonDescriptions = FString::JoinBy(AddOns, - LINE_TERMINATOR, - [](const UFlowNodeBase* Addon) { return Addon->GetNodeDescriptionWithAddons(); }); - if (!AddonDescriptions.IsEmpty()) + return FString::JoinBy(AddOns, LINE_TERMINATOR, [](const UFlowNodeBase* Addon) { - return Description.Append(LINE_TERMINATOR).Append(AddonDescriptions); - } - - return Description; + return Addon->GetNodeDescription(); + }); } bool UFlowNodeBase::CanModifyFlowDataPinType() const @@ -976,7 +970,7 @@ bool UFlowNodeBase::BuildMessage(FString& Message) const EDataValidationResult UFlowNodeBase::ValidateNode() { EDataValidationResult ValidationResult = EDataValidationResult::NotValidated; - + if (GetClass()->IsFunctionImplementedInScript(GET_FUNCTION_NAME_CHECKED(UFlowNodeBase, K2_ValidateNode))) { ValidationResult = K2_ValidateNode(); diff --git a/Source/Flow/Public/Nodes/FlowNodeBase.h b/Source/Flow/Public/Nodes/FlowNodeBase.h index ae52d6452..5d4b38cc5 100644 --- a/Source/Flow/Public/Nodes/FlowNodeBase.h +++ b/Source/Flow/Public/Nodes/FlowNodeBase.h @@ -458,7 +458,7 @@ class FLOW_API UFlowNodeBase virtual FString GetNodeDescription() const; // Complex summary of node's content including its addons - FString GetNodeDescriptionWithAddons() const; + FString GetAddOnDescriptions() const; #endif protected: diff --git a/Source/FlowEditor/Private/Graph/FlowGraphEditorSettings.cpp b/Source/FlowEditor/Private/Graph/FlowGraphEditorSettings.cpp index 766ed1b87..47c7f7a52 100644 --- a/Source/FlowEditor/Private/Graph/FlowGraphEditorSettings.cpp +++ b/Source/FlowEditor/Private/Graph/FlowGraphEditorSettings.cpp @@ -9,6 +9,7 @@ UFlowGraphEditorSettings::UFlowGraphEditorSettings() : NodeDoubleClickTarget(EFlowNodeDoubleClickTarget::PrimaryAssetOrNodeDefinition) , bShowNodeClass(false) , bShowNodeDescriptionWhilePlaying(true) + , bShowAddonDescriptions(true) , bEnforceFriendlyPinNames(false) , bShowSubGraphPreview(true) , bShowSubGraphPath(true) diff --git a/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp b/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp index 362335d2b..0910dca4b 100644 --- a/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp +++ b/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp @@ -359,7 +359,7 @@ void UFlowGraphNode::ReconstructNode() { FlowNode->UpdateNodeConfigText(); } - + // This ensures the graph editor 'Refresh' button still rebuilds all the graph widgets even if the FlowGraphNode has nothing to update // Ideally we could get rid of the 'Refresh' button, but I think it will keep being useful, esp. for users making rough custom widgets (void)OnReconstructNodeCompleted.ExecuteIfBound(); @@ -733,13 +733,24 @@ FText UFlowGraphNode::GetTooltipText() const FString UFlowGraphNode::GetNodeDescription() const { - if (NodeInstance && (GEditor->PlayWorld == nullptr || UFlowGraphEditorSettings::Get()->bShowNodeDescriptionWhilePlaying)) + if (NodeInstance) { - if (UFlowGraphEditorSettings::Get()->bShowAddonNodeDescriptions) + const UFlowGraphEditorSettings* GraphEditorSettings = GetDefault(); + if (GEditor->PlayWorld == nullptr || GraphEditorSettings->bShowNodeDescriptionWhilePlaying) { - return NodeInstance->GetNodeDescriptionWithAddons(); + FString Result = NodeInstance->GetNodeDescription(); + + if (GraphEditorSettings->bShowAddonDescriptions) + { + FString AddonDescriptions = NodeInstance->GetAddOnDescriptions(); + if (!AddonDescriptions.IsEmpty()) + { + return Result.Append(LINE_TERMINATOR).Append(AddonDescriptions); + } + } + + return Result; } - return NodeInstance->GetNodeDescription(); } return FString(); @@ -1528,7 +1539,7 @@ void UFlowGraphNode::RemoveSubNode(UFlowGraphNode* SubNode) { SubNode->NodeInstance->OnAddOnRequestedParentReconstruction.Unbind(); } - + SubNodes.RemoveSingle(SubNode); RebuildRuntimeAddOnsFromEditorSubNodes(); @@ -1545,7 +1556,7 @@ void UFlowGraphNode::RemoveAllSubNodes() SubNode->NodeInstance->OnAddOnRequestedParentReconstruction.Unbind(); } } - + SubNodes.Reset(); RebuildRuntimeAddOnsFromEditorSubNodes(); @@ -1839,8 +1850,7 @@ bool UFlowGraphNode::TryUpdateNodePins() const bool bPinsChanged = false; - if (!FlowNodeInstance->CanUserAddInput() && - !CheckPinsMatch(RequiredNodeInputPins, ExistingNodeInputPins)) + if (!FlowNodeInstance->CanUserAddInput() && !CheckPinsMatch(RequiredNodeInputPins, ExistingNodeInputPins)) { FlowNodeInstance->Modify(); @@ -1850,8 +1860,7 @@ bool UFlowGraphNode::TryUpdateNodePins() const bPinsChanged = true; } - if (!FlowNodeInstance->CanUserAddOutput() && - !CheckPinsMatch(RequiredNodeOutputPins, ExistingNodeOutputPins)) + if (!FlowNodeInstance->CanUserAddOutput() && !CheckPinsMatch(RequiredNodeOutputPins, ExistingNodeOutputPins)) { FlowNodeInstance->Modify(); diff --git a/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h b/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h index 8e558d12d..074daedca 100644 --- a/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h +++ b/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h @@ -44,7 +44,11 @@ class FLOWEDITOR_API UFlowGraphEditorSettings : public UDeveloperSettings UPROPERTY(config, EditAnywhere, Category = "Nodes") bool bShowNodeDescriptionWhilePlaying; - // Pin names will will be displayed in a format that is easier to read, even if PinFriendlyName wasn't set + // Display descriptions from attached addons in node descriptions + UPROPERTY(EditAnywhere, config, Category = "Nodes") + bool bShowAddonDescriptions; + + // Pin names will be displayed in a format that is easier to read, even if PinFriendlyName wasn't set UPROPERTY(EditAnywhere, config, Category = "Nodes") bool bEnforceFriendlyPinNames; @@ -57,10 +61,6 @@ class FLOWEDITOR_API UFlowGraphEditorSettings : public UDeveloperSettings UPROPERTY(config, EditAnywhere, Category = "Nodes", meta = (EditCondition = "bShowSubGraphPreview")) FVector2D SubGraphPreviewSize; - - // Display descriptions from attached addons in node descriptions - UPROPERTY(EditAnywhere, config, Category = "Nodes") - bool bShowAddonNodeDescriptions = true; /** Enable hot reload for native flow nodes? * WARNING: hot reload can easily crash the editor and you can lose progress */