using System.Collections.Generic;
using System.Diagnostics;
using GTweens.Tweens;
namespace GTweens.Contexts
{
///
/// Manages and updates a collection of GTweens.
///
public sealed class GTweensContext
{
///
/// Gets or sets the time scale at which the tweens should play.
///
public float TimeScale { get; set; } = 1f;
///
/// Gets the duration of the last tweens tick in milliseconds.
///
public float TickDurationMs { get; private set; }
readonly List _aliveTweens = new();
readonly List _tweensToAdd = new();
readonly List _tweensToRemove = new();
readonly Stopwatch _updateStopwatch = new();
///
/// Plays a GTween within the context.
///
/// The GTween to play.
public void Play(GTween gTween)
{
if(gTween.IsNested)
{
return;
}
if(gTween.IsAlive)
{
TryStartTween(gTween);
return;
}
gTween.IsAlive = true;
_tweensToAdd.Add(gTween);
TryStartTween(gTween);
}
///
/// Updates the context and all managed tweens.
///
/// The elapsed time since the last update in seconds.
public void Tick(float deltaTime)
{
float scaledDeltaTime = deltaTime * TimeScale;
_updateStopwatch.Restart();
foreach(GTween tween in _tweensToAdd)
{
_aliveTweens.Add(tween);
}
_tweensToAdd.Clear();
foreach (GTween tween in _aliveTweens)
{
if(tween.IsPlaying)
{
tween.Tick(scaledDeltaTime);
}
else
{
_tweensToRemove.Add(tween);
}
}
foreach(GTween tween in _tweensToRemove)
{
tween.IsAlive = false;
_aliveTweens.Remove(tween);
_tweensToAdd.Remove(tween);
}
_tweensToRemove.Clear();
_updateStopwatch.Stop();
TickDurationMs = _updateStopwatch.ElapsedMilliseconds;
}
///
/// Clears all tweens from the context.
///
public void Clear()
{
_aliveTweens.Clear();
_tweensToAdd.Clear();
_tweensToRemove.Clear();
}
void TryStartTween(GTween gTween)
{
if (!gTween.IsPlaying)
{
gTween.Start();
}
}
}
}