rj-action-library/Runtime/Actions/Sequence/Parallel.cs

99 lines
2.3 KiB
C#

using Godot;
using System.Collections.Generic;
namespace Rokojori
{
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Parallel.svg") ]
public partial class Parallel : SequenceAction
{
public enum Mode
{
First_Finishes_Sequence,
Wait_For_All_To_Finish
}
[Export]
public Mode mode = Mode.Wait_For_All_To_Finish;
[Export]
public Action[] actions;
[Export]
public bool triggerDirectChildren = true;
[Export]
public bool ignoreNonSequenceActions = true;
[Export]
public bool errorsCountAsFinished = false;
protected override void _OnTrigger()
{
var actions = new List<Action>( this.actions );
if ( triggerDirectChildren )
{
Nodes.ForEachDirectChild<Action>( this, a => actions.Add( a ) );
}
var sequenceActions = Lists.FilterAndMap( actions, ( a, i ) => a is SequenceAction, a => (SequenceAction) a );
var sequenceID = DispatchStart();
if ( ! ignoreNonSequenceActions && sequenceActions.Count != actions.Count && Mode.First_Finishes_Sequence == mode )
{
actions.ForEach( a => Action.Trigger( a ) );
DispatchEnd( sequenceID );
return;
}
var numFinished = 0;
var running = true;
sequenceActions.ForEach(
sa =>
{
sa.onSequenceDone.Once(
( fe )=>
{
if ( ! running )
{
return;
}
if ( fe.success || errorsCountAsFinished )
{
numFinished ++;
if ( Mode.First_Finishes_Sequence == mode )
{
running = false;
DispatchEnd( sequenceID );
}
else if ( Mode.Wait_For_All_To_Finish == mode )
{
if ( numFinished == sequenceActions.Count )
{
running = false;
DispatchEnd( sequenceID );
}
}
}
else
{
running = false;
DispatchCancelled( sequenceID );
}
}
);
}
);
actions.ForEach( a => Action.Trigger( a ) );
}
}
}