using System.Collections.Generic;
namespace Watermelon
{
///
/// Tracks a group of objects and fires a single callback
/// when every tween in the group has finished — either by natural completion or by being killed.
///
/// Usage patterns:
///
/// - Manual: create a collection, call for each tween, then .
/// - Automatic: bracket tween creation with /
/// — all tweens created in between are auto-collected.
/// - Operator: use collection += tween to lazily create and populate a collection.
///
///
///
/// Kill-path correctness:
/// The collection subscribes to each tween's internal OnTerminated hook, which fires for both
/// and . This ensures the
/// callback is always invoked regardless of how individual tweens end.
///
///
public class TweenCaseCollection
{
private List tweenCases = new List();
/// All tweens registered in this collection.
public List TweenCases => tweenCases;
private SimpleCallback tweensCompleted;
///
/// Adds to the collection and subscribes to its termination event.
/// The termination hook fires for both and .
///
public void AddTween(TweenCase tweenCase)
{
// OnTerminated fires for both Complete() and Kill() — covers all termination paths
tweenCase.OnTerminated(OnTweenCaseTerminated);
tweenCases.Add(tweenCase);
}
///
/// Returns true if every tween in the collection is no longer active
/// (i.e. all have been completed or killed). An empty collection is considered complete.
///
public bool IsComplete()
{
// IsActive becomes false immediately on Kill() or Complete()->Kill(), so this is the
// single reliable "still running" check regardless of how the tween ended.
for (int i = 0; i < tweenCases.Count; i++)
{
if (tweenCases[i].IsActive)
return false;
}
return true;
}
/// Forces immediate completion of all tweens in the collection (applies final values and fires per-tween callbacks).
public void Complete()
{
for (int i = 0; i < tweenCases.Count; i++)
{
tweenCases[i].Complete();
}
}
/// Kills all tweens in the collection. Per-tween OnComplete callbacks are not fired, but the collection's callback is.
public void Kill()
{
for (int i = 0; i < tweenCases.Count; i++)
{
tweenCases[i].Kill();
}
}
///
/// Registers a callback to be invoked when all tweens in the collection finish (regardless of whether they complete or are killed).
/// Multiple calls accumulate callbacks (+= semantics).
///
public void OnComplete(SimpleCallback callback)
{
tweensCompleted += callback;
}
///
/// Called by each tween when it terminates. Checks whether all tweens have finished
/// and fires if so.
///
private void OnTweenCaseTerminated()
{
for (int i = 0; i < tweenCases.Count; i++)
{
if (tweenCases[i].IsActive)
return;
}
tweensCompleted?.Invoke();
}
///
/// Convenience operator: adds to ,
/// creating a new collection first if is null.
///
///
/// TweenCaseCollection group = null;
/// group += transform.DOMove(target, 0.5f);
/// group += spriteRenderer.DOFade(0f, 0.5f);
/// group.OnComplete(() => Debug.Log("all done"));
///
///
///
public static TweenCaseCollection operator +(TweenCaseCollection caseCollection, TweenCase tweenCase)
{
if(caseCollection == null)
caseCollection = new TweenCaseCollection();
caseCollection.AddTween(tweenCase);
return caseCollection;
}
}
}