Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Config/DefaultFlow.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
+PropertyRedirects=(OldName="FlowGraphNode.FlowNode",NewName="FlowGraphNode.NodeInstance")
+StructRedirects=(OldName="/Script/Flow.FlowNamedDataPinOutputProperty",NewName="/Script/Flow.FlowNamedDataPinProperty")
+PropertyRedirects=(OldName="FlowNode_DefineProperties.OutputProperties",NewName="NamedProperties")
+FunctionRedirects=(OldName="/Script/Flow.FlowSubsystem.FinishRootFlow",NewName="/Script/Flow.FlowSubsystem.FinishAndDeinitializeRootFlow")
+FunctionRedirects=(OldName="/Script/Flow.FlowSubsystem.FinishAllRootFlows",NewName="/Script/Flow.FlowSubsystem.FinishAndDeinitializeAllRootFlows")
21 changes: 11 additions & 10 deletions Source/Flow/Private/FlowAsset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ void UFlowAsset::ClearInstances()
{
if (ActiveInstances.IsValidIndex(i) && ActiveInstances[i])
{
ActiveInstances[i]->FinishFlow(EFlowFinishPolicy::Keep);
ActiveInstances[i]->FinishFlowAndDeinitializeInstance(EFlowFinishPolicy::Keep);
}
}

Expand Down Expand Up @@ -1023,6 +1023,12 @@ AActor* UFlowAsset::TryFindActorOwner() const
return nullptr;
}

void UFlowAsset::FinishFlowAndDeinitializeInstance(const EFlowFinishPolicy InFinishPolicy)
{
FinishFlow(InFinishPolicy);
DeinitializeInstance();
}

void UFlowAsset::PreStartFlow()
{
ResetNodes();
Expand Down Expand Up @@ -1081,13 +1087,14 @@ void UFlowAsset::FinishNode(UFlowNode* Node)
return;
}

// if this instance is a Root Flow, we need to deregister it from the subsystem first
// if this instance is a Root Flow, we need to deregister it from the subsystem first. This will
// finalize and deinitialize the root flow.
if (Owner.IsValid())
{
const TSet<UFlowAsset*>& RootFlowInstances = GetFlowSubsystem()->GetRootInstancesByOwner(Owner.Get());
if (RootFlowInstances.Contains(this))
{
GetFlowSubsystem()->FinishRootFlow(Owner.Get(), TemplateAsset, EFlowFinishPolicy::Keep);
GetFlowSubsystem()->FinishAndDeinitializeRootFlow(Owner.Get(), TemplateAsset, EFlowFinishPolicy::Keep);

return;
}
Expand All @@ -1108,7 +1115,7 @@ void UFlowAsset::ResetNodes()
RecordedNodes.Empty();
}

void UFlowAsset::FinishFlow(const EFlowFinishPolicy InFinishPolicy, const bool bRemoveInstance /*= true*/)
void UFlowAsset::FinishFlow(const EFlowFinishPolicy InFinishPolicy)
{
FinishPolicy = InFinishPolicy;

Expand All @@ -1120,12 +1127,6 @@ void UFlowAsset::FinishFlow(const EFlowFinishPolicy InFinishPolicy, const bool b
Node->Deactivate();
}
ActiveNodes.Empty();

// provides option to finish game-specific logic prior to removing asset instance
if (bRemoveInstance)
{
DeinitializeInstance();
}
}

UFlowSubsystem* UFlowAsset::GetFlowSubsystem() const
Expand Down
4 changes: 2 additions & 2 deletions Source/Flow/Private/FlowComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void UFlowComponent::UnregisterWithFlowSubsystem()
{
if (UFlowSubsystem* FlowSubsystem = GetFlowSubsystem())
{
FlowSubsystem->FinishAllRootFlows(this, EFlowFinishPolicy::Keep);
FlowSubsystem->FinishAndDeinitializeAllRootFlows(this, EFlowFinishPolicy::Keep);
FlowSubsystem->UnregisterComponent(this);
}
}
Expand Down Expand Up @@ -461,7 +461,7 @@ void UFlowComponent::FinishRootFlow(UFlowAsset* TemplateAsset, const EFlowFinish
{
if (UFlowSubsystem* FlowSubsystem = GetFlowSubsystem())
{
FlowSubsystem->FinishRootFlow(this, TemplateAsset, FinishPolicy);
FlowSubsystem->FinishAndDeinitializeRootFlow(this, TemplateAsset, FinishPolicy);
}
}

Expand Down
39 changes: 33 additions & 6 deletions Source/Flow/Private/FlowSubsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ UFlowAsset* UFlowSubsystem::CreateRootFlow(UObject* Owner, UFlowAsset* FlowAsset
return NewFlow;
}

void UFlowSubsystem::FinishRootFlow(UObject* Owner, UFlowAsset* TemplateAsset, const EFlowFinishPolicy FinishPolicy)
void UFlowSubsystem::FinishAndDeinitializeRootFlow(UObject* Owner, UFlowAsset* TemplateAsset, const EFlowFinishPolicy FinishPolicy)
{
UFlowAsset* InstanceToFinish = nullptr;

Expand All @@ -139,11 +139,11 @@ void UFlowSubsystem::FinishRootFlow(UObject* Owner, UFlowAsset* TemplateAsset, c
if (InstanceToFinish)
{
RootInstances.Remove(InstanceToFinish);
InstanceToFinish->FinishFlow(FinishPolicy);
InstanceToFinish->FinishFlowAndDeinitializeInstance(FinishPolicy);
}
}

void UFlowSubsystem::FinishAllRootFlows(UObject* Owner, const EFlowFinishPolicy FinishPolicy)
void UFlowSubsystem::FinishAndDeinitializeAllRootFlows(UObject* Owner, const EFlowFinishPolicy FinishPolicy)
{
TArray<UFlowAsset*> InstancesToFinish;

Expand All @@ -158,7 +158,7 @@ void UFlowSubsystem::FinishAllRootFlows(UObject* Owner, const EFlowFinishPolicy
for (UFlowAsset* InstanceToFinish : InstancesToFinish)
{
RootInstances.Remove(InstanceToFinish);
InstanceToFinish->FinishFlow(FinishPolicy);
InstanceToFinish->FinishFlowAndDeinitializeInstance(FinishPolicy);
}
}

Expand All @@ -182,7 +182,12 @@ UFlowAsset* UFlowSubsystem::CreateSubFlow(UFlowNode_SubGraph* SubGraphNode, cons
// get instanced asset from map - in case it was already instanced by calling CreateSubFlow() with bPreloading == true
UFlowAsset* AssetInstance = InstancedSubFlows[SubGraphNode];

AssetInstance->NodeOwningThisAssetInstance = SubGraphNode;
if (!AssetInstance->NodeOwningThisAssetInstance.IsValid())
{
AssetInstance->NodeOwningThisAssetInstance = SubGraphNode;
}
check(AssetInstance->NodeOwningThisAssetInstance == SubGraphNode);

SubGraphNode->GetFlowAsset()->ActiveSubGraphs.Add(SubGraphNode, AssetInstance);

// don't activate Start Node if we're loading Sub Graph from SaveGame
Expand All @@ -195,6 +200,23 @@ UFlowAsset* UFlowSubsystem::CreateSubFlow(UFlowNode_SubGraph* SubGraphNode, cons
return NewInstance;
}

void UFlowSubsystem::FinishSubFlow(UFlowNode_SubGraph* SubGraphNode, const EFlowFinishPolicy FinishPolicy)
{
if (InstancedSubFlows.Contains(SubGraphNode))
{
// The flow asset running on the subgraph node.
UFlowAsset* SubgraphFlowAsset = InstancedSubFlows[SubGraphNode];

// This is the flow asset that has the subgraph node. Do not confuse with the flow asset that the node is running.
// Remove the subgraph flow from the owning flow active subgraph list.
UFlowAsset* SubgraphNodeParentFlow = SubGraphNode->GetFlowAsset();
SubgraphNodeParentFlow->ActiveSubGraphs.Remove(SubGraphNode);

// Finish the flow but do not remove the instance.
SubgraphFlowAsset->FinishFlow(FinishPolicy);
}
}

void UFlowSubsystem::RemoveSubFlow(UFlowNode_SubGraph* SubGraphNode, const EFlowFinishPolicy FinishPolicy)
{
if (InstancedSubFlows.Contains(SubGraphNode))
Expand All @@ -204,7 +226,12 @@ void UFlowSubsystem::RemoveSubFlow(UFlowNode_SubGraph* SubGraphNode, const EFlow
SubGraphNode->GetFlowAsset()->ActiveSubGraphs.Remove(SubGraphNode);
InstancedSubFlows.Remove(SubGraphNode);

AssetInstance->FinishFlow(FinishPolicy);
if (AssetInstance->IsActive())
{
AssetInstance->FinishFlow(FinishPolicy);
}

AssetInstance->DeinitializeInstance();

// Make sure to set the NodeOwningThisAssetInstance after the FinishFlow call, as it may be needed in the FinishFlow method
AssetInstance->NodeOwningThisAssetInstance = nullptr;
Expand Down
16 changes: 14 additions & 2 deletions Source/Flow/Private/Nodes/Graph/FlowNode_SubGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,26 @@ void UFlowNode_SubGraph::ExecuteInput(const FName& PinName)

void UFlowNode_SubGraph::Cleanup()
{
if (CanBeAssetInstanced() && GetFlowSubsystem())
UFlowSubsystem* FlowSubsystem = GetFlowSubsystem();
if (CanBeAssetInstanced() && FlowSubsystem)
{
GetFlowSubsystem()->RemoveSubFlow(this, EFlowFinishPolicy::Keep);
FlowSubsystem->FinishSubFlow(this, EFlowFinishPolicy::Keep);
}

Super::Cleanup();
}

void UFlowNode_SubGraph::DeinitializeInstance()
{
UFlowSubsystem* FlowSubsystem = GetFlowSubsystem();
if (CanBeAssetInstanced() && FlowSubsystem)
{
FlowSubsystem->RemoveSubFlow(this, EFlowFinishPolicy::Keep);
}

Super::DeinitializeInstance();
}

void UFlowNode_SubGraph::ForceFinishNode()
{
TriggerFirstOutput(true);
Expand Down
4 changes: 4 additions & 0 deletions Source/Flow/Public/FlowAsset.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ class FLOW_API UFlowAsset : public UObject
virtual void DeinitializeInstance();
bool IsInstanceInitialized() const { return IsValid(TemplateAsset); }

void FinishFlowAndDeinitializeInstance(const EFlowFinishPolicy InFinishPolicy);

UFlowAsset* GetTemplateAsset() const { return TemplateAsset; }

/* Object that spawned Root Flow instance, i.e. World Settings or Player Controller.
Expand All @@ -381,6 +383,8 @@ class FLOW_API UFlowAsset : public UObject

virtual void PreStartFlow();
virtual void StartFlow(IFlowDataPinValueSupplierInterface* DataPinValueSupplier = nullptr);
virtual void FinishFlow(const EFlowFinishPolicy InFinishPolicy);

bool HasStartedFlow() const;

protected:
Expand Down
9 changes: 7 additions & 2 deletions Source/Flow/Public/FlowSubsystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,21 @@ class FLOW_API UFlowSubsystem : public UGameInstanceSubsystem
* Nodes have opportunity to terminate themselves differently if Flow Graph has been aborted
* Example: Spawn node might despawn all actors if Flow Graph is aborted, not completed */
UFUNCTION(BlueprintCallable, Category = "FlowSubsystem", meta = (DefaultToSelf = "Owner"))
virtual void FinishRootFlow(UObject* Owner, UFlowAsset* TemplateAsset, const EFlowFinishPolicy FinishPolicy);
virtual void FinishAndDeinitializeRootFlow(UObject* Owner, UFlowAsset* TemplateAsset, const EFlowFinishPolicy FinishPolicy);

/* Finish Policy value is read by Flow Node
* Nodes have opportunity to terminate themselves differently if Flow Graph has been aborted
* Example: Spawn node might despawn all actors if Flow Graph is aborted, not completed */
UFUNCTION(BlueprintCallable, Category = "FlowSubsystem", meta = (DefaultToSelf = "Owner"))
virtual void FinishAllRootFlows(UObject* Owner, const EFlowFinishPolicy FinishPolicy);
virtual void FinishAndDeinitializeAllRootFlows(UObject* Owner, const EFlowFinishPolicy FinishPolicy);

protected:
UFlowAsset* CreateSubFlow(UFlowNode_SubGraph* SubGraphNode, const FString& SavedInstanceName = FString(), const bool bPreloading = false);

/* Finishes the SubFlow running in the SubGraphNode. It does not deinitialize or removes from the internal InstancedSubFlows list */
void FinishSubFlow(UFlowNode_SubGraph* SubGraphNode, const EFlowFinishPolicy FinishPolicy);

/* Removes the Subflow from the InstancedSubFlows list; and Finishes and Deinitializes it. */
void RemoveSubFlow(UFlowNode_SubGraph* SubGraphNode, const EFlowFinishPolicy FinishPolicy);

public:
Expand Down
3 changes: 2 additions & 1 deletion Source/Flow/Public/Nodes/Graph/FlowNode_SubGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FLOW_API UFlowNode_SubGraph
GENERATED_BODY()

public:
UFlowNode_SubGraph();
UFlowNode_SubGraph();

friend class UFlowAsset;
friend class FFlowNode_SubGraphDetails;
Expand Down Expand Up @@ -53,6 +53,7 @@ class FLOW_API UFlowNode_SubGraph

virtual void ExecuteInput(const FName& PinName) override;
virtual void Cleanup() override;
virtual void DeinitializeInstance() override;

public:
virtual void ForceFinishNode() override;
Expand Down