using Syntriax.Engine.Core; namespace Syntriax.Engine.Systems.Tween; internal class Tween : ITween { public Event OnStarted { get; } = new(); public Event OnPaused { get; } = new(); public Event OnResumed { get; } = new(); public Event OnCancelled { get; } = new(); public Event OnCompleted { get; } = new(); public Event OnEnded { get; } = new(); public Event OnUpdated { get; } = new(); public Event OnDeltaUpdated { get; } = new(); 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; } = EaseLinear.Instance; 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, new(Easing.Evaluate(Progress) - Easing.Evaluate(previousProgress))); if (_counter >= Duration) State = TweenState.Completed; } } internal void Reset() { OnStarted.Clear(); OnPaused.Clear(); OnResumed.Clear(); OnCancelled.Clear(); OnCompleted.Clear(); OnEnded.Clear(); OnUpdated.Clear(); OnDeltaUpdated.Clear(); _counter = 0f; Progress = 0f; State = TweenState.Idle; } public Tween() { } public Tween(float duration) { Duration = duration; } }