// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Linq; using osu.Framework.Bindables; namespace osu.Game.Beatmaps.ControlPoints { public class ControlPointGroup : IComparable, IEquatable { public event Action? ItemAdded; public event Action? ItemChanged; public event Action? ItemRemoved; private void raiseItemChanged(ControlPoint controlPoint) => ItemChanged?.Invoke(controlPoint); /// /// The time at which the control point takes effect. /// public double Time { get; } public IBindableList ControlPoints => controlPoints; private readonly BindableList controlPoints = new BindableList(); public ControlPointGroup(double time) { Time = time; } public int CompareTo(ControlPointGroup? other) => Time.CompareTo(other?.Time); public void Add(ControlPoint point) { var existing = controlPoints.FirstOrDefault(p => p.GetType() == point.GetType()); if (existing != null) Remove(existing); point.AttachGroup(this); controlPoints.Add(point); ItemAdded?.Invoke(point); point.Changed += raiseItemChanged; } public void Remove(ControlPoint point) { controlPoints.Remove(point); ItemRemoved?.Invoke(point); point.Changed -= raiseItemChanged; } public sealed override bool Equals(object? obj) => obj is ControlPointGroup otherGroup && Equals(otherGroup); public virtual bool Equals(ControlPointGroup? other) => other != null && Time == other.Time && ControlPoints.SequenceEqual(other.ControlPoints); public override int GetHashCode() { HashCode hashCode = new HashCode(); hashCode.Add(Time); foreach (var point in controlPoints) hashCode.Add(point); return hashCode.ToHashCode(); } } }