162 lines
3.5 KiB
C#
162 lines
3.5 KiB
C#
|
|
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<TimeLineEvent> events = new List<TimeLineEvent>();
|
|
List<TimeLineSpan> spans = new List<TimeLineSpan>();
|
|
|
|
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<int> eventRemovals = null;
|
|
List<int> 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<int>(); }
|
|
|
|
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<int>(); }
|
|
|
|
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 );
|
|
}
|
|
}
|
|
} |