rj-action-library/Runtime/Time/TImeLineManager_Scheduling.cs

188 lines
5.5 KiB
C#

using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
using System.Threading.Tasks;
namespace Rokojori
{
public partial class TimeLineManager:NetworkNode
{
public static void RemoveEvent( TimeLine timeline, int id )
{
RJLog.Log( "Removing tick:", timeline, id );
timeline = TimeLineManager.Ensure( timeline );
var runner = timeline.runner;
runner.RemoveEvent( id );
}
public static TimeLineCallback ScheduleCallback( TimeLine timeline, System.Action<TimeLineCallback> callback )
{
timeline = TimeLineManager.Ensure( timeline );
var runner = timeline.runner;
var eventID = TimeLineManager.CreateID();
return runner._ScheduleCallback( callback, eventID );
}
static async Task RunLater( float delay, TimeLineEvent te, Action<TimeLineEvent> callback, Node context = null )
{
await context.RequestNextFrame();
await context.WaitForAsyncTimer( delay );
callback( te );
}
public static TimeLineEvent ScheduleEvent( TimeLine timeline, float position, Action<TimeLineEvent> callback, Node context = null )
{
timeline = TimeLineManager.Ensure( timeline );
if ( Engine.IsEditorHint() )
{
var te = new TimeLineEvent();
var time = timeline.position;
RunLater( position - time, te, callback, context );
return te;
}
var runner = timeline.runner;
var eventID = TimeLineManager.CreateID();
return runner._ScheduleEvent( position, eventID, false, callback );
}
public static TimeLineEvent ScheduleEventIn( TimeLine timeline, float offset, Action<TimeLineEvent> callback, Node context = null)
{
timeline = TimeLineManager.Ensure( timeline );
var position = timeline.position + offset;
return ScheduleEvent( timeline, position, callback, context );
}
public static TimeLineEvent ScheduleEventWith( Duration duration, Action<TimeLineEvent> callback, Node context = null )
{
return ScheduleEventIn( duration.timeLine, duration.GetDurationInSeconds(), callback, context );
}
public static TimeLineEvent ScheduleLoopEvent( TimeLine timeline, float duration, float offset, Action<TimeLineEvent> callback )
{
timeline = TimeLineManager.Ensure( timeline );
var runner = timeline.runner;
var eventID = TimeLineManager.CreateID();
return runner._ScheduleLoopEvent( duration, offset, eventID, false, callback );
}
public static TimeLineSpan ScheduleSpan( TimeLine timeline, float start, float end, Action<TimeLineSpan,TimeLineSpanUpdateType> callback, Node context = null )
{
timeline = TimeLineManager.Ensure( timeline );
var delay = start - timeline.position;
var duration = end - start;
return ScheduleSpanIn( timeline, delay, duration, callback, context );
/*if ( Engine.IsEditorHint() )
{
var span = new TimeLineSpan();
span.id = GodotRandom.Get().IntegerInclusive( 0, 1000000 );
// var root = Root.Window();
// RJLog.Log( root, RokojoriPlugin.Get() );
RunInEditor( span, end - start, callback, context );
return span;
}
timeline = TimeLineManager.Ensure( timeline );
var runner = timeline.runner;
var spanID = TimeLineManager.CreateID();
var duration = end - start;
return runner._ScheduleSpan( start, end, spanID, false, callback );*/
}
public static TimeLineSpan ScheduleSpanWith( Duration duration, Action<TimeLineSpan,TimeLineSpanUpdateType> callback )
{
return ScheduleSpanIn( duration.timeLine, 0, duration.GetDurationInSeconds(), callback );
}
static async Task RunSpanInEditor( TimeLineSpan span, float duration, Action<TimeLineSpan,TimeLineSpanUpdateType> callback, Node context = null )
{
if ( context == null )
{
return;
}
for ( int i = 0; i < 3; i++ )
{
await context.RequestNextFrame();
}
var elapsed = 0f;
var isFirst = true;
var startTime = Time.GetTicksMsec() / 1000.0f;
span.start = startTime;
span.end = startTime + duration;
span.wasInside = true;
span.timeLine = new TimeLine();
while ( elapsed < duration )
{
var type = isFirst ? TimeLineSpanUpdateType.Start : TimeLineSpanUpdateType.InSpan;
isFirst = false;
callback( span, type );
await context.RequestNextFrame();
elapsed = ( Time.GetTicksMsec() / 1000.0f - startTime );
}
callback( span, TimeLineSpanUpdateType.End );
}
public static TimeLineSpan ScheduleSpanIn( TimeLine timeline, float delay, float duration, Action<TimeLineSpan,TimeLineSpanUpdateType> callback, Node context = null )
{
timeline = TimeLineManager.Ensure( timeline );
if ( Engine.IsEditorHint() )
{
var span = new TimeLineSpan();
span.id = GodotRandom.Get().IntegerInclusive( 0, 1000000 );
// var root = Root.Window();
// RJLog.Log( root, RokojoriPlugin.Get() );
RunSpanInEditor( span, duration, callback, context );
return span;
}
var runner = timeline.runner;
if ( runner == null )
{
return null;
}
var start = timeline.position + delay;
var end = start + duration;
var spanID = TimeLineManager.CreateID();
return runner._ScheduleSpan( start, end, spanID, false, callback );
}
}
}