2025-05-30 20:55:09 +03:00

85 lines
2.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Syntriax.Engine.Core;
namespace Syntriax.Engine.Systems.Tween;
public class TweenManager : UniverseObject, ITweenManager
{
private CoroutineManager coroutineManager = null!;
private readonly Queue<Tween> queue = new();
private readonly Dictionary<ITween, IEnumerator> runningCoroutines = [];
public ITween StartTween(float duration, ITweenManager.TweenSetCallback? setCallback = null)
{
Tween tween = Get(duration);
tween.OnUpdated.AddListener(tween => setCallback?.Invoke(tween.Value));
runningCoroutines.Add(tween, coroutineManager.StartCoroutine(RunTween(tween)));
return tween;
}
private Tween Get(float duration)
{
if (!queue.TryDequeue(out Tween? result))
result = new(duration);
result.Duration = duration;
return result;
}
private void Return(Tween tween)
{
if (queue.Contains(tween))
return;
tween.Reset();
queue.Enqueue(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 += Universe.Time.DeltaTime;
yield return null;
}
runningCoroutines.Remove(tween);
Return(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 OnEnteringUniverse(IUniverse universe)
{
coroutineManager = universe.GetRequiredUniverseObject<CoroutineManager>();
}
protected override void OnExitingUniverse(IUniverse universe)
{
coroutineManager = null!;
}
}