using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System; using Godot; namespace Rokojori { public class TimeLineRunner { public RJTimeLine timeLine; public double lastPosition = 0; public double position = 0; public bool playing = false; public double deltaScale = 1; public double speed = 1; List events = new List(); List spans = new List(); public TimeLineRunner( RJTimeLine timeLine ) { this.timeLine = timeLine; playing = timeLine.AutoStart; } public void UpdateTimeLine( double delta, TimeLineManager manager ) { if ( ! playing ) { return; } lastPosition = position; position += delta * deltaScale * speed; var isForward = speed >= 0; if ( isForward ) { ProcessForward( manager ); } } void ProcessForward( TimeLineManager manager ) { List eventRemovals = null; List spanRemovals = null; for ( int i = 0; i < events.Count; i++ ) { var eventPosition = events[ i ].position; if ( ! RangeDouble.ContainsExclusiveMax( lastPosition, position, eventPosition ) ) { continue; } RJLog.Log( "Emitting:", "last:", lastPosition, "now:", position, "event:", eventPosition ); manager.EmitSignal( TimeLineManager.SignalName.OnEvent, events[ i ].id ); if ( events[ i ].persistent ) { continue; } if ( eventRemovals == null ){ eventRemovals = new List(); } eventRemovals.Add( i ); } if ( eventRemovals != null ) { Lists.RemoveIncreasingIndices( events, eventRemovals ); } if ( spans.Count == 0 ) { return; } var timelineSpan = new RangeDouble( lastPosition, position ); var span = new RangeDouble( 0, 1 ); for ( int i = 0; i < spans.Count; i++ ) { span.min = spans[ i ].start; span.max = spans[ i ].end; if ( ! timelineSpan.Overlaps( span ) ) { continue; } var isStart = timelineSpan.Contains( spans[ i ].start ); var isEnd = timelineSpan.Contains( spans[ i ].end ); var spanType = TimeLineSpan.InSpan; if ( isStart && isEnd ) { spanType = TimeLineSpan.CompletelyInside; } else if ( isStart ) { spanType = TimeLineSpan.Start; } else if ( isEnd ) { spanType = TimeLineSpan.End; } manager.EmitSignal( TimeLineManager.SignalName.OnSpan, spans[ i ].id, spanType ); if ( spans[ i ].persistent ) { continue; } if ( spanRemovals == null ){ spanRemovals = new List(); } spanRemovals.Add( i ); } } public void ScheduleEvent( double position, int callbackID, bool isPersistent ) { var tle = new TimeLineEvent(); tle.position = position; tle.id = callbackID; tle.persistent = isPersistent; events.Add( tle ); } public void ScheduleSpan( double start, double end, int callbackID, bool isPersistent ) { var tse = new TimeLineSpan(); tse.start = start; tse.end = end; tse.id = callbackID; tse.persistent = isPersistent; tse.wasInside = false; spans.Add( tse ); } } }