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 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.WaitForAsyncTimer( 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 ) { return ScheduleSpanIn( duration.timeLine, 0, duration.GetDurationInSeconds(), callback ); } 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 = 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 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 ); } } }