From c77c2e4c55938263080c39c4407a5a81b1b48b95 Mon Sep 17 00:00:00 2001 From: MaksymKapelianovych Date: Mon, 6 May 2024 11:46:50 +0300 Subject: [PATCH 1/5] Mark bEnabled as UPROPERTY to keep breakpoint state between editor sessions --- Source/Flow/Public/Nodes/FlowPin.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Flow/Public/Nodes/FlowPin.h b/Source/Flow/Public/Nodes/FlowPin.h index 950e9373..033edc4b 100644 --- a/Source/Flow/Public/Nodes/FlowPin.h +++ b/Source/Flow/Public/Nodes/FlowPin.h @@ -221,6 +221,7 @@ struct FLOW_API FFlowPinTrait UPROPERTY() uint8 bTraitAllowed : 1; + UPROPERTY() uint8 bEnabled : 1; uint8 bHit : 1; From c835fe420fa3f7a3bc383ffe24fe82f8f1a842fb Mon Sep 17 00:00:00 2001 From: MaksymKapelianovych Date: Tue, 14 May 2024 15:31:21 +0300 Subject: [PATCH 2/5] Flow Traits are now stored locally for every user --- Source/Flow/Private/Nodes/FlowPin.cpp | 84 +--- Source/Flow/Public/Nodes/FlowPin.h | 45 -- .../Private/Asset/FlowDebuggerSubsystem.cpp | 388 ++++++++++++++++++ .../Private/Graph/FlowGraphEditor.cpp | 103 +++-- .../Private/Graph/Nodes/FlowGraphNode.cpp | 45 +- .../Private/Graph/Widgets/SFlowGraphNode.cpp | 59 +-- .../Public/Asset/FlowDebuggerSubsystem.h | 149 +++++++ .../Public/Graph/FlowGraphEditorSettings.h | 23 ++ .../Public/Graph/Nodes/FlowGraphNode.h | 8 +- .../Public/Graph/Widgets/SFlowGraphNode.h | 3 +- 10 files changed, 669 insertions(+), 238 deletions(-) diff --git a/Source/Flow/Private/Nodes/FlowPin.cpp b/Source/Flow/Private/Nodes/FlowPin.cpp index b6808ece..9c606029 100644 --- a/Source/Flow/Private/Nodes/FlowPin.cpp +++ b/Source/Flow/Private/Nodes/FlowPin.cpp @@ -37,86 +37,4 @@ FORCEINLINE FString FPinRecord::DoubleDigit(const int32 Number) { return Number > 9 ? FString::FromInt(Number) : TEXT("0") + FString::FromInt(Number); } -#endif - -////////////////////////////////////////////////////////////////////////// -// Pin Trait - -void FFlowPinTrait::AllowTrait() -{ - if (!bTraitAllowed) - { - bTraitAllowed = true; - bEnabled = true; - } -} - -void FFlowPinTrait::DisallowTrait() -{ - if (bTraitAllowed) - { - bTraitAllowed = false; - bEnabled = false; - } -} - -bool FFlowPinTrait::IsAllowed() const -{ - return bTraitAllowed; -} - -void FFlowPinTrait::EnableTrait() -{ - if (bTraitAllowed && !bEnabled) - { - bEnabled = true; - } -} - -void FFlowPinTrait::DisableTrait() -{ - if (bTraitAllowed && bEnabled) - { - bEnabled = false; - } -} - -void FFlowPinTrait::ToggleTrait() -{ - if (bTraitAllowed) - { - bTraitAllowed = false; - bEnabled = false; - } - else - { - bTraitAllowed = true; - bEnabled = true; - } -} - -bool FFlowPinTrait::CanEnable() const -{ - return bTraitAllowed && !bEnabled; -} - -bool FFlowPinTrait::IsEnabled() const -{ - return bTraitAllowed && bEnabled; -} - -void FFlowPinTrait::MarkAsHit() -{ - bHit = true; -} - -void FFlowPinTrait::ResetHit() -{ - bHit = false; -} - -bool FFlowPinTrait::IsHit() const -{ - return bHit; -} - +#endif \ No newline at end of file diff --git a/Source/Flow/Public/Nodes/FlowPin.h b/Source/Flow/Public/Nodes/FlowPin.h index 033edc4b..1f5c2d82 100644 --- a/Source/Flow/Public/Nodes/FlowPin.h +++ b/Source/Flow/Public/Nodes/FlowPin.h @@ -210,48 +210,3 @@ struct FLOW_API FPinRecord FORCEINLINE static FString DoubleDigit(const int32 Number); }; #endif - -// It can represent any trait added on the specific node instance, i.e. breakpoint -USTRUCT() -struct FLOW_API FFlowPinTrait -{ - GENERATED_USTRUCT_BODY() - -protected: - UPROPERTY() - uint8 bTraitAllowed : 1; - - UPROPERTY() - uint8 bEnabled : 1; - uint8 bHit : 1; - -public: - FFlowPinTrait() - : bTraitAllowed(false) - , bEnabled(false) - , bHit(false) - { - }; - - explicit FFlowPinTrait(const bool bInitialState) - : bTraitAllowed(bInitialState) - , bEnabled(bInitialState) - , bHit(false) - { - }; - - void AllowTrait(); - void DisallowTrait(); - bool IsAllowed() const; - - void EnableTrait(); - void DisableTrait(); - void ToggleTrait(); - - bool CanEnable() const; - bool IsEnabled() const; - - void MarkAsHit(); - void ResetHit(); - bool IsHit() const; -}; diff --git a/Source/FlowEditor/Private/Asset/FlowDebuggerSubsystem.cpp b/Source/FlowEditor/Private/Asset/FlowDebuggerSubsystem.cpp index 94715f0a..46264a5d 100644 --- a/Source/FlowEditor/Private/Asset/FlowDebuggerSubsystem.cpp +++ b/Source/FlowEditor/Private/Asset/FlowDebuggerSubsystem.cpp @@ -12,12 +12,30 @@ #include "Framework/Notifications/NotificationManager.h" #include "Templates/Function.h" #include "UnrealEdGlobals.h" +#include "Graph/FlowGraphEditorSettings.h" +#include "Graph/Nodes/FlowGraphNode.h" #include "Widgets/Notifications/SNotificationList.h" #include UE_INLINE_GENERATED_CPP_BY_NAME(FlowDebuggerSubsystem) #define LOCTEXT_NAMESPACE "FlowDebuggerSubsystem" +////////////////////////////////////////////////////////////////////////// +// Flow Debug Trait + +bool FFlowDebugTrait::IsEnabled() const +{ + return bEnabled; +} + +bool FFlowDebugTrait::IsHit() const +{ + return bHit; +} + +////////////////////////////////////////////////////////////////////////// +// UFlowDebuggerSubsystem + UFlowDebuggerSubsystem::UFlowDebuggerSubsystem() { FEditorDelegates::BeginPIE.AddUObject(this, &UFlowDebuggerSubsystem::OnBeginPIE); @@ -129,4 +147,374 @@ bool UFlowDebuggerSubsystem::IsPlaySessionPaused() return AreAllGameWorldPaused(); } +void UFlowDebuggerSubsystem::CreateTrait(const UFlowGraphNode* OwnerNode, EFlowTraitType Type, bool bEnabled) +{ + UFlowGraphEditorSettings* Settings = GetMutableDefault(); + check(Settings); + FFlowTraitSettings& TraitSettings = Settings->PerNodeTraits.FindOrAdd(OwnerNode->NodeGuid); + + // ensure that this node doesn't already contain a trait with provided type + checkSlow(!TraitSettings.NodeTraits.ContainsByPredicate([Type](const FFlowDebugTrait& Trait) + { + return Trait.Type == Type; + })); + + TraitSettings.NodeTraits.Emplace(Type, bEnabled); + SaveFlowGraphEditorSettings(); +} + +void UFlowDebuggerSubsystem::CreateTrait(const UEdGraphPin* OwnerPin, EFlowTraitType Type, bool bEnabled) +{ + UFlowGraphEditorSettings* Settings = GetMutableDefault(); + check(Settings); + FFlowTraitSettings& TraitSettings = Settings->PerNodeTraits.FindOrAdd(OwnerPin->GetOwningNode()->NodeGuid); + + // ensure that this pin doesn't already contain a trait with provided type + checkSlow(!TraitSettings.PinTraits.ContainsByPredicate([OwnerPin, Type](const FFlowDebugTrait& Trait) + { + return Trait.PinId == OwnerPin->PinId && Trait.Type == Type; + })); + + TraitSettings.PinTraits.Emplace(Type, OwnerPin->PinId, bEnabled); + SaveFlowGraphEditorSettings(); +} + +void UFlowDebuggerSubsystem::RemoveTrait(const UFlowGraphNode* OwnerNode, EFlowTraitType Type) +{ + RemoveNodeTraitByPredicate(OwnerNode, [Type](const FFlowDebugTrait& Trait) + { + return Trait.Type == Type; + }); +} + +void UFlowDebuggerSubsystem::RemoveTrait(const UEdGraphPin* OwnerPin, EFlowTraitType Type) +{ + RemovePinTraitByPredicate(OwnerPin, [OwnerPin, Type](const FFlowDebugTrait& Trait) + { + return Trait.PinId == OwnerPin->PinId && Trait.Type == Type; + }); +} + +void UFlowDebuggerSubsystem::RemoveNodeTraitByPredicate(const UFlowGraphNode* OwnerNode, + const TFunctionRef Predicate) +{ + if(TArray* Traits = GetNodeTraits(OwnerNode)) + { + if (Traits->RemoveAllSwap(Predicate, EAllowShrinking::No)) + { + if(Traits->IsEmpty()) + { + ClearNodeTraits(OwnerNode); + } + SaveFlowGraphEditorSettings(); + } + } +} + +void UFlowDebuggerSubsystem::RemovePinTraitByPredicate(const UFlowGraphNode* OwnerNode, + const TFunctionRef Predicate) +{ + if(TArray* Traits = GetPinTraits(OwnerNode)) + { + if (Traits->RemoveAllSwap(Predicate, EAllowShrinking::No)) + { + if(Traits->IsEmpty()) + { + ClearPinTraits(OwnerNode); + } + SaveFlowGraphEditorSettings(); + } + } +} + +void UFlowDebuggerSubsystem::RemovePinTraitByPredicate(const UEdGraphPin* OwnerPin, + const TFunctionRef Predicate) +{ + const UFlowGraphNode* OwnerNode = Cast(OwnerPin->GetOwningNode()); + check(OwnerNode); + + if(TArray* Traits = GetPinTraits(OwnerNode)) + { + if (Traits->RemoveAllSwap(Predicate, EAllowShrinking::No)) + { + if(Traits->IsEmpty()) + { + ClearPinTraits(OwnerPin); + } + SaveFlowGraphEditorSettings(); + } + } +} + +void UFlowDebuggerSubsystem::ClearNodeTraits(const UFlowGraphNode* OwnerNode) +{ + if (FFlowTraitSettings* TraitSettings = GetPerNodeSettings(OwnerNode)) + { + TraitSettings->NodeTraits.Empty(); + + // if all settings data is default, we can remove it from the map + if(*TraitSettings == FFlowTraitSettings()) + { + UFlowGraphEditorSettings* Settings = GetMutableDefault(); + Settings->PerNodeTraits.Remove(OwnerNode->NodeGuid); + } + + SaveFlowGraphEditorSettings(); + } +} + +void UFlowDebuggerSubsystem::ClearPinTraits(const UFlowGraphNode* OwnerNode) +{ + if (FFlowTraitSettings* TraitSettings = GetPerNodeSettings(OwnerNode)) + { + TraitSettings->PinTraits.Empty(); + + // if all settings data is default, we can remove it from the map + if(*TraitSettings == FFlowTraitSettings()) + { + UFlowGraphEditorSettings* Settings = GetMutableDefault(); + Settings->PerNodeTraits.Remove(OwnerNode->NodeGuid); + } + + SaveFlowGraphEditorSettings(); + } +} + +void UFlowDebuggerSubsystem::ClearPinTraits(const UEdGraphPin* OwnerPin) +{ + UFlowGraphNode* OwnerNode = Cast(OwnerPin->GetOwningNode()); + check(OwnerNode); + + if (FFlowTraitSettings* TraitSettings = GetPerNodeSettings(OwnerNode)) + { + TraitSettings->PinTraits.RemoveAllSwap([OwnerPin](const FFlowDebugTrait& Trait) + { + return Trait.PinId == OwnerPin->PinId; + }); + + // if all settings data is default, we can remove it from the map + if(*TraitSettings == FFlowTraitSettings()) + { + UFlowGraphEditorSettings* Settings = GetMutableDefault(); + Settings->PerNodeTraits.Remove(OwnerNode->NodeGuid); + } + + SaveFlowGraphEditorSettings(); + } +} + +void UFlowDebuggerSubsystem::CleanupTraits(const UFlowGraphNode* OwnerNode) +{ + RemovePinTraitByPredicate(OwnerNode, [OwnerNode](const FFlowDebugTrait& Trait) + { + auto Predicate = [Trait](const UEdGraphPin* Pin) + { + return Pin->PinId == Trait.PinId; + }; + return OwnerNode->Pins.ContainsByPredicate(Predicate) == false; + }); +} + +FFlowDebugTrait* UFlowDebuggerSubsystem::FindTrait(const UFlowGraphNode* OwnerNode, EFlowTraitType Type) +{ + if(TArray* Traits = GetNodeTraits(OwnerNode)) + { + for(FFlowDebugTrait& Trait : *Traits) + { + if(Trait.Type == Type) + { + return &Trait; + } + } + } + + return nullptr; +} + +FFlowDebugTrait* UFlowDebuggerSubsystem::FindTrait(const UEdGraphPin* OwnerPin, EFlowTraitType Type) +{ + const UFlowGraphNode* OwnerNode = Cast(OwnerPin->GetOwningNode()); + check(OwnerNode); + + if(TArray* Traits = GetPinTraits(OwnerNode)) + { + for(FFlowDebugTrait& Trait : *Traits) + { + if(Trait.PinId == OwnerPin->PinId && Trait.Type == Type) + { + return &Trait; + } + } + } + + return nullptr; +} + +void UFlowDebuggerSubsystem::SetTraitEnabled(const UFlowGraphNode* OwnerNode, EFlowTraitType Type, bool bIsEnabled) +{ + if (FFlowDebugTrait* Trait = FindTrait(OwnerNode, Type)) + { + Trait->bEnabled = bIsEnabled; + SaveFlowGraphEditorSettings(); + } +} + +void UFlowDebuggerSubsystem::SetTraitEnabled(const UEdGraphPin* OwnerPin, EFlowTraitType Type, bool bIsEnabled) +{ + if (FFlowDebugTrait* Trait = FindTrait(OwnerPin, Type)) + { + Trait->bEnabled = bIsEnabled; + SaveFlowGraphEditorSettings(); + } +} + +bool UFlowDebuggerSubsystem::IsTraitEnabled(const UFlowGraphNode* OwnerNode, EFlowTraitType Type) +{ + if (const FFlowDebugTrait* Trait = FindTrait(OwnerNode, Type)) + { + return Trait->IsEnabled(); + } + + return false; +} + +bool UFlowDebuggerSubsystem::IsTraitEnabled(const UEdGraphPin* OwnerPin, EFlowTraitType Type) +{ + if (const FFlowDebugTrait* Trait = FindTrait(OwnerPin, Type)) + { + return Trait->IsEnabled(); + } + + return false; +} + +void UFlowDebuggerSubsystem::ToggleTrait(const UFlowGraphNode* OwnerNode, EFlowTraitType Type) +{ + if (FindTrait(OwnerNode, Type)) + { + RemoveTrait(OwnerNode, Type); + } + else + { + CreateTrait(OwnerNode, Type, true); + } +} + +void UFlowDebuggerSubsystem::ToggleTrait(const UEdGraphPin* OwnerPin, EFlowTraitType Type) +{ + if (FindTrait(OwnerPin, Type)) + { + RemoveTrait(OwnerPin, Type); + } + else + { + CreateTrait(OwnerPin, Type, true); + } +} + +TArray UFlowDebuggerSubsystem::SetAllTraitsHit(const UFlowGraphNode* OwnerNode, bool bHit) +{ + TArray HitTraitTypes; + for (EFlowTraitType Type : TEnumRange()) + { + if (SetTraitHit(OwnerNode, Type, bHit)) + { + HitTraitTypes.Add(Type); + } + } + + return HitTraitTypes; +} + +TArray UFlowDebuggerSubsystem::SetAllTraitsHit(const UEdGraphPin* OwnerPin, bool bHit) +{ + TArray HitTraitTypes; + for (EFlowTraitType Type : TEnumRange()) + { + if (SetTraitHit(OwnerPin, Type, bHit)) + { + HitTraitTypes.Add(Type); + } + } + + return HitTraitTypes; +} + + +bool UFlowDebuggerSubsystem::SetTraitHit(const UFlowGraphNode* OwnerNode, EFlowTraitType Type, bool bHit) +{ + if (FFlowDebugTrait* Trait = FindTrait(OwnerNode, Type)) + { + Trait->bHit = bHit; + return true; + } + + return false; +} + +bool UFlowDebuggerSubsystem::SetTraitHit(const UEdGraphPin* OwnerPin, EFlowTraitType Type, bool bHit) +{ + if (FFlowDebugTrait* Trait = FindTrait(OwnerPin, Type)) + { + Trait->bHit = bHit; + return true; + } + + return false; +} + +bool UFlowDebuggerSubsystem::IsTraitHit(const UFlowGraphNode* OwnerNode, EFlowTraitType Type) +{ + if (const FFlowDebugTrait* Trait = FindTrait(OwnerNode, Type)) + { + return Trait->IsHit(); + } + + return false; +} + +bool UFlowDebuggerSubsystem::IsTraitHit(const UEdGraphPin* OwnerPin, EFlowTraitType Type) +{ + if (const FFlowDebugTrait* Trait = FindTrait(OwnerPin, Type)) + { + return Trait->IsHit(); + } + + return false; +} + +FFlowTraitSettings* UFlowDebuggerSubsystem::GetPerNodeSettings(const UFlowGraphNode* OwnerNode) +{ + UFlowGraphEditorSettings* Settings = GetMutableDefault(); + check(Settings); + return Settings->PerNodeTraits.Find(OwnerNode->NodeGuid); +} + +TArray* UFlowDebuggerSubsystem::GetNodeTraits(const UFlowGraphNode* OwnerNode) +{ + FFlowTraitSettings* Settings = GetPerNodeSettings(OwnerNode); + + // return nullptr if there's no node traits associated w/ this flow node + return (!Settings || Settings->NodeTraits.IsEmpty()) ? + nullptr : + &Settings->NodeTraits; +} + +TArray* UFlowDebuggerSubsystem::GetPinTraits(const UFlowGraphNode* OwnerNode) +{ + FFlowTraitSettings* Settings = GetPerNodeSettings(OwnerNode); + + // return nullptr if there's no pin traits associated w/ this flow node + return (!Settings || Settings->PinTraits.IsEmpty()) ? + nullptr : + &Settings->PinTraits; +} + +void UFlowDebuggerSubsystem::SaveFlowGraphEditorSettings() +{ + UFlowGraphEditorSettings* Settings = GetMutableDefault(); + check(Settings); + Settings->SaveConfig(); +} + #undef LOCTEXT_NAMESPACE diff --git a/Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp b/Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp index 24b7e73b..a3e4f2bb 100644 --- a/Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp +++ b/Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp @@ -464,6 +464,9 @@ void SFlowGraphEditor::DeleteSelectedNodes() { if (const UFlowGraphNode* FlowGraphNode = Cast(Node)) { + UFlowDebuggerSubsystem::ClearNodeTraits(FlowGraphNode); + UFlowDebuggerSubsystem::ClearPinTraits(FlowGraphNode); + if (FlowGraphNode->GetFlowNode()) { const FGuid NodeGuid = FlowGraphNode->GetFlowNode()->GetGuid(); @@ -851,7 +854,11 @@ void SFlowGraphEditor::OnAddBreakpoint() const { for (UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - SelectedNode->NodeBreakpoint.AllowTrait(); + const FFlowDebugTrait* Trait = UFlowDebuggerSubsystem::FindTrait(SelectedNode, EFlowTraitType::Breakpoint); + if (Trait == nullptr) + { + UFlowDebuggerSubsystem::CreateTrait(SelectedNode, EFlowTraitType::Breakpoint, true); + } } } @@ -859,9 +866,10 @@ void SFlowGraphEditor::OnAddPinBreakpoint() { if (UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) + const FFlowDebugTrait* Trait = UFlowDebuggerSubsystem::FindTrait(Pin, EFlowTraitType::Breakpoint); + if (Trait == nullptr) { - GraphNode->PinBreakpoints.Add(Pin, FFlowPinTrait(true)); + UFlowDebuggerSubsystem::CreateTrait(Pin, EFlowTraitType::Breakpoint, true); } } } @@ -870,7 +878,7 @@ bool SFlowGraphEditor::CanAddBreakpoint() const { for (const UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - return !SelectedNode->NodeBreakpoint.IsAllowed(); + return UFlowDebuggerSubsystem::FindTrait(SelectedNode, EFlowTraitType::Breakpoint) == nullptr; } return false; @@ -878,12 +886,9 @@ bool SFlowGraphEditor::CanAddBreakpoint() const bool SFlowGraphEditor::CanAddPinBreakpoint() { - if (UEdGraphPin* Pin = GetGraphPinForMenu()) + if (const UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) - { - return !GraphNode->PinBreakpoints.Contains(Pin) || !GraphNode->PinBreakpoints[Pin].IsAllowed(); - } + return UFlowDebuggerSubsystem::FindTrait(Pin, EFlowTraitType::Breakpoint) == nullptr; } return false; @@ -891,9 +896,9 @@ bool SFlowGraphEditor::CanAddPinBreakpoint() void SFlowGraphEditor::OnRemoveBreakpoint() const { - for (UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) + for (const UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - SelectedNode->NodeBreakpoint.DisallowTrait(); + UFlowDebuggerSubsystem::RemoveTrait(SelectedNode, EFlowTraitType::Breakpoint); } } @@ -901,10 +906,7 @@ void SFlowGraphEditor::OnRemovePinBreakpoint() { if (UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) - { - GraphNode->PinBreakpoints.Remove(Pin); - } + UFlowDebuggerSubsystem::RemoveTrait(Pin, EFlowTraitType::Breakpoint); } } @@ -912,7 +914,7 @@ bool SFlowGraphEditor::CanRemoveBreakpoint() const { for (const UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - return SelectedNode->NodeBreakpoint.IsAllowed(); + return UFlowDebuggerSubsystem::FindTrait(SelectedNode, EFlowTraitType::Breakpoint) != nullptr; } return false; @@ -920,12 +922,9 @@ bool SFlowGraphEditor::CanRemoveBreakpoint() const bool SFlowGraphEditor::CanRemovePinBreakpoint() { - if (UEdGraphPin* Pin = GetGraphPinForMenu()) + if (const UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (const UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) - { - return GraphNode->PinBreakpoints.Contains(Pin); - } + return UFlowDebuggerSubsystem::FindTrait(Pin, EFlowTraitType::Breakpoint) != nullptr; } return false; @@ -933,9 +932,9 @@ bool SFlowGraphEditor::CanRemovePinBreakpoint() void SFlowGraphEditor::OnEnableBreakpoint() const { - for (UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) + for (const UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - SelectedNode->NodeBreakpoint.EnableTrait(); + UFlowDebuggerSubsystem::SetTraitEnabled(SelectedNode, EFlowTraitType::Breakpoint, true); } } @@ -943,26 +942,20 @@ void SFlowGraphEditor::OnEnablePinBreakpoint() { if (UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) - { - GraphNode->PinBreakpoints[Pin].EnableTrait(); - } + UFlowDebuggerSubsystem::SetTraitEnabled(Pin, EFlowTraitType::Breakpoint, true); } } bool SFlowGraphEditor::CanEnableBreakpoint() { - if (UEdGraphPin* Pin = GetGraphPinForMenu()) + for (const UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - if (const UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) + if (const FFlowDebugTrait* Trait = UFlowDebuggerSubsystem::FindTrait(SelectedNode, EFlowTraitType::Breakpoint)) { - return GraphNode->PinBreakpoints.Contains(Pin); + return Trait->IsEnabled() == false; } - } - - for (const UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) - { - return SelectedNode->NodeBreakpoint.CanEnable(); + + return false; } return false; @@ -972,10 +965,12 @@ bool SFlowGraphEditor::CanEnablePinBreakpoint() { if (UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) + if (const FFlowDebugTrait* Trait = UFlowDebuggerSubsystem::FindTrait(Pin, EFlowTraitType::Breakpoint)) { - return GraphNode->PinBreakpoints.Contains(Pin) && GraphNode->PinBreakpoints[Pin].CanEnable(); + return Trait->IsEnabled() == false; } + + return false; } return false; @@ -985,7 +980,7 @@ void SFlowGraphEditor::OnDisableBreakpoint() const { for (UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - SelectedNode->NodeBreakpoint.DisableTrait(); + UFlowDebuggerSubsystem::SetTraitEnabled(SelectedNode, EFlowTraitType::Breakpoint, false); } } @@ -993,10 +988,11 @@ void SFlowGraphEditor::OnDisablePinBreakpoint() { if (UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) - { - GraphNode->PinBreakpoints[Pin].DisableTrait(); - } + UFlowDebuggerSubsystem::SetTraitEnabled(Pin, EFlowTraitType::Breakpoint, false); + // if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) + // { + // GraphNode->PinBreakpoints[Pin].DisableTrait(); + // } } } @@ -1004,7 +1000,12 @@ bool SFlowGraphEditor::CanDisableBreakpoint() const { for (const UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - return SelectedNode->NodeBreakpoint.IsEnabled(); + if (const FFlowDebugTrait* Trait = UFlowDebuggerSubsystem::FindTrait(SelectedNode, EFlowTraitType::Breakpoint)) + { + return Trait->IsEnabled(); + } + + return false; } return false; @@ -1014,10 +1015,12 @@ bool SFlowGraphEditor::CanDisablePinBreakpoint() { if (UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) + if (const FFlowDebugTrait* Trait = UFlowDebuggerSubsystem::FindTrait(Pin, EFlowTraitType::Breakpoint)) { - return GraphNode->PinBreakpoints.Contains(Pin) && GraphNode->PinBreakpoints[Pin].IsEnabled(); + return Trait->IsEnabled(); } + + return false; } return false; @@ -1025,9 +1028,9 @@ bool SFlowGraphEditor::CanDisablePinBreakpoint() void SFlowGraphEditor::OnToggleBreakpoint() const { - for (UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) + for (const UFlowGraphNode* SelectedNode : GetSelectedFlowNodes()) { - SelectedNode->NodeBreakpoint.ToggleTrait(); + UFlowDebuggerSubsystem::ToggleTrait(SelectedNode, EFlowTraitType::Breakpoint); } } @@ -1035,11 +1038,7 @@ void SFlowGraphEditor::OnTogglePinBreakpoint() { if (UEdGraphPin* Pin = GetGraphPinForMenu()) { - if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) - { - GraphNode->PinBreakpoints.Add(Pin, FFlowPinTrait()); - GraphNode->PinBreakpoints[Pin].ToggleTrait(); - } + UFlowDebuggerSubsystem::ToggleTrait(Pin, EFlowTraitType::Breakpoint); } } diff --git a/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp b/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp index 802c0ba3..5fc70700 100644 --- a/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp +++ b/Source/FlowEditor/Private/Graph/Nodes/FlowGraphNode.cpp @@ -262,6 +262,9 @@ void UFlowGraphNode::ReconstructNode() DestroyPin(OldPin); } + // remove expired data from deleted nodes and pins + UFlowDebuggerSubsystem::CleanupTraits(this); + bNeedsFullReconstruction = false; } @@ -359,16 +362,6 @@ void UFlowGraphNode::ReconstructSinglePin(UEdGraphPin* NewPin, UEdGraphPin* OldP // Copy over modified persistent data NewPin->MovePersistentDataFromOldPin(*OldPin); - - // Update the in breakpoints as the old pin will be going the way of the dodo - for (TPair& PinBreakpoint : PinBreakpoints) - { - if (PinBreakpoint.Key.Get() == OldPin) - { - PinBreakpoint.Key = NewPin; - break; - } - } } void UFlowGraphNode::GetNodeContextMenuActions(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context) const @@ -739,7 +732,7 @@ void UFlowGraphNode::RemoveOrphanedPin(UEdGraphPin* Pin) const FScopedTransaction Transaction(LOCTEXT("RemoveOrphanedPin", "Remove Orphaned Pin")); Modify(); - PinBreakpoints.Remove(Pin); + UFlowDebuggerSubsystem::ClearPinTraits(Pin); Pin->MarkAsGarbage(); Pins.Remove(Pin); @@ -825,7 +818,7 @@ void UFlowGraphNode::RemoveInstancePin(UEdGraphPin* Pin) const FScopedTransaction Transaction(LOCTEXT("RemoveInstancePin", "Remove Instance Pin")); Modify(); - PinBreakpoints.Remove(Pin); + UFlowDebuggerSubsystem::ClearPinTraits(Pin); if (Pin->Direction == EGPD_Input) { @@ -927,10 +920,13 @@ void UFlowGraphNode::GetPinHoverText(const UEdGraphPin& Pin, FString& HoverTextO void UFlowGraphNode::OnInputTriggered(const int32 Index) { - if (InputPins.IsValidIndex(Index) && PinBreakpoints.Contains(InputPins[Index])) + if (InputPins.IsValidIndex(Index)) { - PinBreakpoints[InputPins[Index]].MarkAsHit(); - TryPausingSession(true); + const TArray HitTraitTypes = UFlowDebuggerSubsystem::SetAllTraitsHit(InputPins[Index], true); + if (HitTraitTypes.Contains(EFlowTraitType::Breakpoint)) + { + TryPausingSession(true); + } } TryPausingSession(false); @@ -938,10 +934,13 @@ void UFlowGraphNode::OnInputTriggered(const int32 Index) void UFlowGraphNode::OnOutputTriggered(const int32 Index) { - if (OutputPins.IsValidIndex(Index) && PinBreakpoints.Contains(OutputPins[Index])) + if (OutputPins.IsValidIndex(Index)) { - PinBreakpoints[OutputPins[Index]].MarkAsHit(); - TryPausingSession(true); + const TArray HitTraitTypes = UFlowDebuggerSubsystem::SetAllTraitsHit(OutputPins[Index], true); + if (HitTraitTypes.Contains(EFlowTraitType::Breakpoint)) + { + TryPausingSession(true); + } } TryPausingSession(false); @@ -950,9 +949,9 @@ void UFlowGraphNode::OnOutputTriggered(const int32 Index) void UFlowGraphNode::TryPausingSession(bool bPauseSession) { // Node breakpoints waits on any pin triggered - if (NodeBreakpoint.IsEnabled()) + const TArray HitTraitTypes = UFlowDebuggerSubsystem::SetAllTraitsHit(this, true); + if (HitTraitTypes.Contains(EFlowTraitType::Breakpoint)) { - NodeBreakpoint.MarkAsHit(); bPauseSession = true; } @@ -980,10 +979,10 @@ void UFlowGraphNode::ResetBreakpoints() FEditorDelegates::ResumePIE.RemoveAll(this); FEditorDelegates::EndPIE.RemoveAll(this); - NodeBreakpoint.ResetHit(); - for (TPair& PinBreakpoint : PinBreakpoints) + UFlowDebuggerSubsystem::SetTraitHit(this, EFlowTraitType::Breakpoint, false); + for (UEdGraphPin* Pin : Pins) { - PinBreakpoint.Value.ResetHit(); + UFlowDebuggerSubsystem::SetTraitHit(Pin, EFlowTraitType::Breakpoint, false); } } diff --git a/Source/FlowEditor/Private/Graph/Widgets/SFlowGraphNode.cpp b/Source/FlowEditor/Private/Graph/Widgets/SFlowGraphNode.cpp index 0038cc5f..e51a487e 100644 --- a/Source/FlowEditor/Private/Graph/Widgets/SFlowGraphNode.cpp +++ b/Source/FlowEditor/Private/Graph/Widgets/SFlowGraphNode.cpp @@ -21,6 +21,7 @@ #include "SNodePanel.h" #include "Styling/SlateColor.h" #include "TutorialMetaData.h" +#include "Asset/FlowDebuggerSubsystem.h" #include "Widgets/Images/SImage.h" #include "Widgets/Input/SButton.h" #include "Widgets/Layout/SBorder.h" @@ -101,18 +102,18 @@ const FSlateBrush* SFlowGraphNode::GetShadowBrush(bool bSelected) const void SFlowGraphNode::GetOverlayBrushes(bool bSelected, const FVector2D WidgetSize, TArray& Brushes) const { // Node breakpoint - if (FlowGraphNode->NodeBreakpoint.IsAllowed()) + if (const FFlowDebugTrait* Trait = UFlowDebuggerSubsystem::FindTrait(FlowGraphNode, EFlowTraitType::Breakpoint)) { FOverlayBrushInfo NodeBrush; - if (FlowGraphNode->NodeBreakpoint.IsHit()) + if (Trait->IsHit()) { NodeBrush.Brush = FFlowEditorStyle::Get()->GetBrush(TEXT("FlowGraph.BreakpointHit")); NodeBrush.OverlayOffset.X = WidgetSize.X - 12.0f; } else { - NodeBrush.Brush = FFlowEditorStyle::Get()->GetBrush(FlowGraphNode->NodeBreakpoint.IsEnabled() ? TEXT("FlowGraph.BreakpointEnabled") : TEXT("FlowGraph.BreakpointDisabled")); + NodeBrush.Brush = FFlowEditorStyle::Get()->GetBrush(Trait->IsEnabled() ? TEXT("FlowGraph.BreakpointEnabled") : TEXT("FlowGraph.BreakpointDisabled")); NodeBrush.OverlayOffset.X = WidgetSize.X; } @@ -122,41 +123,41 @@ void SFlowGraphNode::GetOverlayBrushes(bool bSelected, const FVector2D WidgetSiz } // Pin breakpoints - for (const TPair& PinBreakpoint : FlowGraphNode->PinBreakpoints) + for (UEdGraphPin* Pin : FlowGraphNode->Pins) { - if (PinBreakpoint.Key.Get()->Direction == EGPD_Input) + if (const FFlowDebugTrait* Breakpoint = UFlowDebuggerSubsystem::FindTrait(Pin, EFlowTraitType::Breakpoint)) { - GetPinBrush(true, WidgetSize.X, FlowGraphNode->InputPins.IndexOfByKey(PinBreakpoint.Key.Get()), PinBreakpoint.Value, Brushes); - } - else - { - GetPinBrush(false, WidgetSize.X, FlowGraphNode->OutputPins.IndexOfByKey(PinBreakpoint.Key.Get()), PinBreakpoint.Value, Brushes); + if (Pin->Direction == EGPD_Input) + { + GetPinBrush(true, WidgetSize.X, FlowGraphNode->InputPins.IndexOfByKey(Pin), Breakpoint, Brushes); + } + else + { + GetPinBrush(false, WidgetSize.X, FlowGraphNode->OutputPins.IndexOfByKey(Pin), Breakpoint, Brushes); + } } } } -void SFlowGraphNode::GetPinBrush(const bool bLeftSide, const float WidgetWidth, const int32 PinIndex, const FFlowPinTrait& Breakpoint, TArray& Brushes) const +void SFlowGraphNode::GetPinBrush(const bool bLeftSide, const float WidgetWidth, const int32 PinIndex, const FFlowDebugTrait* Breakpoint, TArray& Brushes) const { - if (Breakpoint.IsAllowed()) - { - FOverlayBrushInfo PinBrush; - - if (Breakpoint.IsHit()) - { - PinBrush.Brush = FFlowEditorStyle::Get()->GetBrush(TEXT("FlowGraph.PinBreakpointHit")); - PinBrush.OverlayOffset.X = bLeftSide ? 0.0f : (WidgetWidth - 36.0f); - PinBrush.OverlayOffset.Y = 12.0f + PinIndex * 28.0f; - } - else - { - PinBrush.Brush = FFlowEditorStyle::Get()->GetBrush(Breakpoint.IsEnabled() ? TEXT("FlowGraph.BreakpointEnabled") : TEXT("FlowGraph.BreakpointDisabled")); - PinBrush.OverlayOffset.X = bLeftSide ? -24.0f : WidgetWidth; - PinBrush.OverlayOffset.Y = 16.0f + PinIndex * 28.0f; - } + FOverlayBrushInfo PinBrush; - PinBrush.AnimationEnvelope = FVector2D(0.f, 10.f); - Brushes.Add(PinBrush); + if (Breakpoint->IsHit()) + { + PinBrush.Brush = FFlowEditorStyle::Get()->GetBrush(TEXT("FlowGraph.PinBreakpointHit")); + PinBrush.OverlayOffset.X = bLeftSide ? 0.0f : (WidgetWidth - 36.0f); + PinBrush.OverlayOffset.Y = 12.0f + PinIndex * 28.0f; } + else + { + PinBrush.Brush = FFlowEditorStyle::Get()->GetBrush(Breakpoint->IsEnabled() ? TEXT("FlowGraph.BreakpointEnabled") : TEXT("FlowGraph.BreakpointDisabled")); + PinBrush.OverlayOffset.X = bLeftSide ? -24.0f : WidgetWidth; + PinBrush.OverlayOffset.Y = 16.0f + PinIndex * 28.0f; + } + + PinBrush.AnimationEnvelope = FVector2D(0.f, 10.f); + Brushes.Add(PinBrush); } BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION diff --git a/Source/FlowEditor/Public/Asset/FlowDebuggerSubsystem.h b/Source/FlowEditor/Public/Asset/FlowDebuggerSubsystem.h index 0200ba01..9521af08 100644 --- a/Source/FlowEditor/Public/Asset/FlowDebuggerSubsystem.h +++ b/Source/FlowEditor/Public/Asset/FlowDebuggerSubsystem.h @@ -6,9 +6,77 @@ #include "Logging/TokenizedMessage.h" #include "FlowDebuggerSubsystem.generated.h" +class UFlowGraphNode; +class UEdGraphPin; +struct FFlowTraitSettings; class UFlowAsset; class FFlowMessageLog; +UENUM() +enum class EFlowTraitType +{ + Breakpoint, // default trait type + + // ^ Add new trait types above here ^ + Max +}; + +ENUM_RANGE_BY_COUNT(EFlowTraitType, EFlowTraitType::Max) + +// It can represent any trait added on the specific node instance, i.e. breakpoint +USTRUCT() +struct FLOWEDITOR_API FFlowDebugTrait +{ + GENERATED_USTRUCT_BODY() + +protected: + /** Pin that the trait is placed on. Zero filled if this trait is for a node, not a pin */ + UPROPERTY() + FGuid PinId; + + UPROPERTY() + EFlowTraitType Type; + + UPROPERTY() + uint8 bEnabled : 1; + uint8 bHit : 1; + +public: + FFlowDebugTrait() + : Type(EFlowTraitType::Breakpoint) // default trait type + , bEnabled(false) + , bHit(false) + { + }; + + explicit FFlowDebugTrait(EFlowTraitType InType, const bool bInitialState) + : Type(InType) + , bEnabled(bInitialState) + , bHit(false) + { + }; + + explicit FFlowDebugTrait(EFlowTraitType InType, FGuid InPinId, const bool bInitialState) + : PinId(InPinId) + , Type(InType) + , bEnabled(bInitialState) + , bHit(false) + { + }; + + bool IsEnabled() const; + bool IsHit() const; + + bool operator==(const FFlowDebugTrait& Other) const + { + return Type == Other.Type + && PinId == Other.PinId; + } + + friend class UFlowDebuggerSubsystem; +}; + + /** ** Persistent subsystem supporting Flow Graph debugging */ @@ -34,4 +102,85 @@ class FLOWEDITOR_API UFlowDebuggerSubsystem : public UEditorSubsystem public: static void PausePlaySession(); static bool IsPlaySessionPaused(); + + // Flow Traits Functions + + /** Adds trait with provided Type to OwnerNode. Node cannot accept traits of the same type */ + static void CreateTrait(const UFlowGraphNode* OwnerNode, EFlowTraitType Type, bool bEnabled); + /** Adds trait with provided Type to OwnerPin. Pin cannot accept traits of the same type */ + static void CreateTrait(const UEdGraphPin* OwnerPin, EFlowTraitType Type, bool bEnabled); + + /** Removes trait with provided Type from OwnerNode */ + static void RemoveTrait(const UFlowGraphNode* OwnerNode, EFlowTraitType Type); + /** Removes trait with provided Type from OwnerPin */ + static void RemoveTrait(const UEdGraphPin* OwnerPin, EFlowTraitType Type); + + /** Removes any OwnerNode's trait that matches the provided Predicate */ + static void RemoveNodeTraitByPredicate(const UFlowGraphNode* OwnerNode, const TFunctionRef Predicate); + /** Removes any pin trait of provided OwnerNode that matches the provided Predicate */ + static void RemovePinTraitByPredicate(const UFlowGraphNode* OwnerNode, const TFunctionRef Predicate); + /** Removes any OwnerPin's trait that matches the provided Predicate */ + static void RemovePinTraitByPredicate(const UEdGraphPin* OwnerPin, const TFunctionRef Predicate); + + /** Clears all node traits for provided OwnerNode */ + static void ClearNodeTraits(const UFlowGraphNode* OwnerNode); + /** Clears all pin traits for provided OwnerNode */ + static void ClearPinTraits(const UFlowGraphNode* OwnerNode); + /** Clears all traits for provided OwnerPin */ + static void ClearPinTraits(const UEdGraphPin* OwnerPin); + /** Removes stale pin traits for provided OwnerNode. Pin list can be changed after node reconstructing and traits for removed pins can stay in PerNodeSettings. + * There is no need to clean node's traits here, cause all node events can be processed right away and there will be no stale nodes in PerNodeSettings */ + static void CleanupTraits(const UFlowGraphNode* OwnerNode); + + /** Finds OwnerNode's trait with provided Type + * returns null if there are no OwnerNode's trait with provided Type */ + static FFlowDebugTrait* FindTrait(const UFlowGraphNode* OwnerNode, EFlowTraitType Type); + /** Finds OwnerPin's trait with Type + * returns null if there are no OwnerPin's trait with provided Type */ + static FFlowDebugTrait* FindTrait(const UEdGraphPin* OwnerPin, EFlowTraitType Type); + + /** Sets or clears the enabled flag for the OwnerNode's trait with provided Type */ + static void SetTraitEnabled(const UFlowGraphNode* OwnerNode, EFlowTraitType Type, bool bIsEnabled); + /** Sets or clears the enabled flag for the OwnerPin's trait with provided Type */ + static void SetTraitEnabled(const UEdGraphPin* OwnerPin, EFlowTraitType Type, bool bIsEnabled); + + /** Returns the enabled flag for the OwnerNode's trait with provided Type */ + static bool IsTraitEnabled(const UFlowGraphNode* OwnerNode, EFlowTraitType Type); + /** Returns the enabled flag for the OwnerPin's trait with provided Type */ + static bool IsTraitEnabled(const UEdGraphPin* OwnerPin, EFlowTraitType Type); + + /** Creates or removes OwnerNode's trait with provided Type */ + static void ToggleTrait(const UFlowGraphNode* OwnerNode, EFlowTraitType Type); + /** Creates or removes OwnerPin's trait with provided Type */ + static void ToggleTrait(const UEdGraphPin* OwnerPin, EFlowTraitType Type); + + /** Sets the hit flag for the all OwnerNode's traits */ + static TArray SetAllTraitsHit(const UFlowGraphNode* OwnerNode, bool bHit); + /** Sets the hit flag for the all OwnerPin's traits */ + static TArray SetAllTraitsHit(const UEdGraphPin* OwnerPin, bool bHit); + + /** Sets the hit flag for the OwnerNode's trait with provided Type */ + static bool SetTraitHit(const UFlowGraphNode* OwnerNode, EFlowTraitType Type, bool bHit); + /** Sets the hit flag for the OwnerPin's trait with provided Type */ + static bool SetTraitHit(const UEdGraphPin* OwnerPin, EFlowTraitType Type, bool bHit); + + /** Returns the hit flag for the OwnerNode's trait with provided Type */ + static bool IsTraitHit(const UFlowGraphNode* OwnerNode, EFlowTraitType Type); + /** Returns the hit flag for the OwnerPin's trait with provided Type */ + static bool IsTraitHit(const UEdGraphPin* OwnerPin, EFlowTraitType Type); + + /** Retrieves the user settings associated with a FlowGraphNode. + * returns null if the FlowGraphNode has default settings (no nodes and pins traits) */ + static FFlowTraitSettings* GetPerNodeSettings(const UFlowGraphNode* OwnerNode); + + /** Retrieves the Array of node's traits associated with a FlowGraphNode. + * returns null if there are no node's traits associated with this FlowGraphNode */ + static TArray* GetNodeTraits(const UFlowGraphNode* OwnerNode); + + /** Retrieves the Array of pins' traits associated with a FlowGraphNode. + * returns null if there are no pins' traits associated with this FlowGraphNode */ + static TArray* GetPinTraits(const UFlowGraphNode* OwnerNode); + + /** Saves any modifications made to traits */ + static void SaveFlowGraphEditorSettings(); }; diff --git a/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h b/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h index 6da9fc25..39e51790 100644 --- a/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h +++ b/Source/FlowEditor/Public/Graph/FlowGraphEditorSettings.h @@ -2,6 +2,7 @@ #pragma once +#include "Asset/FlowDebuggerSubsystem.h" #include "Engine/DeveloperSettings.h" #include "FlowGraphEditorSettings.generated.h" @@ -13,6 +14,24 @@ enum class EFlowNodeDoubleClickTarget : uint8 PrimaryAssetOrNodeDefinition UMETA(Tooltip = "First try opening the asset then if there is none, open the node class") }; +USTRUCT() +struct FLOWEDITOR_API FFlowTraitSettings +{ + GENERATED_BODY() + + UPROPERTY() + TArray NodeTraits; + + UPROPERTY() + TArray PinTraits; + + bool operator==(const FFlowTraitSettings& Other) const + { + return NodeTraits == Other.NodeTraits + && PinTraits == Other.PinTraits; + } +}; + /** * */ @@ -60,6 +79,10 @@ class FLOWEDITOR_API UFlowGraphEditorSettings : public UDeveloperSettings UPROPERTY(EditAnywhere, config, Category = "Wires") bool bHighlightOutputWiresOfSelectedNodes; + /** Maps Blueprint path to settings such as breakpoints */ + UPROPERTY(config) + TMap PerNodeTraits; + public: virtual FName GetCategoryName() const override { return FName("Flow Graph"); } virtual FText GetSectionText() const override { return INVTEXT("User Settings"); } diff --git a/Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h b/Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h index b80321ad..e8502d42 100644 --- a/Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h +++ b/Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h @@ -69,8 +69,8 @@ class FLOWEDITOR_API UFlowGraphNode : public UEdGraphNode // Graph node public: - UPROPERTY() - FFlowPinTrait NodeBreakpoint; + // UPROPERTY() + // FFlowPinTrait NodeBreakpoint; // UEdGraphNode virtual bool CanCreateUnderSpecifiedSchema(const UEdGraphSchema* Schema) const override; @@ -142,8 +142,8 @@ class FLOWEDITOR_API UFlowGraphNode : public UEdGraphNode TArray InputPins; TArray OutputPins; - UPROPERTY() - TMap PinBreakpoints; + // UPROPERTY() + // TMap PinBreakpoints; void CreateInputPin(const FFlowPin& FlowPin, const int32 Index = INDEX_NONE); void CreateOutputPin(const FFlowPin& FlowPin, const int32 Index = INDEX_NONE); diff --git a/Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h b/Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h index a97eade0..a6ae003e 100644 --- a/Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h +++ b/Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h @@ -4,7 +4,6 @@ #include "SGraphNode.h" #include "KismetPins/SGraphPinExec.h" - #include "Graph/Nodes/FlowGraphNode.h" class FLOWEDITOR_API SFlowGraphPinExec : public SGraphPinExec @@ -33,7 +32,7 @@ class FLOWEDITOR_API SFlowGraphNode : public SGraphNode virtual void GetOverlayBrushes(bool bSelected, const FVector2D WidgetSize, TArray& Brushes) const override; // -- - virtual void GetPinBrush(const bool bLeftSide, const float WidgetWidth, const int32 PinIndex, const FFlowPinTrait& Breakpoint, TArray& Brushes) const; + virtual void GetPinBrush(const bool bLeftSide, const float WidgetWidth, const int32 PinIndex, const struct FFlowDebugTrait* Breakpoint, TArray& Brushes) const; // SGraphNode virtual void UpdateGraphNode() override; From 2247d631559276d1e430dc769a9c844391917f93 Mon Sep 17 00:00:00 2001 From: MaksymKapelianovych Date: Tue, 14 May 2024 16:19:31 +0300 Subject: [PATCH 3/5] Remove comment --- Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp b/Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp index a3e4f2bb..6aa60220 100644 --- a/Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp +++ b/Source/FlowEditor/Private/Graph/FlowGraphEditor.cpp @@ -989,10 +989,6 @@ void SFlowGraphEditor::OnDisablePinBreakpoint() if (UEdGraphPin* Pin = GetGraphPinForMenu()) { UFlowDebuggerSubsystem::SetTraitEnabled(Pin, EFlowTraitType::Breakpoint, false); - // if (UFlowGraphNode* GraphNode = Cast(Pin->GetOwningNode())) - // { - // GraphNode->PinBreakpoints[Pin].DisableTrait(); - // } } } From 94ff4d9578bbe3c04a4b720eb1dba94620b472ab Mon Sep 17 00:00:00 2001 From: MaksymKapelianovych Date: Tue, 14 May 2024 16:46:14 +0300 Subject: [PATCH 4/5] Remove comments --- Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h b/Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h index e8502d42..a421cc50 100644 --- a/Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h +++ b/Source/FlowEditor/Public/Graph/Nodes/FlowGraphNode.h @@ -69,9 +69,6 @@ class FLOWEDITOR_API UFlowGraphNode : public UEdGraphNode // Graph node public: - // UPROPERTY() - // FFlowPinTrait NodeBreakpoint; - // UEdGraphNode virtual bool CanCreateUnderSpecifiedSchema(const UEdGraphSchema* Schema) const override; virtual void AutowireNewNode(UEdGraphPin* FromPin) override; @@ -142,9 +139,6 @@ class FLOWEDITOR_API UFlowGraphNode : public UEdGraphNode TArray InputPins; TArray OutputPins; - // UPROPERTY() - // TMap PinBreakpoints; - void CreateInputPin(const FFlowPin& FlowPin, const int32 Index = INDEX_NONE); void CreateOutputPin(const FFlowPin& FlowPin, const int32 Index = INDEX_NONE); From 565a11d5713d26aad44d92faf75946cab034ec89 Mon Sep 17 00:00:00 2001 From: MaksymKapelianovych Date: Sun, 16 Jun 2024 20:30:11 +0300 Subject: [PATCH 5/5] Fix trait type after merge --- Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h b/Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h index acde82e6..028f5911 100644 --- a/Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h +++ b/Source/FlowEditor/Public/Graph/Widgets/SFlowGraphNode.h @@ -34,7 +34,7 @@ class FLOWEDITOR_API SFlowGraphNode : public SGraphNode // -- // SGraphNode - virtual void GetPinBrush(const bool bLeftSide, const float WidgetWidth, const int32 PinIndex, const struct FFlowPinTrait& Breakpoint, TArray& Brushes) const; + virtual void GetPinBrush(const bool bLeftSide, const float WidgetWidth, const int32 PinIndex, const struct FFlowDebugTrait* Breakpoint, TArray& Brushes) const; virtual FText GetTitle() const; virtual FText GetDescription() const;