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; } }