Navigation
API > API/Plugins > API/Plugins/ControlFlows
Inheritance Hierarchy
- FSharedFromThisBase
- TSharedFromThis
- FControlFlow
References
| Module | ControlFlows |
| Header | /Engine/Plugins/Experimental/ControlFlows/Source/ControlFlows/Public/ControlFlow.h |
| Include | #include "ControlFlow.h" |
Syntax
class FControlFlow : public TSharedFromThis< FControlFlow >
Remarks
System/Tool to queue (asynchronous or synchronous) functions for modularity implemented via delegates. Allows code to be more easily read so there fewer 'Alt+G'-ing around to figure out what and where a class does it's thing
This system only supports non-const functions currently.
'QueueFunction': Queues a 'void (...)' function. The Flow will execute this function and continue on with the next function in queue.
'QueueWait': Queues a 'void (FControlFlowNodeRef FlowHandle, ...)' function. The flow will stop until 'FlowHandle->ContinueFlow()' is called. BE RESPONSIBLE and make sure all code paths call to continue xOR cancel, otherwise the flow will hang.
'QueueControlFlow': Queues a 'void (TSharedRef
'QueueControlFlowBranch': Queues a 'int32(TSharedRef
'QueueConcurrentFlows': Queues a 'void(TSharedRef
'QueueConditionalLoop': Queues a 'EConditionalLoopResult(TSharedRef
'QueueStep': Usable in UObject's or classes that derive from TSharedFromThis
Using the auto-deduction of 'QueueStep', you can change the queue from a synchronous function (QueueFunction) to an asynchronous one (QueueWait) or vice-versa by adding/removing the 'FControlFlowNodeRef FlowHandle' as your first parameter. And you can change it to (QueueControlFlow) if need be as well!
Syntax:
void MyFunction(...); void MyFunction(FControlFlowNodeRef FlowHandle, ...); void MyFunction(TSharedRef
ControlFlowInstance->QueueStep(this, &UserClass:MyFunction1, ...) .QueueStep(this, &UserClass:MyFunction2, ...) .QueueStep(this, &UserClass:MyFunction3, ...);
This allow ease of going from Synchronous Functionality to Asynchronously Functionality to Subflows as you build out your Flow.
Full Example Class
struct FMyFlowClass : public TSharedFromThis
void RunMyPurpose()
{
MyPurpose
.QueueStep(this, &ThisClass::Construct)
.Loop(this
{
Outerloop->RunLoopFirst()
.SetCancelledNodeAsComplete(true)
.QueueStep(this, &ThisClass::Foo)
.QueueStep(this, &ThisClass::Foo)
.Loop(this
{
InnerLoop->CheckConditionFirst()
.BranchFlow([this], TSharedRef
Branch->AddOrGetBranch(1)
.QueueStep(this, &ThisClass::Foo)
.ForkFlow([this], TSharedRef
ConcurrentFlows->AddOrGetFlow(1) .QueueStep(this, &ThisClass::Foo); });
return FMath::RandBool() ? EConditionalLoopResult::RunLoop : EConditionalLoopResult::LoopFinished; }) .QueueStep(this, &ThisClass::Foo);
return FMath::RandBool() ? EConditionalLoopResult::RunLoop : EConditionalLoopResult::LoopFinished; }) .QueueStep(this, &ThisClass::Foo);
return EConditionalLoopResult::RunLoop; // OuterLoop will never end in this example }) .QueueStep(this, &ThisClass::Destruct) .ExecuteFlow(); }
private: void Foo(); void Construct(); // Equivalent to Init void Destruct(); // Equivalent to Uninit
TSharedRef
The implementation details of a flow can be fully disjointed from the Flow logic itself!
Constructors
| Type | Name | Description | |
|---|---|---|---|
FControlFlow
(
const FString& FlowDebugName |
Functions
| Type | Name | Description | |
|---|---|---|---|
| FControlFlow & | BranchFlow
(
FunctionT InBranchLambda, |
||
| void | CancelFlow () |
Will cancel ALL flows, both child ControlFlows and ControlFlows who owns this Flow. | |
| void | ExecuteFlow () |
This needs to be called, otherwise nothing will happen!! Call after you finish adding functions to the queue. | |
| FControlFlow & | ForkFlow
(
FunctionT InForkLambda, |
||
| TOptional< FString > | |||
| const FString & | GetDebugName () |
||
| TSharedPtr< FTrackedActivity > | |||
| bool | IsRunning () |
||
| FControlFlow & | Loop
(
FunctionT InLoopLambda, |
||
| size_t | NumInQueue () |
||
| FSimpleMulticastDelegate & | OnFlowCancel () |
||
| FSimpleMulticastDelegate & | |||
| FSimpleMulticastDelegate & | |||
| TSharedRef< FControlFlowTask_BranchLegacy > | QueueBranch
(
FControlFlowBranchDecider_Legacy& BranchDecider, |
Both of these implementations are deprecated. | |
| FConcurrentFlowsDefiner & | QueueConcurrentFlows
(
const FString& TaskName, |
||
| FControlFlowConditionalLoopDefiner & | QueueConditionalLoop
(
const FString& TaskName, |
||
| FControlFlowPopulator & | QueueControlFlow
(
const FString& TaskName, |
||
| FControlFlowBranchDefiner & | QueueControlFlowBranch
(
const FString& TaskName, |
||
| FControlFlow & | QueueDelay
(
const float InSeconds, |
||
| FSimpleDelegate & | QueueFunction
(
const FString& FlowNodeDebugName |
||
| FControlFlowPopulator & | QueueLoop
(
FControlFlowLoopComplete& LoopCompleteDelgate, |
||
| FControlFlow & | QueueSetCancelledNodeAsComplete
(
const bool bCancelledNodeIsComplete, |
||
| FControlFlow & | QueueStep
(
ArgsT... Params |
||
| FControlFlow & | |||
| FControlFlow & | |||
| FControlFlow & | QueueStep
(
const char* NodeName, |
||
| FControlFlowWaitDelegate & | |||
| void | Reset () |
||
| FControlFlow & | SetCancelledNodeAsComplete
(
bool bCancelledNodeIsComplete |
||
| FControlFlow & | TrackActivities
(
TSharedPtr< FTrackedActivity > InActivity |
Constants
| Name | Description |
|---|---|
| UnnamedControlFlowCounter |