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(); } } } }