rokojori_action_library/Runtime/Actions/Sequence/Parallel.cs

113 lines
3.0 KiB
C#

using Godot;
using System.Collections.Generic;
using Rokojori.Extensions;
namespace Rokojori
{
[Tool][GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Parallel.svg") ]
[RokojoriActionCoreExport]
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 = new Action[ 0 ];
[Export]
public bool triggerDirectChildren = true;
[Export]
public bool ignoreNonSequenceActions = true;
[Export]
public bool errorsCountAsFinished = false;
Dictionary<int,int> numFinished = new Dictionary<int, int>();
Dictionary<int,bool> running = new Dictionary<int, bool>();
protected override void _OnTrigger()
{
var allActions = new List<Action>( this.actions );
if ( triggerDirectChildren )
{
Nodes.ForEachDirectChild<Action>( this, a => allActions.Add( a ) );
}
var sequenceActions = ListExtensions.FilterType<Action,SequenceAction>( allActions);
var sequenceID = DispatchStart();
if ( ! ignoreNonSequenceActions && sequenceActions.Count != allActions.Count && Mode.First_Finishes_Sequence == mode )
{
allActions.ForEach( a => Action.TriggerSafe( a ) );
DispatchEnd( sequenceID );
return;
}
numFinished[ sequenceID ] = 0;
running[ sequenceID ] = true;
// var numFinished = 0;
// var running = true;
sequenceActions.ForEach(
sa =>
{
sa.onSequenceDone.Once(
( fe )=>
{
// this.LogInfo( "Sequence Action finished:", HierarchyName.Of( sa ) );
if ( ! running.ContainsKey( sequenceID ) )
{
return;
}
if ( fe.success || errorsCountAsFinished )
{
numFinished[ sequenceID ] = numFinished[ sequenceID ] + 1;
if ( Mode.First_Finishes_Sequence == mode )
{
running.Remove( sequenceID );
// this.LogInfo( "DispatchEnd for First_Finishes_Sequence" );
DispatchEnd( sequenceID );
}
else if ( Mode.Wait_For_All_To_Finish == mode )
{
if ( numFinished[ sequenceID ] == sequenceActions.Count )
{
running.Remove( sequenceID );
// this.LogInfo( "DispatchEnd for Wait_For_All_To_Finish" );
DispatchEnd( sequenceID );
}
}
}
else
{
running.Remove( sequenceID );
// this.LogInfo( "DispatchCancelled for Wait_For_All_To_Finish" );
DispatchCancelled( sequenceID );
}
}
);
}
);
allActions.ForEach( a => Action.TriggerSafe( a ) );
}
}
}