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

232 lines
5.7 KiB
C#
Raw Normal View History

2024-05-19 15:59:41 +00:00
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
namespace Rokojori
{
2024-09-14 06:41:52 +00:00
[Tool]
2024-05-19 15:59:41 +00:00
[GlobalClass]
public partial class TimeLineManager:RJTimeLineManager
{
[Export]
public RJTimeLine[] timeLines;
2025-01-03 12:09:23 +00:00
[Export]
public RJTimeLine engineTimeScale;
[Export]
public RJTimeLine realTimeTimeLine;
[Export]
public bool computeRealtimeWithEngineDelta;
2024-05-19 15:59:41 +00:00
List<TimeLineRunner> _runners = new List<TimeLineRunner>();
int _idCounter = 0;
bool _initialized = false;
public override void _Ready()
{
Initialize();
}
2025-01-03 12:09:23 +00:00
float _lastUpdate = 0;
DateTime lastUpdated = DateTime.Now;
float _estimatedDelta = 0;
float _estimatedDeltaFilter = 0.9f;
float _unscaledDelta = 0;
double _lastRealtimePosition = 0;
double _realtimePosition = 0;
float _lastTimeScale = 1;
public override void _Process( double delta )
{
UpdateRealTime( delta );
if ( engineTimeScale != null )
{
Engine.TimeScale = GetModulatedSpeed( engineTimeScale );
}
_runners.ForEach( r => r.UpdateTimeLine( unscaledTimeDelta, this ) );
}
public void Modulate( RJTimeLine timeline, AnimationCurve c, Action<bool> onReady )
{
var runner = GetRunner( GetTimeLineIndex( timeline ) );
runner.Modulate( c, onReady );
}
void UpdateRealTime( double engineDelta )
{
var now = DateTime.Now;
var unscaled = (float) ( ( now - lastUpdated ).TotalSeconds );
lastUpdated = now;
if ( unscaled < 1f/20f )
{
_estimatedDelta += _estimatedDeltaFilter * ( unscaled - _estimatedDelta );
}
if ( computeRealtimeWithEngineDelta )
{
_unscaledDelta = (float)( Engine.TimeScale == 0 ? _estimatedDelta : ( engineDelta / Engine.TimeScale ) );
}
else
{
_unscaledDelta = _estimatedDelta;
}
_lastRealtimePosition = _realtimePosition;
_realtimePosition += _unscaledDelta;
}
public float unscaledTimeDelta => _unscaledDelta;
public double realtime => _realtimePosition;
2024-05-19 15:59:41 +00:00
void Initialize()
{
if ( _initialized )
{
return;
}
_initialized = true;
_runners = Lists.Map( timeLines, tl => new TimeLineRunner( tl ) );
}
TimeLineRunner GetRunner( int index )
{
if ( index < 0 || index >= _runners.Count )
{
return null ;
}
return _runners[ index ];
}
public override int CreateID()
{
_idCounter ++;
return _idCounter;
}
2024-09-14 06:41:52 +00:00
public static float GetPosition( RJTimeLine timeLine )
{
var manager = Unique<TimeLineManager>.Get();
if ( manager == null )
{
return Time.GetTicksMsec() / 1000f;
}
var index = Arrays.IndexOf( manager.timeLines, timeLine );
index = Mathf.Max( index, 0 );
return (float) manager.GetPosition( index );
}
public static float GetPhase( RJTimeLine timeLine, float duration, float offset = 0 )
{
var time = GetPosition( timeLine ) + offset;
return ( time % duration ) / duration;
}
public static float GetRangePhase( RJTimeLine timeLine, float start, float end )
{
var time = GetPosition( timeLine );
var normalized = MathX.Normalize( time, start, end );
return normalized;
}
2025-01-03 12:09:23 +00:00
2024-05-19 15:59:41 +00:00
public override void ScheduleEvent( int timeLineIndex, double position, int callbackID, bool isPersistent )
{
var runner = _runners[ timeLineIndex ];
runner.ScheduleEvent( position, callbackID, isPersistent );
}
public override void ScheduleSpan( int timeLineIndex, double start, double end, int callbackID, bool isPersistent )
{
var runner = _runners[ timeLineIndex ];
runner.ScheduleSpan( start, end, callbackID, isPersistent );
}
public override double GetLastPosition( int timeLineIndex )
{
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 0; }
return runner.lastPosition;
}
public override double GetPosition( int timeLineIndex )
{
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 0; }
return runner.position;
}
public override void SetPosition( int timeLineIndex, double position )
{
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return; }
runner.position = position;
}
public override double GetSpeed( int timeLineIndex )
{
2025-01-03 12:09:23 +00:00
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 1; }
2024-05-19 15:59:41 +00:00
return runner.speed;
}
2025-01-03 12:09:23 +00:00
public float GetModulatedSpeed( RJTimeLine timeline )
{
var timeLineIndex = GetTimeLineIndex( timeline );
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 1; }
return runner.modulatedSpeed;
}
public float GetSpeed( RJTimeLine timeline )
{
return (float) GetSpeed( GetTimeLineIndex( timeline ) );
}
2024-05-19 15:59:41 +00:00
public override void SetSpeed( int timeLineIndex, double speed )
{
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return; }
runner.speed = speed;
}
2025-01-03 12:09:23 +00:00
public void SetSpeed( RJTimeLine timeline, double speed )
{
SetSpeed( GetTimeLineIndex( timeline ), speed );
}
2024-05-19 15:59:41 +00:00
public override bool GetPlayState( int timeLineIndex )
{
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return false; }
return runner.playing;
}
public override void SetPlayState( int timeLineIndex, bool isPlaying )
{
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return; }
runner.playing = isPlaying;
}
}
}