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 numFinished = new Dictionary(); Dictionary running = new Dictionary(); protected override void _OnTrigger() { var allActions = new List( this.actions ); if ( triggerDirectChildren ) { Nodes.ForEachDirectChild( this, a => allActions.Add( a ) ); } var sequenceActions = ListExtensions.FilterType( 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 ) ); } } }