diff --git a/src/BizHawk.Client.Common/controllers/ClickyVirtualPadController.cs b/src/BizHawk.Client.Common/controllers/ClickyVirtualPadController.cs index bc3f223d39..5f2ea15e54 100644 --- a/src/BizHawk.Client.Common/controllers/ClickyVirtualPadController.cs +++ b/src/BizHawk.Client.Common/controllers/ClickyVirtualPadController.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; + +using BizHawk.Common.CollectionExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -33,27 +35,9 @@ namespace BizHawk.Client.Common public void Click(string button) => _pressed.Add(button); public void Toggle(string button) - { - if (IsPressed(button)) - { - _pressed.Remove(button); - } - else - { - _pressed.Add(button); - } - } + => _ = _pressed.ToggleMembership(button); public void SetBool(string button, bool value) - { - if (value) - { - _pressed.Remove(button); - } - else - { - _pressed.Add(button); - } - } + => _pressed.SetMembership(button, shouldBeMember: !value); } } diff --git a/src/BizHawk.Client.Common/controllers/StickyControllers.cs b/src/BizHawk.Client.Common/controllers/StickyControllers.cs index 6baef48d69..49d1eedca4 100644 --- a/src/BizHawk.Client.Common/controllers/StickyControllers.cs +++ b/src/BizHawk.Client.Common/controllers/StickyControllers.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; +using BizHawk.Common.CollectionExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -37,16 +38,7 @@ namespace BizHawk.Client.Common public void SetHapticChannelStrength(string name, int strength) => throw new NotSupportedException(); public void SetButtonHold(string button, bool enabled) - { - if (enabled) - { - _buttonHolds.Add(button); - } - else - { - _buttonHolds.Remove(button); - } - } + => _buttonHolds.SetMembership(button, shouldBeMember: enabled); public void SetAxisHold(string name, int? value) { @@ -74,14 +66,7 @@ namespace BizHawk.Client.Common { foreach (var button in buttons.Where(button => !_justPressed.Contains(button))) { - if (_buttonHolds.Contains(button)) - { - _buttonHolds.Remove(button); - } - else - { - _buttonHolds.Add(button); - } + _ = _buttonHolds.ToggleMembership(button); } _justPressed = buttons; diff --git a/src/BizHawk.Client.EmuHawk/Input/Input.cs b/src/BizHawk.Client.EmuHawk/Input/Input.cs index 3b20a9977e..9a692e5e41 100644 --- a/src/BizHawk.Client.EmuHawk/Input/Input.cs +++ b/src/BizHawk.Client.EmuHawk/Input/Input.cs @@ -20,8 +20,7 @@ namespace BizHawk.Client.EmuHawk /// public void ControlInputFocus(Control c, HostInputType types, bool wants) { - if (types.HasFlag(HostInputType.Mouse) && wants) _wantingMouseFocus.Add(c); - if (types.HasFlag(HostInputType.Mouse) && !wants) _wantingMouseFocus.Remove(c); + if (types.HasFlag(HostInputType.Mouse)) _wantingMouseFocus.SetMembership(c, shouldBeMember: wants); } private readonly HashSet _wantingMouseFocus = new HashSet(); diff --git a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs index 67dda4c144..52cb5362a3 100644 --- a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs +++ b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs @@ -2085,13 +2085,9 @@ namespace BizHawk.Client.EmuHawk { ClearHighlighted(); } - else if (_secondaryHighlightedAddresses.Contains(pointedAddress)) - { - _secondaryHighlightedAddresses.Remove(pointedAddress); - } else { - _secondaryHighlightedAddresses.Add(pointedAddress); + _ = _secondaryHighlightedAddresses.ToggleMembership(pointedAddress); } } else if ((ModifierKeys & Keys.Shift) == Keys.Shift) diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs index 0b49666a2b..12785bf0e6 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs @@ -992,14 +992,7 @@ namespace BizHawk.Client.EmuHawk TasView.SelectRow(i, _selectionDragState); if (AxisEditingMode && (ModifierKeys == Keys.Control || ModifierKeys == Keys.Shift)) { - if (_selectionDragState) - { - _extraAxisRows.Add(i); - } - else - { - _extraAxisRows.Remove(i); - } + _extraAxisRows.SetMembership(i, shouldBeMember: _selectionDragState); } } diff --git a/src/BizHawk.Common/Extensions/CollectionExtensions.cs b/src/BizHawk.Common/Extensions/CollectionExtensions.cs index 934e5ad109..775be9d8f4 100644 --- a/src/BizHawk.Common/Extensions/CollectionExtensions.cs +++ b/src/BizHawk.Common/Extensions/CollectionExtensions.cs @@ -377,6 +377,30 @@ namespace BizHawk.Common.CollectionExtensions => source.OrderByDescending(ReturnSelf); #endif + /// iff any removed + public static bool RemoveAll(this ICollection collection, T item) + { + if (collection is ISet) return collection.Remove(item); +#if false // probably not worth it, would need to benchmark + if (collection is IList list) + { + // remove from end + var i = list.LastIndexOf(item); + if (i < 0) return false; + do + { + list.RemoveAt(i); + i = list.LastIndexOf(item); + } + while (i < 0); + return true; + } +#endif + if (!collection.Remove(item)) return false; + while (collection.Remove(item)) {/*noop*/} + return true; + } + /// /// /// (This is an extension method which reimplements for other collections. @@ -423,6 +447,20 @@ namespace BizHawk.Common.CollectionExtensions return true; } + /// + /// if is , + /// removes every copy of from ; + /// else if is + /// and is not present in , appends one copy; + /// else no-op (does not limit to one copy) + /// + public static void SetMembership(this ICollection collection, T item, bool shouldBeMember) + { + if (!shouldBeMember) _ = collection.RemoveAll(item); + else if (!collection.Contains(item)) collection.Add(item); + // else noop + } + public static ReadOnlySpan Slice(this ReadOnlySpan span, Range range) { var (offset, length) = range.GetOffsetAndLength(span.Length); @@ -447,6 +485,18 @@ namespace BizHawk.Common.CollectionExtensions => list.ToDictionary(static kvp => kvp.Key, static kvp => kvp.Value); #endif + /// + /// if contains , removes every copy; + /// otherwise appends one copy + /// + /// new membership state ( iff added) + public static bool ToggleMembership(this ICollection collection, T item) + { + var removed = collection.RemoveAll(item); + if (!removed) collection.Add(item); + return removed; + } + public static bool IsSortedAsc(this IReadOnlyList list) where T : IComparable { diff --git a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.ComponentModel.cs b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.ComponentModel.cs index 44f1b88b0e..9c137f9bfd 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.ComponentModel.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.ComponentModel.cs @@ -2,6 +2,9 @@ using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; + +using BizHawk.Common.CollectionExtensions; + using NymaTypes; using static BizHawk.Emulation.Cores.Waterbox.NymaCore; using static BizHawk.Emulation.Cores.Waterbox.NymaCore.NymaSettingsInfo; @@ -418,12 +421,7 @@ namespace BizHawk.Emulation.Cores.Waterbox } public override void SetValue(object component, object value) - { - if ((bool)value) - ((NymaSettings)component).DisabledLayers.Remove(LayerName); - else - ((NymaSettings)component).DisabledLayers.Add(LayerName); - } + => ((NymaSettings) component).DisabledLayers.SetMembership(LayerName, shouldBeMember: !((bool) value)); public override bool ShouldSerializeValue(object component) {