using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System; using Godot; namespace Rokojori { // public class SequenceRunner // { // public Sequence sequence; // public List actions; // public List sequencables; // public int sequencablesIndex = 0; // bool cancelled = false; // bool cancelledSequence = false; // int _runID = -1; // SequenceAction _runningAction; // int _runningActionID = -1; // public void Cancel() // { // if ( cancelled || _runningAction == null ) // { // return; // } // cancelled = true; // _runningAction.CancelAction( _runningActionID ); // } // void CancelRun() // { // if ( cancelledSequence ) // { // return; // } // if ( ! cancelled ) // { // cancelled = true; // } // cancelledSequence = true; // sequence.DispatchCancelled( _runID ); // sequence.ClearRun( this ); // } // public void ProcessNext() // { // // RJLog.Log( "@" + sequence.Name, "Index:", sequencablesIndex ); // if ( sequencablesIndex == 0 ) // { // _runID = sequence.DispatchStart(); // if ( sequencables.Count == 0 ) // { // actions.ForEach( a => Action.TriggerSafe( a ) ); // sequence.DispatchEnd( _runID ); // sequence.ClearRun( this ); // return; // } // } // if ( sequencablesIndex >= sequencables.Count ) // { // TriggerAllAfter( sequencables[ sequencables.Count -1 ] ); // sequence.DispatchEnd( _runID ); // sequence.ClearRun( this ); // return; // } // if ( cancelled ) // { // CancelRun(); // return; // } // var sequenceAction = sequencables[ sequencablesIndex ]; // StartAction( sequenceAction ); // } // Dictionary> callbacks = // new Dictionary>(); // void StartAction( SequenceAction action ) // { // var capturedAction = action; // System.Action callback = // ( SequenceAction.FinishedEvent ev ) => // { // //RJLog.Log( "On Done", id, success ); // if ( ev.id != _runningActionID ) // { // // RJLog.Error( "Invalid ID", id, "!=", _runningActionID ); // return; // } // _runningActionID = -1; // if ( ev.success ) // { // sequencablesIndex ++; // ProcessNext(); // } // else // { // sequence.DispatchCancelled( _runID ); // sequence.ClearRun( this ); // } // var callbackReference = callbacks[ capturedAction ]; // capturedAction.onSequenceDone.RemoveAction( callbackReference ); // callbacks.Remove( capturedAction ); // }; // RunNext( action, callback ); // /* // _runningAction = action; // callbacks[ _runningAction ] = callback; // _runningAction.OnSequenceDone += callback; // TriggerAllBefore( _runningAction ); // Action.Trigger( _runningAction ); // _runningActionID = _runningAction.GetLastSequenceActionID(); // */ // } // void RunNext( SequenceAction action, System.Action callback ) // { // _runningAction = action; // callbacks[ _runningAction ] = callback; // _runningAction.onSequenceDone.AddAction( callback ); // TriggerAllBefore( _runningAction ); // Action.TriggerSafe( _runningAction ); // _runningActionID = _runningAction.GetLastSequenceActionID(); // } // void TriggerAllBefore( SequenceAction action ) // { // var actionIndex = actions.IndexOf( action ); // for ( int i = actionIndex - 1; i >= 0; i -- ) // { // if ( typeof( SequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) ) // { // return; // } // // RJLog.Log( _runID, "Triggering Actions Before", i, actions[ i ].Name, HierarchyName.Of( action ) ); // Action.TriggerSafe( actions[ i ] ); // } // } // void TriggerAllAfter( SequenceAction action ) // { // var actionIndex = actions.IndexOf( action ); // for ( int i = actionIndex + 1; i < actions.Count; i ++ ) // { // if ( typeof( SequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) ) // { // return; // } // // RJLog.Log( "Triggering Action", actions[ i ].Name ); // Action.TriggerSafe( actions[ i ] ); // } // } // } [Tool] [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Sequence.svg") ] [RokojoriActionCoreExport] public partial class Sequence:SequenceAction { /** Actions to execute*/ [Export] public Action[] actions = new Action[ 0 ]; [Export] public bool triggerDirectChildren = true; List running = new List(); [Export] public bool noOverlays = false; protected override void _OnTrigger() { if ( noOverlays && running.Count > 0 ) { return; } // this.LogInfo( "Running" ); var run = new SequenceRunner(); run.sequence = this; run.actions = new List( actions ); if ( triggerDirectChildren ) { Nodes.ForEachDirectChild( this, a => run.actions.Add( a ) ); } run.sequencables = Lists.FilterType( run.actions ); // RJLog.Log( "Running", HierarchyName.Of( this ), run.sequencables.Count ); running.Add( run ); run.ProcessNext(); } public override void CancelAction( int id ) { running.ForEach( r => r.Cancel() ); } public void ClearRun( SequenceRunner run ) { running.Remove( run ); } } }