232 lines
5.7 KiB
C#
232 lines
5.7 KiB
C#
|
|
using System.Diagnostics;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using Godot;
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public partial class TimeLineManager:RJTimeLineManager
|
|
{
|
|
[Export]
|
|
public RJTimeLine[] timeLines;
|
|
|
|
[Export]
|
|
public RJTimeLine engineTimeScale;
|
|
|
|
[Export]
|
|
public RJTimeLine realTimeTimeLine;
|
|
|
|
[Export]
|
|
public bool computeRealtimeWithEngineDelta;
|
|
|
|
|
|
List<TimeLineRunner> _runners = new List<TimeLineRunner>();
|
|
|
|
int _idCounter = 0;
|
|
bool _initialized = false;
|
|
|
|
public override void _Ready()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
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;
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
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 )
|
|
{
|
|
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 1; }
|
|
return runner.speed;
|
|
}
|
|
|
|
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 ) );
|
|
}
|
|
|
|
public override void SetSpeed( int timeLineIndex, double speed )
|
|
{
|
|
var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return; }
|
|
runner.speed = speed;
|
|
}
|
|
|
|
public void SetSpeed( RJTimeLine timeline, double speed )
|
|
{
|
|
SetSpeed( GetTimeLineIndex( timeline ), speed );
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
}
|
|
}
|
|
} |