// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Caching; using osu.Framework.Graphics; using System; using System.Collections.Generic; using System.Linq; namespace osu.Game.Storyboards { public class CommandTimeline : ICommandTimeline { private readonly List commands = new List(); public IEnumerable Commands => commands.OrderBy(c => c.StartTime); public bool HasCommands => commands.Count > 0; private Cached startTimeBacking; public double StartTime => startTimeBacking.IsValid ? startTimeBacking : (startTimeBacking.Value = HasCommands ? commands.Min(c => c.StartTime) : double.MinValue); private Cached endTimeBacking; public double EndTime => endTimeBacking.IsValid ? endTimeBacking : (endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue); public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default(T); public T EndValue => HasCommands ? commands.OrderByDescending(c => c.EndTime).First().EndValue : default(T); public void Add(Easing easing, double startTime, double endTime, T startValue, T endValue) { if (endTime < startTime) return; commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue, }); startTimeBacking.Invalidate(); endTimeBacking.Invalidate(); } public override string ToString() => $"{commands.Count} command(s)"; public class TypedCommand : ICommand { public Easing Easing { get; set; } public double StartTime { get; set; } public double EndTime { get; set; } public double Duration => EndTime - StartTime; public T StartValue; public T EndValue; public int CompareTo(ICommand other) { var result = StartTime.CompareTo(other.StartTime); if (result != 0) return result; return EndTime.CompareTo(other.EndTime); } public override string ToString() => $"{StartTime} -> {EndTime}, {StartValue} -> {EndValue} {Easing}"; } } public interface ICommandTimeline { double StartTime { get; } double EndTime { get; } bool HasCommands { get; } } public interface ICommand : IComparable { Easing Easing { get; set; } double StartTime { get; set; } double EndTime { get; set; } double Duration { get; } } }