using Godot; using System.Collections.Generic; namespace Rokojori { [Tool][GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Parallel.svg") ] public partial class RepeatSequence : SequenceAction { [Export] public Action action; [Export] public int maxNumRepeats = 3; [Export] public float maxRepeatDuration = 60; [Export] public TimeLine timeLine; bool stopSignal = false; public void Stop() { stopSignal = true; } protected override void _OnTrigger() { var id = DispatchStart(); this.LogInfo( "Starting ID:", id ); if ( ! ( action is SequenceAction ) ) { Trigger( action ); DispatchEnd( id ); return; } var tl = TimeLineManager.Ensure( timeLine ); if ( maxNumRepeats <= 0 && ( tl == null || maxRepeatDuration <= 0 ) ) { return; } var runner = new RepeatSequenceRunner(); runner.Start( id, this ); } } public class RepeatSequenceRunner { public RepeatSequence repeatSequence; public TimeLine timeLine; public int sequenceID; public int maxRepeats = 0; public int started = 0; public float startTime = 0; public float endTime = 0; public void Start( int id, RepeatSequence repeatSequence ) { this.repeatSequence = repeatSequence; this.sequenceID = id; timeLine = TimeLineManager.Ensure( repeatSequence.timeLine ); startTime = timeLine.position; endTime = startTime + repeatSequence.maxRepeatDuration; maxRepeats = repeatSequence.maxNumRepeats; Next(); } public void Next() { if ( started == maxRepeats ) { repeatSequence.DispatchEnd( sequenceID ); repeatSequence.LogInfo( "Finished:", sequenceID ); return; } started ++; repeatSequence.LogInfo( "Next:", sequenceID, started ); var sa = (SequenceAction) repeatSequence.action; sa.onSequenceDone.Once( async ( fe ) => { // repeatSequence.LogInfo( fe.success ); await sa.RequestNextFrame(); Next(); } ); sa.Trigger(); } } }