// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; using System.Collections.Immutable; using osu.Framework.Input.StateChanges.Events; using osu.Framework.Input.States; namespace osu.Framework.Input.StateChanges { /// /// An abstract base class of an which denotes a list of button state changes (pressed or released). /// /// The type of button. public abstract class ButtonInput : IInput where TButton : struct { public ImmutableArray> Entries; protected ButtonInput(IEnumerable> entries) { Entries = entries.ToImmutableArray(); } /// /// Creates a with a single state. /// /// The to add. /// The state of . protected ButtonInput(TButton button, bool isPressed) { Entries = ImmutableArray.Create(new ButtonInputEntry(button, isPressed)); } /// /// Creates a from the difference of two . /// /// /// Buttons that are pressed in and not pressed in will be listed as . /// Buttons that are not pressed in and pressed in will be listed as . /// /// The newer . /// The older . protected ButtonInput(ButtonStates current, ButtonStates previous) { var difference = (current ?? new ButtonStates()).EnumerateDifference(previous ?? new ButtonStates()); var builder = ImmutableArray.CreateBuilder>(difference.Released.Length + difference.Pressed.Length); foreach (var button in difference.Released) builder.Add(new ButtonInputEntry(button, false)); foreach (var button in difference.Pressed) builder.Add(new ButtonInputEntry(button, true)); Entries = builder.MoveToImmutable(); } /// /// Retrieves the from an . /// protected abstract ButtonStates GetButtonStates(InputState state); /// /// Create a state change event. /// /// The which changed. /// The that changed. /// The type of change that occurred on . protected virtual ButtonStateChangeEvent CreateEvent(InputState state, TButton button, ButtonStateChangeKind kind) => new ButtonStateChangeEvent(state, this, button, kind); public virtual void Apply(InputState state, IInputStateChangeHandler handler) { if (Entries.Length == 0) return; var buttonStates = GetButtonStates(state); foreach (var entry in Entries) { if (buttonStates.SetPressed(entry.Button, entry.IsPressed)) { var buttonStateChange = CreateEvent(state, entry.Button, entry.IsPressed ? ButtonStateChangeKind.Pressed : ButtonStateChangeKind.Released); handler.HandleInputStateChange(buttonStateChange); } } } } }