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.
86 lines
2.2 KiB
C#
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!;
|
|
}
|
|
}
|