Untitled
user_8265478
plain_text
2 years ago
4.6 kB
7
Indexable
//MultiGate.h//
// Copyright https://github.com/MothCocoon/FlowGraph/graphs/contributors
#pragma once
#include "Nodes/FlowNode.h"
#include "FlowNode_ExecutionMultiGate.generated.h"
/**
* Executes a series of pins in order
*/
UCLASS(NotBlueprintable, meta = (DisplayName = "Multi Gate", Keywords = "series, loop, random"))
class FLOW_API UFlowNode_ExecutionMultiGate final : public UFlowNode
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category = "MultiGate", meta = (EditCondition = "bParallel==false"))
bool bRandom;
// Allow executing output pins again, without triggering Reset pin
// If set to False, every output pin can be triggered only once
UPROPERTY(EditAnywhere, Category = "MultiGate")
bool bLoop;
//Allow the execution of the outputs in parallel
UPROPERTY(EditAnywhere, Category = "MultiGate")
bool bParallel;
UPROPERTY(EditAnywhere, Category = "MultiGate")
int32 StartIndex;
private:
UPROPERTY(SaveGame)
int32 NextOutput;
UPROPERTY(SaveGame)
TArray<bool> Completed;
public:
#if WITH_EDITOR
virtual bool CanUserAddOutput() const override { return true; }
#endif
protected:
virtual void ExecuteInput(const FName& PinName) override;
virtual void Cleanup() override;
#if WITH_EDITOR
virtual FString GetNodeDescription() const override;
#endif
};
//MultiGate.cpp//
// Copyright https://github.com/MothCocoon/FlowGraph/graphs/contributors
#include "Nodes/Route/FlowNode_ExecutionMultiGate.h"
UFlowNode_ExecutionMultiGate::UFlowNode_ExecutionMultiGate(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, StartIndex(INDEX_NONE)
{
#if WITH_EDITOR
Category = TEXT("Route");
NodeStyle = EFlowNodeStyle::Logic;
#endif
FString ResetPinTooltip = TEXT("Finish work of this node.");
ResetPinTooltip += LINE_TERMINATOR;
ResetPinTooltip += TEXT("Calling In input will start triggering output pins once again.");
InputPins.Add(FFlowPin(TEXT("Stop")));
InputPins.Add(FFlowPin(TEXT("Reset"), ResetPinTooltip));
AllowedSignalModes = {EFlowSignalMode::Enabled, EFlowSignalMode::Disabled};
OutputPins.Empty();
SetNumberedOutputPins(0, 1);
OutputPins.Add(FFlowPin(TEXT("Completed")));
OutputPins.Add(FFlowPin(TEXT("Stopped")));
}
void UFlowNode_ExecutionMultiGate::ExecuteInput(const FName& PinName)
{
if (PinName == DefaultInputPin.PinName)
{
if (Completed.Num() == 0)
{
Completed.Init(false, OutputPins.Num());
}
if (!Completed.Contains(false))
{
return;
}
const bool bUseStartIndex = !Completed.Contains(true) && Completed.IsValidIndex(StartIndex);
if (bParallel)
{
// Ejecutar todas las salidas en paralelo directamente
for (const FFlowPin& Output : OutputPins)
{
TriggerOutput(Output.PinName, false);
}
// Llamar al output "Completed" cuando se completan todas las salidas en paralelo
TriggerOutput(TEXT("Completed"), false);
}
if (bRandom)
{
int32 Index;
if (bUseStartIndex)
{
Index = StartIndex;
}
else
{
TArray<int32> AvailableIndexes;
AvailableIndexes.Reserve(Completed.Num()); // todo
for (int32 i = 0; i < Completed.Num(); i++)
{
if (Completed[i] == false)
{
AvailableIndexes.Emplace(i);
}
}
const int32 Random = FMath::RandRange(0, AvailableIndexes.Num() - 1);
Index = AvailableIndexes[Random];
}
Completed[Index] = true;
TriggerOutput(OutputPins[Index].PinName, false);
}
else
{
if (bUseStartIndex)
{
NextOutput = StartIndex;
}
const int32 CurrentOutput = NextOutput;
// We have to calculate NextOutput before TriggerOutput(..)
// TriggerOutput may call Reset and Cleanup
NextOutput = ++NextOutput % OutputPins.Num();
Completed[CurrentOutput] = true;
TriggerOutput(OutputPins[CurrentOutput].PinName, false);
}
if (!Completed.Contains(false) && bLoop)
{
Finish();
}
}
else if (PinName == TEXT("Reset"))
{
Finish();
}
}
void UFlowNode_ExecutionMultiGate::Cleanup()
{
NextOutput = 0;
Completed.Reset();
}
#if WITH_EDITOR
FString UFlowNode_ExecutionMultiGate::GetNodeDescription() const
{
FString Result;
Result.Reserve(128);
if (bRandom)
{
Result.Append(TEXT("Random"));
}
if (bParallel)
{
Result.Append(TEXT("Parallel"));
}
if (bRandom && bLoop)
{
Result.Append(TEXT(", "));
}
if (bLoop)
{
Result.Append(TEXT("Loop"));
}
if (StartIndex != INDEX_NONE)
{
if (bRandom || bLoop)
{
Result.Append(TEXT(", "));
}
if (OutputPins.IsValidIndex(StartIndex))
{
Result.Appendf(TEXT("Start Index: %d"), StartIndex);
}
else
{
Result.Append(TEXT("StartIndex: Invalid"));
}
}
return Result;
}
#endif
Editor is loading...
Leave a Comment