2026-07-25 15:24:59 -05:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.Iris.Render.OpenGL
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2026-07-25 21:37:32 -05:00
|
|
|
/// Shared state machine for animations: play/pause/reset, repeat and the async-notify
|
|
|
|
|
/// event. Time evaluation lives in the concrete subclasses (see <see cref="GLKeyframeAnimation"/>).
|
2026-07-25 15:24:59 -05:00
|
|
|
/// </summary>
|
|
|
|
|
public abstract class GLAnimation : SharedRenderObject, IAnimation
|
|
|
|
|
{
|
|
|
|
|
public int RepeatCount { get; set; }
|
2026-07-25 21:37:32 -05:00
|
|
|
public bool IsPlaying { get; protected set; }
|
|
|
|
|
public bool IsActive { get; protected set; }
|
2026-07-25 15:24:59 -05:00
|
|
|
public bool AutoReset { get; set; }
|
|
|
|
|
public AnimationResetBehavior ResetBehavior { get; set; } = AnimationResetBehavior.LeaveCurrent;
|
|
|
|
|
|
|
|
|
|
public event AsyncNotifyHandler? AsyncNotifyEvent;
|
|
|
|
|
|
|
|
|
|
public virtual void Play()
|
|
|
|
|
{
|
|
|
|
|
IsPlaying = true;
|
|
|
|
|
IsActive = true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-25 21:37:32 -05:00
|
|
|
public virtual void Pause()
|
|
|
|
|
{
|
|
|
|
|
if (IsActive)
|
|
|
|
|
IsPlaying = false;
|
|
|
|
|
}
|
2026-07-25 15:24:59 -05:00
|
|
|
|
|
|
|
|
public virtual void Reset()
|
|
|
|
|
{
|
|
|
|
|
IsPlaying = false;
|
|
|
|
|
IsActive = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual void InstantAdvance(float advanceTime) { }
|
|
|
|
|
|
|
|
|
|
public virtual void InstantFinish()
|
|
|
|
|
{
|
|
|
|
|
IsPlaying = false;
|
|
|
|
|
IsActive = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void RaiseAsyncNotify(int cookie) => AsyncNotifyEvent?.Invoke(cookie);
|
|
|
|
|
|
2026-07-25 21:37:32 -05:00
|
|
|
/// <summary>Advance internal time by <paramref name="advanceMs"/>. Driven by the system's pulse.</summary>
|
|
|
|
|
internal abstract void Advance(int advanceMs);
|
2026-07-25 15:24:59 -05:00
|
|
|
}
|
|
|
|
|
|
2026-07-25 21:37:32 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Aggregates child animations and drives them together. The public API exposes no way
|
|
|
|
|
/// to add members (IAnimationGroup has no members beyond IAnimation), so membership is
|
|
|
|
|
/// only available internally; kept for lifecycle parity.
|
|
|
|
|
/// </summary>
|
2026-07-25 15:24:59 -05:00
|
|
|
public sealed class GLAnimationGroup : GLAnimation, IAnimationGroup
|
|
|
|
|
{
|
|
|
|
|
private readonly List<GLAnimation> m_members = new List<GLAnimation>();
|
|
|
|
|
|
|
|
|
|
public override void Play()
|
|
|
|
|
{
|
|
|
|
|
base.Play();
|
2026-07-25 21:37:32 -05:00
|
|
|
foreach (GLAnimation a in m_members)
|
2026-07-25 15:24:59 -05:00
|
|
|
a.Play();
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-25 21:37:32 -05:00
|
|
|
public override void Pause()
|
|
|
|
|
{
|
|
|
|
|
base.Pause();
|
|
|
|
|
foreach (GLAnimation a in m_members)
|
|
|
|
|
a.Pause();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Reset()
|
|
|
|
|
{
|
|
|
|
|
base.Reset();
|
|
|
|
|
foreach (GLAnimation a in m_members)
|
|
|
|
|
a.Reset();
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-25 15:24:59 -05:00
|
|
|
internal void Add(GLAnimation animation) => m_members.Add(animation);
|
|
|
|
|
|
|
|
|
|
internal override void Advance(int advanceMs)
|
|
|
|
|
{
|
2026-07-25 21:37:32 -05:00
|
|
|
foreach (GLAnimation a in m_members)
|
|
|
|
|
if (a.IsPlaying)
|
|
|
|
|
a.Advance(advanceMs);
|
2026-07-25 15:24:59 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|