using System.Collections; using Syntriax.Engine.Core; using Syntriax.Engine.Core.Abstract; namespace Syntriax.Engine.Systems.Tween; public class TweenManager : HierarchyObject { private CoroutineManager coroutineManager = null!; private readonly Dictionary runningCoroutines = []; public ITween StartTween(float duration, TweenSetCallback? setCallback = null) { Tween tween = new(duration); tween.OnUpdated += tween => setCallback?.Invoke(tween.Value); runningCoroutines.Add(tween, coroutineManager.StartCoroutine(RunTween(tween))); return tween; } private IEnumerator RunTween(Tween tween) { tween.State = TweenState.Playing; yield return null; while (true) { if (tween.State.CheckFlag(TweenState.Cancelled | TweenState.Completed)) break; if (tween.State.CheckFlag(TweenState.Paused)) { yield return null; continue; } tween.Counter += GameManager.Time.DeltaTime; yield return null; } runningCoroutines.Remove(tween); } public void CancelTween(ITween tween) { if (!runningCoroutines.TryGetValue(tween, out IEnumerator? runningCoroutine)) return; tween.State = TweenState.Cancelled; coroutineManager.StopCoroutine(runningCoroutine); runningCoroutines.Remove(tween); } protected override void OnEnteringHierarchy(IGameManager gameManager) { coroutineManager = gameManager.FindHierarchyObject() ?? throw new($"No {nameof(CoroutineManager)} was found in the game manager"); } protected override void OnExitingHierarchy(IGameManager gameManager) { coroutineManager = null!; } public delegate void TweenSetCallback(float t); }