237 lines
5.5 KiB
C#
237 lines
5.5 KiB
C#
|
|
using System.Diagnostics;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using Godot;
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class ActionSequenceRunner
|
|
{
|
|
public ActionSequence sequence;
|
|
public List<RJAction> actions;
|
|
public List<RJSequenceAction> sequencables;
|
|
public int sequencablesIndex = 0;
|
|
bool cancelled = false;
|
|
bool cancelledSequence = false;
|
|
|
|
int _runID = -1;
|
|
|
|
RJSequenceAction _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 => Actions.Trigger( 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<RJSequenceAction,RJSequenceAction.OnSequenceDoneEventHandler> callbacks =
|
|
new Dictionary<RJSequenceAction, RJSequenceAction.OnSequenceDoneEventHandler>();
|
|
|
|
void StartAction( RJSequenceAction action )
|
|
{
|
|
var capturedAction = action;
|
|
|
|
RJSequenceAction.OnSequenceDoneEventHandler callback =
|
|
( long id, bool success ) =>
|
|
{
|
|
|
|
//RJLog.Log( "On Done", id, success );
|
|
|
|
if ( id != _runningActionID )
|
|
{
|
|
// RJLog.Error( "Invalid ID", id, "!=", _runningActionID );
|
|
return;
|
|
}
|
|
|
|
_runningActionID = -1;
|
|
|
|
if ( success )
|
|
{
|
|
sequencablesIndex ++;
|
|
ProcessNext();
|
|
}
|
|
else
|
|
{
|
|
sequence.DispatchCancelled( _runID );
|
|
sequence.ClearRun( this );
|
|
}
|
|
|
|
var callbackReference = callbacks[ capturedAction ];
|
|
capturedAction.OnSequenceDone -= callbackReference;
|
|
|
|
callbacks.Remove( capturedAction );
|
|
};
|
|
|
|
RunNext( action, callback );
|
|
|
|
/*
|
|
_runningAction = action;
|
|
callbacks[ _runningAction ] = callback;
|
|
_runningAction.OnSequenceDone += callback;
|
|
TriggerAllBefore( _runningAction );
|
|
Actions.Trigger( _runningAction );
|
|
_runningActionID = _runningAction.GetLastSequenceActionID();
|
|
*/
|
|
}
|
|
|
|
void RunNext( RJSequenceAction action, RJSequenceAction.OnSequenceDoneEventHandler callback )
|
|
{
|
|
_runningAction = action;
|
|
callbacks[ _runningAction ] = callback;
|
|
_runningAction.OnSequenceDone += callback;
|
|
|
|
|
|
TriggerAllBefore( _runningAction );
|
|
Actions.Trigger( _runningAction );
|
|
_runningActionID = _runningAction.GetLastSequenceActionID();
|
|
}
|
|
|
|
void TriggerAllBefore( RJSequenceAction action )
|
|
{
|
|
var actionIndex = actions.IndexOf( action );
|
|
|
|
for ( int i = actionIndex - 1; i >= 0; i -- )
|
|
{
|
|
if ( typeof( RJSequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
RJLog.Log( "Triggering Action", actions[ i ].Name );
|
|
|
|
Actions.Trigger( actions[ i ] );
|
|
}
|
|
|
|
}
|
|
|
|
void TriggerAllAfter( RJSequenceAction action )
|
|
{
|
|
var actionIndex = actions.IndexOf( action );
|
|
|
|
for ( int i = actionIndex + 1; i < actions.Count; i ++ )
|
|
{
|
|
if ( typeof( RJSequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
RJLog.Log( "Triggering Action", actions[ i ].Name );
|
|
Actions.Trigger( actions[ i ] );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/RJActionSequence.svg") ]
|
|
public partial class ActionSequence:RJSequenceAction
|
|
{
|
|
/** <summary for="field actions">Actions to execute</summary>*/
|
|
[Export]
|
|
public RJAction[] actions;
|
|
|
|
[Export]
|
|
public bool triggerDirectChildren = true;
|
|
|
|
List<ActionSequenceRunner> running = new List<ActionSequenceRunner>();
|
|
|
|
public override void _OnTrigger()
|
|
{
|
|
var run = new ActionSequenceRunner();
|
|
run.sequence = this;
|
|
run.actions = new List<RJAction>( actions );
|
|
|
|
if ( triggerDirectChildren )
|
|
{
|
|
Nodes.ForEachDirectChild<RJAction>( this, a => run.actions.Add( a ) );
|
|
}
|
|
|
|
run.sequencables = Lists.FilterType<RJAction,RJSequenceAction>( 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( ActionSequenceRunner run )
|
|
{
|
|
running.Remove( run );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} |