83 lines
2.4 KiB
C#

using Syntriax.Engine.Core;
namespace Syntriax.Engine.Systems.Tween;
internal class Tween : ITween
{
public event ITween.TweenEventHandler? OnStarted = null;
public event ITween.TweenEventHandler? OnPaused = null;
public event ITween.TweenEventHandler? OnResumed = null;
public event ITween.TweenEventHandler? OnCancelled = null;
public event ITween.TweenEventHandler? OnCompleted = null;
public event ITween.TweenEventHandler? OnEnded = null;
public event ITween.TweenEventHandler? OnUpdated = null;
public event ITween.TweenDeltaEventHandler? OnDeltaUpdated = null;
private TweenState _state = TweenState.Idle;
public TweenState State
{
get => _state;
set
{
if (value == _state)
return;
TweenState previousState = _state;
_state = value;
switch (value)
{
case TweenState.Completed: OnCompleted?.Invoke(this); OnEnded?.Invoke(this); break;
case TweenState.Cancelled: OnCancelled?.Invoke(this); OnEnded?.Invoke(this); break;
case TweenState.Paused: OnPaused?.Invoke(this); break;
case TweenState.Playing:
if (previousState == TweenState.Idle)
OnStarted?.Invoke(this);
else
OnResumed?.Invoke(this);
break;
}
}
}
public float Duration { get; internal set; } = 1f;
public float Progress { get; internal set; } = 0f;
private float _counter = 0f;
public IEasing Easing { get; set; } = new EaseLinear();
public float Value => Easing.Evaluate(Progress);
public float Counter
{
get => _counter;
set
{
if (value < _counter)
return;
float previousProgress = Progress;
_counter = value.Min(Duration).Max(0f);
Progress = Counter / Duration;
OnUpdated?.Invoke(this);
OnDeltaUpdated?.Invoke(this, Easing.Evaluate(Progress) - Easing.Evaluate(previousProgress));
if (_counter >= Duration)
State = TweenState.Completed;
}
}
internal void Reset()
{
_counter = 0f;
Progress = 0f;
State = TweenState.Idle;
}
public Tween() { }
public Tween(float duration)
{
Duration = duration;
}
}