Files
Syntriax.Engine/Engine.Systems/Tween/TweenManager.cs
Syntriax 988a6f67f2 BREAKING CHANGE: renamed original Behaviour class to BehaviourInternal, and replaced it with BehaviourBase
Original Behaviour was using old methods for detecting entering/exiting universe,
they are now all under the same hood and the original is kept for UniverseEntranceManager
because it needs to enter the universe without itself. The internal behaviour kept under
a subnamespace of "Core.Internal" for the purpose that it might come in handy for other use cases.
2025-10-22 16:50:19 +03:00

86 lines
2.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Engine.Core;
namespace Engine.Systems.Tween;
public class TweenManager : Behaviour, IEnterUniverse, IExitUniverse, ITweenManager
{
private CoroutineManager coroutineManager = null!;
private readonly Dictionary<ITween, IEnumerator> runningCoroutines = [];
private readonly Queue<Tween> pool = new();
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 (!pool.TryDequeue(out Tween? result))
result = new(duration);
result.Duration = duration;
return result;
}
private void Return(Tween tween)
{
if (pool.Contains(tween))
return;
tween.Wipe();
pool.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);
Return((Tween)tween);
}
public void EnterUniverse(IUniverse universe)
{
coroutineManager = universe.FindRequiredBehaviour<CoroutineManager>();
}
public void ExitUniverse(IUniverse universe)
{
coroutineManager = null!;
}
}