Skip to content

Commit 1a4a2d9

Browse files
committed
Decoupled triggering breakpoints from the Flow Editor module
* UFlowGraphNode no longer operate on breakpoints. * UFlowDebuggerSubsystem binds directly to runtime OnPinTriggered delegate. * Pin breakpoint is now identified as NodeGuid and PinName instead of UEdGraphPin. This way it's possible to bind to OnPinTriggered delegate outside of editor! Events shall be receive in Standalone game, non-shipping game builds. * Wrapped UEdGraphNode pointer in runtime Flow Node class with WITH_EDITORONLY_DATA as this isn't even loaded in Standalone game.
1 parent 3f3c665 commit 1a4a2d9

File tree

20 files changed

+401
-455
lines changed

20 files changed

+401
-455
lines changed

Source/Flow/Private/FlowAsset.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ FString UFlowAsset::ValidationError_NullNodeInstance = TEXT("Node with GUID {0}
3131
UFlowAsset::UFlowAsset(const FObjectInitializer& ObjectInitializer)
3232
: Super(ObjectInitializer)
3333
, bWorldBound(true)
34-
#if WITH_EDITOR
34+
#if WITH_EDITORONLY_DATA
3535
, FlowGraph(nullptr)
3636
#endif
3737
, AllowedNodeClasses({UFlowNodeBase::StaticClass()})
@@ -293,14 +293,6 @@ bool UFlowAsset::CanFlowAssetReferenceFlowNode(const UClass& FlowNodeClass, FTex
293293
return true;
294294
}
295295

296-
TSharedPtr<IFlowGraphInterface> UFlowAsset::FlowGraphInterface = nullptr;
297-
298-
void UFlowAsset::SetFlowGraphInterface(TSharedPtr<IFlowGraphInterface> InFlowAssetEditor)
299-
{
300-
check(!FlowGraphInterface.IsValid());
301-
FlowGraphInterface = InFlowAssetEditor;
302-
}
303-
304296
UFlowNode* UFlowAsset::CreateNode(const UClass* NodeClass, UEdGraphNode* GraphNode)
305297
{
306298
UFlowNode* NewNode = NewObject<UFlowNode>(this, NodeClass, NAME_None, RF_Transactional);
@@ -1473,9 +1465,9 @@ bool UFlowAsset::IsBoundToWorld_Implementation()
14731465
void UFlowAsset::LogError(const FString& MessageToLog, const UFlowNodeBase* Node) const
14741466
{
14751467
// this is runtime log which is should be only called on runtime instances of asset
1476-
if (TemplateAsset == nullptr)
1468+
if (TemplateAsset)
14771469
{
1478-
UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on null template asset %s"), *MessageToLog);
1470+
UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on asset instance %s"), *MessageToLog);
14791471
}
14801472

14811473
if (RuntimeLog.Get())
@@ -1488,9 +1480,9 @@ void UFlowAsset::LogError(const FString& MessageToLog, const UFlowNodeBase* Node
14881480
void UFlowAsset::LogWarning(const FString& MessageToLog, const UFlowNodeBase* Node) const
14891481
{
14901482
// this is runtime log which is should be only called on runtime instances of asset
1491-
if (TemplateAsset == nullptr)
1483+
if (TemplateAsset)
14921484
{
1493-
UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on null template asset %s"), *MessageToLog);
1485+
UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on asset instance %s"), *MessageToLog);
14941486
}
14951487

14961488
if (RuntimeLog.Get())
@@ -1503,9 +1495,9 @@ void UFlowAsset::LogWarning(const FString& MessageToLog, const UFlowNodeBase* No
15031495
void UFlowAsset::LogNote(const FString& MessageToLog, const UFlowNodeBase* Node) const
15041496
{
15051497
// this is runtime log which is should be only called on runtime instances of asset
1506-
if (TemplateAsset == nullptr)
1498+
if (TemplateAsset)
15071499
{
1508-
UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on null template asset %s"), *MessageToLog);
1500+
UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on asset instance %s"), *MessageToLog);
15091501
}
15101502

15111503
if (RuntimeLog.Get())

Source/Flow/Private/FlowSubsystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
#include UE_INLINE_GENERATED_CPP_BY_NAME(FlowSubsystem)
1919

20-
#if WITH_EDITOR
20+
#if !UE_BUILD_SHIPPING
2121
FNativeFlowAssetEvent UFlowSubsystem::OnInstancedTemplateAdded;
2222
FNativeFlowAssetEvent UFlowSubsystem::OnInstancedTemplateRemoved;
2323
#endif

Source/Flow/Private/Nodes/FlowNode.cpp

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,15 @@ void UFlowNode::PostLoad()
7676

7777
bool UFlowNode::IsSupportedInputPinName(const FName& PinName) const
7878
{
79+
const FFlowPin* InputPin = FindFlowPinByName(PinName, InputPins);
80+
7981
if (AddOns.IsEmpty())
8082
{
81-
checkf(FindFlowPinByName(PinName, InputPins), TEXT("Only AddOns should introduce unknown Pins to a FlowNode, so if we have no AddOns, we should have no unknown pins"));
82-
83+
checkf(InputPin, TEXT("Only AddOns should introduce unknown Pins to a FlowNode, so if we have no AddOns, we should have no unknown pins"));
8384
return true;
8485
}
8586

86-
if (const FFlowPin* FoundInputFlowPin = FindFlowPinByName(PinName, InputPins))
87-
{
88-
return true;
89-
}
90-
else
91-
{
92-
return false;
93-
}
87+
return (InputPin != nullptr);
9488
}
9589

9690
void UFlowNode::AddInputPins(const TArray<FFlowPin>& Pins)
@@ -813,23 +807,19 @@ void UFlowNode::TriggerInput(const FName& PinName, const EFlowPinActivationType
813807
TArray<FPinRecord>& Records = InputRecords.FindOrAdd(PinName);
814808
Records.Add(FPinRecord(FApp::GetCurrentTime(), ActivationType));
815809

816-
LogVerbose(FString::Printf(TEXT("Triggering input %s."), *PinName.ToString()));
817-
#endif // UE_BUILD_SHIPPING
818-
819-
#if WITH_EDITOR
820-
if (GEditor && UFlowAsset::GetFlowGraphInterface().IsValid())
810+
if (const UFlowAsset* FlowAssetTemplate = GetFlowAsset()->GetTemplateAsset())
821811
{
822-
UFlowAsset::GetFlowGraphInterface()->OnInputTriggered(GraphNode, InputPins.IndexOfByKey(PinName));
812+
(void)FlowAssetTemplate->OnPinTriggered.ExecuteIfBound(NodeGuid, PinName);
823813
}
824-
#endif // WITH_EDITOR
814+
#endif
825815
}
816+
#if !UE_BUILD_SHIPPING
826817
else
827818
{
828-
#if !UE_BUILD_SHIPPING
829819
LogError(FString::Printf(TEXT("Input Pin name %s invalid"), *PinName.ToString()));
830-
#endif // UE_BUILD_SHIPPING
831820
return;
832821
}
822+
#endif
833823

834824
switch (SignalMode)
835825
{
@@ -883,24 +873,15 @@ void UFlowNode::TriggerOutput(const FName PinName, const bool bFinish /*= false*
883873
TArray<FPinRecord>& Records = OutputRecords.FindOrAdd(PinName);
884874
Records.Add(FPinRecord(FApp::GetCurrentTime(), ActivationType));
885875

886-
LogVerbose(FString::Printf(TEXT("\n Triggering output: %s. bFinish: %s "), *PinName.ToString(), bFinish ? TEXT("true") : TEXT("false")));
887-
888-
#if WITH_EDITOR
889-
if (GEditor && UFlowAsset::GetFlowGraphInterface().IsValid())
876+
if (const UFlowAsset* FlowAssetTemplate = GetFlowAsset()->GetTemplateAsset())
890877
{
891-
UFlowAsset::GetFlowGraphInterface()->OnOutputTriggered(GraphNode, OutputPins.IndexOfByKey(PinName));
878+
FlowAssetTemplate->OnPinTriggered.ExecuteIfBound(NodeGuid, PinName);
892879
}
893-
#endif
894880
}
895881
else
896882
{
897883
LogError(FString::Printf(TEXT("Output Pin name %s invalid"), *PinName.ToString()));
898884
}
899-
#endif // UE_BUILD_SHIPPING
900-
901-
#if WITH_EDITOR
902-
LogVerbose(FString::Printf(TEXT("\n Description: %s"), *GetNodeDescription()));
903-
LogVerbose(FString::Printf(TEXT("\n Status: %s"), *GetStatusStringForNodeAndAddOns()));
904885
#endif
905886

906887
// call the next node
@@ -924,7 +905,7 @@ void UFlowNode::Deactivate()
924905
// there is nothing to deactivate, node was never active
925906
return;
926907
}
927-
908+
928909
if (GetFlowAsset()->FinishPolicy == EFlowFinishPolicy::Abort)
929910
{
930911
ActivationState = EFlowNodeState::Aborted;
@@ -1077,7 +1058,7 @@ FString UFlowNode::GetStatusStringForNodeAndAddOns() const
10771058
FString CombinedStatusString = GetStatusString();
10781059

10791060
// Give all of the AddOns a chance to add their status strings as well
1080-
(void) ForEachAddOnConst(
1061+
(void)ForEachAddOnConst(
10811062
[&CombinedStatusString](const UFlowNodeAddOn& AddOn)
10821063
{
10831064
const FString AddOnStatusString = AddOn.GetStatusString();

Source/Flow/Private/Nodes/FlowNodeBase.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ using namespace EFlowForEachAddOnFunctionReturnValue_Classifiers;
3030

3131
UFlowNodeBase::UFlowNodeBase(const FObjectInitializer& ObjectInitializer)
3232
: Super(ObjectInitializer)
33-
, GraphNode(nullptr)
3433
#if WITH_EDITORONLY_DATA
34+
, GraphNode(nullptr)
3535
, bDisplayNodeTitleWithoutPrefix(true)
3636
, bCanDelete(true)
3737
, bCanDuplicate(true)
@@ -575,17 +575,14 @@ EFlowForEachAddOnFunctionReturnValue UFlowNodeBase::ForEachAddOnForClass(const U
575575
return ReturnValue;
576576
}
577577

578+
#if WITH_EDITOR
578579
void UFlowNodeBase::PostLoad()
579580
{
580581
Super::PostLoad();
581582

582-
#if WITH_EDITOR
583583
EnsureNodeDisplayStyle();
584-
#endif
585584
}
586585

587-
#if WITH_EDITOR
588-
589586
void UFlowNodeBase::SetGraphNode(UEdGraphNode* NewGraphNode)
590587
{
591588
GraphNode = NewGraphNode;
@@ -726,7 +723,7 @@ FText UFlowNodeBase::GetGeneratedDisplayName() const
726723

727724
void UFlowNodeBase::EnsureNodeDisplayStyle()
728725
{
729-
// todo: remove in Flow 2.1
726+
// todo: remove in Flow 2.2
730727

731728
// Backward compatibility update to convert NodeStyle to NodeDisplayStyle
732729
FLOW_ASSERT_ENUM_MAX(EFlowNodeStyle, 7);

Source/Flow/Public/FlowAsset.h

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,9 @@ class UEdGraph;
2222
class UEdGraphNode;
2323
class UFlowAsset;
2424

25-
#if WITH_EDITOR
26-
27-
/** Interface for calling the graph editor methods */
28-
class FLOW_API IFlowGraphInterface
29-
{
30-
public:
31-
IFlowGraphInterface() {}
32-
virtual ~IFlowGraphInterface() {}
33-
34-
virtual void OnInputTriggered(UEdGraphNode* GraphNode, const int32 Index) const {}
35-
virtual void OnOutputTriggered(UEdGraphNode* GraphNode, const int32 Index) const {}
36-
};
37-
25+
#if !UE_BUILD_SHIPPING
3826
DECLARE_DELEGATE(FFlowGraphEvent);
39-
27+
DECLARE_DELEGATE_TwoParams(FFlowSignalEvent, const FGuid& /*NodeGuid*/, const FName& /*PinName*/);
4028
#endif
4129

4230
// Working Data struct for the Harvest Data Pins operation
@@ -96,7 +84,7 @@ class FLOW_API UFlowAsset : public UObject
9684
bool bWorldBound;
9785

9886
//////////////////////////////////////////////////////////////////////////
99-
// Graph
87+
// Graph (editor-only)
10088

10189
#if WITH_EDITOR
10290
public:
@@ -108,13 +96,24 @@ class FLOW_API UFlowAsset : public UObject
10896
virtual void PostDuplicate(bool bDuplicateForPIE) override;
10997
virtual void PostLoad() override;
11098
// --
99+
#endif
111100

101+
#if WITH_EDITORONLY_DATA
112102
public:
113103
FSimpleDelegate OnDetailsRefreshRequested;
114104

115105
static FString ValidationError_NodeClassNotAllowed;
116106
static FString ValidationError_NullNodeInstance;
117107

108+
private:
109+
UPROPERTY()
110+
TObjectPtr<UEdGraph> FlowGraph;
111+
#endif
112+
113+
#if WITH_EDITOR
114+
public:
115+
UEdGraph* GetGraph() const { return FlowGraph; }
116+
118117
virtual EDataValidationResult ValidateAsset(FFlowMessageLog& MessageLog);
119118

120119
// Returns whether the node class is allowed in this flow asset
@@ -129,25 +128,6 @@ class FLOW_API UFlowAsset : public UObject
129128
bool IsFlowNodeClassInDeniedClasses(const UClass& FlowNodeClass) const;
130129
#endif
131130

132-
// IFlowGraphInterface
133-
#if WITH_EDITORONLY_DATA
134-
135-
private:
136-
UPROPERTY()
137-
TObjectPtr<UEdGraph> FlowGraph;
138-
139-
static TSharedPtr<IFlowGraphInterface> FlowGraphInterface;
140-
#endif
141-
142-
public:
143-
#if WITH_EDITOR
144-
UEdGraph* GetGraph() const { return FlowGraph; };
145-
146-
static void SetFlowGraphInterface(TSharedPtr<IFlowGraphInterface> InFlowAssetEditor);
147-
static TSharedPtr<IFlowGraphInterface> GetFlowGraphInterface() { return FlowGraphInterface; };
148-
#endif
149-
// --
150-
151131
//////////////////////////////////////////////////////////////////////////
152132
// Nodes
153133

@@ -285,7 +265,7 @@ class FLOW_API UFlowAsset : public UObject
285265

286266
void AddCustomOutput(const FName& EventName);
287267
void RemoveCustomOutput(const FName& EventName);
288-
#endif // WITH_EDITOR
268+
#endif
289269

290270
//////////////////////////////////////////////////////////////////////////
291271
// Instances of the template asset
@@ -406,7 +386,6 @@ class FLOW_API UFlowAsset : public UObject
406386
TWeakObjectPtr<UFlowAsset> GetFlowInstance(UFlowNode_SubGraph* SubGraphNode) const;
407387

408388
protected:
409-
410389
void TriggerCustomInput_FromSubGraph(UFlowNode_SubGraph* Node, const FName& EventName) const;
411390
void TriggerCustomOutput(const FName& EventName);
412391

@@ -415,6 +394,11 @@ class FLOW_API UFlowAsset : public UObject
415394
void FinishNode(UFlowNode* Node);
416395
void ResetNodes();
417396

397+
#if !UE_BUILD_SHIPPING
398+
public:
399+
FFlowSignalEvent OnPinTriggered;
400+
#endif
401+
418402
public:
419403
UFlowSubsystem* GetFlowSubsystem() const;
420404
FName GetDisplayName() const;

Source/Flow/Public/FlowSubsystem.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,15 @@ class FLOW_API UFlowSubsystem : public UGameInstanceSubsystem
4949
UPROPERTY()
5050
TMap<TObjectPtr<UFlowNode_SubGraph>, TObjectPtr<UFlowAsset>> InstancedSubFlows;
5151

52-
#if WITH_EDITOR
52+
#if !UE_BUILD_SHIPPING
5353
public:
5454
/* Called after creating the first instance of given Flow Asset */
5555
static FNativeFlowAssetEvent OnInstancedTemplateAdded;
5656

5757
/* Called just before removing the last instance of given Flow Asset */
5858
static FNativeFlowAssetEvent OnInstancedTemplateRemoved;
5959
#endif
60-
60+
6161
protected:
6262
UPROPERTY()
6363
TObjectPtr<UFlowSaveGame> LoadedSaveGame;

Source/Flow/Public/Nodes/FlowNodeBase.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -261,20 +261,19 @@ class FLOW_API UFlowNodeBase
261261
UFUNCTION(BlueprintCallable, Category = DataPins, DisplayName = "Try Resolve DataPin As Class")
262262
FFlowDataPinResult_Class TryResolveDataPinAsClass(const FName& PinName) const;
263263

264-
// Public only for for TResolveDataPinWorkingData's use
264+
// Public only for TResolveDataPinWorkingData's use
265265
EFlowDataPinResolveResult TryResolveDataPinPrerequisites(const FName& PinName, const UFlowNode*& FlowNode, const FFlowPin*& FlowPin, EFlowPinType PinType) const;
266266

267267
public:
268268

269269
//////////////////////////////////////////////////////////////////////////
270270
// Editor
271-
// (some editor symbols exposed to enabled creation of non-editor tooling)
272-
273-
UPROPERTY()
274-
TObjectPtr<UEdGraphNode> GraphNode;
275271

276272
#if WITH_EDITORONLY_DATA
277273
protected:
274+
UPROPERTY()
275+
TObjectPtr<UEdGraphNode> GraphNode;
276+
278277
UPROPERTY(EditDefaultsOnly, Category = "FlowNode")
279278
uint8 bDisplayNodeTitleWithoutPrefix : 1;
280279

@@ -292,13 +291,12 @@ class FLOW_API UFlowNodeBase
292291
FFlowMessageLog ValidationLog;
293292
#endif // WITH_EDITORONLY_DATA
294293

294+
#if WITH_EDITOR
295295
public:
296-
UEdGraphNode* GetGraphNode() const { return GraphNode; }
297-
298296
virtual void PostLoad() override;
299-
300-
#if WITH_EDITOR
297+
301298
void SetGraphNode(UEdGraphNode* NewGraphNode);
299+
UEdGraphNode* GetGraphNode() const { return GraphNode; }
302300

303301
// Set up UFlowNodeBase when being opened for edit in the editor
304302
virtual void SetupForEditing(UEdGraphNode& EdGraphNode);
@@ -316,7 +314,7 @@ class FLOW_API UFlowNodeBase
316314
// Called by owning FlowNode to add to its Status String.
317315
// (may be multi-line)
318316
virtual FString GetStatusString() const;
319-
#endif
317+
#endif // WITH_EDITOR
320318

321319
protected:
322320
// Information displayed while node is working - displayed over node as NodeInfoPopup
@@ -361,7 +359,7 @@ class FLOW_API UFlowNodeBase
361359

362360
protected:
363361
void EnsureNodeDisplayStyle();
364-
#endif
362+
#endif // WITH_EDITOR
365363

366364
protected:
367365
// Set the editor-only Config Text

0 commit comments

Comments
 (0)