using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System; using Godot; using System.Threading.Tasks; using Rokojori.Extensions; 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 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 callback, Node context = null ) { await context.RequestNextFrame(); await context.WaitFor( delay ); callback( te ); } public static TimelineEvent ScheduleEvent( Timeline timeline, float position, Action 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 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 callback, Node context = null ) { return ScheduleEventIn( duration.timeLine, duration.GetDurationInSeconds(), callback, context ); } public static TimelineEvent ScheduleLoopEvent( Timeline timeline, float duration, float offset, Action 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 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 callback, Node context = null ) { return ScheduleSpanIn( duration.timeLine, 0, duration.GetDurationInSeconds(), callback, context ); } static async Task RunSpanInEditor( TimelineSpan span, float duration, Action 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 = Godot.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 = (Godot.Time.GetTicksMsec() / 1000.0f - startTime ); } callback( span, TimelineSpanUpdateType.End ); } public static TimelineSpan ScheduleSpanIn( Timeline timeline, float delay, float duration, Action callback, Node context = null ) { timeline = TimelineManager.Ensure( timeline ); if ( Engine.IsEditorHint() ) { var span = new TimelineSpan(); span.id = GodotRandom.Get().IntegerInclusiveInRange( 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 ); } } }