Skip to content

Commit

Permalink
Add and use Insert{Before,After}{,Last} helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
YoshiRulz committed Mar 5, 2025
1 parent 7d876de commit 957029f
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/BizHawk.Client.Common/DisplayManager/FilterManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ public void Compile(string channel, Size inSize, Size outsize, bool finalTarget)
if (currState.SurfaceDisposition == SurfaceDisposition.Texture)
{
var renderer = new Render();
Filters.Insert(Filters.Count, renderer);
Filters.Add(renderer);
Compile(channel, inSize, outsize, finalTarget);
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using BizHawk.Common;
using BizHawk.Common.IOExtensions;
using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common;

namespace BizHawk.Client.Common
Expand All @@ -21,8 +22,7 @@ public void SaveBackup()
return;
}

var backupName = Filename;
backupName = backupName.Insert(Filename.LastIndexOf('.'), $".{DateTime.Now:yyyy-MM-dd HH.mm.ss}");
var backupName = Filename.InsertBeforeLast('.', insert: $".{DateTime.Now:yyyy-MM-dd HH.mm.ss}", out _);
backupName = Path.Combine(Session.BackupDirectory, Path.GetFileName(backupName));

Write(backupName, isBackup: true);
Expand Down
16 changes: 16 additions & 0 deletions src/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable

using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
Expand All @@ -12,6 +13,7 @@

using BizHawk.Client.Common;
using BizHawk.Common;
using BizHawk.Common.CollectionExtensions;
using BizHawk.Common.ReflectionExtensions;
using BizHawk.Emulation.Common;

Expand Down Expand Up @@ -158,6 +160,20 @@ public static IEnumerable<TabPage> TabPages(this TabControl tabControl)
return tabControl.TabPages.Cast<TabPage>();
}

#pragma warning disable CS0618 // WinForms doesn't use generics ofc
public static bool InsertAfter(this ToolStripItemCollection items, ToolStripItem needle, ToolStripItem insert)
=> ((IList) items).InsertAfter(needle, insert: insert);

public static bool InsertAfterLast(this ToolStripItemCollection items, ToolStripItem needle, ToolStripItem insert)
=> ((IList) items).InsertAfterLast(needle, insert: insert);

public static bool InsertBefore(this ToolStripItemCollection items, ToolStripItem needle, ToolStripItem insert)
=> ((IList) items).InsertBefore(needle, insert: insert);

public static bool InsertBeforeLast(this ToolStripItemCollection items, ToolStripItem needle, ToolStripItem insert)
=> ((IList) items).InsertBeforeLast(needle, insert: insert);
#pragma warning restore CS0618

public static void ReplaceDropDownItems(this ToolStripDropDownItem menu, params ToolStripItem[] items)
{
menu.DropDownItems.Clear();
Expand Down
12 changes: 5 additions & 7 deletions src/BizHawk.Client.EmuHawk/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ private void MainForm_Load(object sender, EventArgs e)
#if BIZHAWKBUILD_SUPERHAWK
ToolStripMenuItemEx superHawkThrottleMenuItem = new() { Text = "SUPER·HAWK" };
superHawkThrottleMenuItem.Click += (_, _) => Config.SuperHawkThrottle = !Config.SuperHawkThrottle;
SpeedSkipSubMenu.DropDownItems.Insert(
SpeedSkipSubMenu.DropDownItems.IndexOf(MinimizeSkippingMenuItem),
superHawkThrottleMenuItem);
_ = SpeedSkipSubMenu.DropDownItems.InsertBefore(MinimizeSkippingMenuItem, insert: superHawkThrottleMenuItem);
ConfigSubMenu.DropDownOpened += (_, _) => superHawkThrottleMenuItem.Checked = Config.SuperHawkThrottle;
#endif

Expand Down Expand Up @@ -159,9 +157,9 @@ private void MainForm_Load(object sender, EventArgs e)
submenu.Enabled = false;
}
}
ConfigSubMenu.DropDownItems.Insert(
ConfigSubMenu.DropDownItems.IndexOf(CoresSubMenu) + 1,
new ToolStripMenuItemEx
_ = ConfigSubMenu.DropDownItems.InsertAfter(
CoresSubMenu,
insert: new ToolStripMenuItemEx
{
DropDownItems =
{
Expand All @@ -175,7 +173,7 @@ private void MainForm_Load(object sender, EventArgs e)
Text = "Core Settings",
});

MainformMenu.Items.Insert(MainformMenu.Items.IndexOf(ToolsSubMenu) + 1, NullHawkVSysSubmenu);
_ = MainformMenu.Items.InsertAfter(ToolsSubMenu, insert: NullHawkVSysSubmenu);

// Hide Status bar icons and general StatusBar prep
MainStatusBar.Padding = new Padding(MainStatusBar.Padding.Left, MainStatusBar.Padding.Top, MainStatusBar.Padding.Left, MainStatusBar.Padding.Bottom); // Workaround to remove extra padding on right
Expand Down
4 changes: 1 addition & 3 deletions src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,7 @@ public TAStudio()
};
if (this.ShowDialogWithTempMute(dialog).IsOk()) GoToFrame(int.Parse(dialog.PromptText));
};
EditSubMenu.DropDownItems.Insert(
EditSubMenu.DropDownItems.IndexOf(ReselectClipboardMenuItem) + 1,
goToFrameMenuItem);
_ = EditSubMenu.DropDownItems.InsertAfter(ReselectClipboardMenuItem, insert: goToFrameMenuItem);

RecentSubMenu.Image = Resources.Recent;
recentMacrosToolStripMenuItem.Image = Resources.Recent;
Expand Down
2 changes: 1 addition & 1 deletion src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public RamWatch()
i++;
}
};
WatchesSubMenu.DropDownItems.Insert(11, deduperMenuItem);
_ = WatchesSubMenu.DropDownItems.InsertBefore(toolStripSeparator3, insert: deduperMenuItem);

Settings = new RamWatchSettings();

Expand Down
109 changes: 109 additions & 0 deletions src/BizHawk.Common/Extensions/CollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ namespace BizHawk.Common.CollectionExtensions
public static class CollectionExtensions
#pragma warning restore MA0104
{
private const string ERR_MSG_IMMUTABLE_LIST = "immutable list passed to mutating method";

private const string WARN_NONGENERIC = "use generic overload";

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Expand Down Expand Up @@ -247,6 +251,111 @@ public static int IndexOf<T>(this IReadOnlyList<T> list, T elem)
return -1;
}

public static bool InsertAfter<T>(this IList<T> list, T needle, T insert)
{
Debug.Assert(!list.IsReadOnly, ERR_MSG_IMMUTABLE_LIST);
var insertPoint = list.IndexOf(needle);
if (insertPoint < 0) return false;
list.Insert(insertPoint + 1, insert);
return true;
}

[Obsolete(WARN_NONGENERIC)]
public static bool InsertAfter<T>(this IList list, T needle, T insert)
{
Debug.Assert(!list.IsReadOnly, ERR_MSG_IMMUTABLE_LIST);
var insertPoint = list.IndexOf(needle);
if (insertPoint < 0) return false;
list.Insert(insertPoint + 1, insert);
return true;
}

public static bool InsertAfterLast<T>(this IList<T> list, T needle, T insert)
{
Debug.Assert(!list.IsReadOnly, ERR_MSG_IMMUTABLE_LIST);
var insertPoint = list.LastIndexOf(needle);
if (insertPoint < 0) return false;
list.Insert(insertPoint + 1, insert);
return true;
}

[Obsolete(WARN_NONGENERIC)]
public static bool InsertAfterLast<T>(this IList list, T needle, T insert)
{
Debug.Assert(!list.IsReadOnly, ERR_MSG_IMMUTABLE_LIST);
var insertPoint = list.LastIndexOf(needle);
if (insertPoint < 0) return false;
list.Insert(insertPoint + 1, insert);
return true;
}

public static bool InsertBefore<T>(this IList<T> list, T needle, T insert)
{
Debug.Assert(!list.IsReadOnly, ERR_MSG_IMMUTABLE_LIST);
var insertPoint = list.IndexOf(needle);
if (insertPoint < 0) return false;
list.Insert(insertPoint, insert);
return true;
}

[Obsolete(WARN_NONGENERIC)]
public static bool InsertBefore<T>(this IList list, T needle, T insert)
{
Debug.Assert(!list.IsReadOnly, ERR_MSG_IMMUTABLE_LIST);
var insertPoint = list.IndexOf(needle);
if (insertPoint < 0) return false;
list.Insert(insertPoint, insert);
return true;
}

public static bool InsertBeforeLast<T>(this IList<T> list, T needle, T insert)
{
Debug.Assert(!list.IsReadOnly, ERR_MSG_IMMUTABLE_LIST);
var insertPoint = list.LastIndexOf(needle);
if (insertPoint < 0) return false;
list.Insert(insertPoint, insert);
return true;
}

[Obsolete(WARN_NONGENERIC)]
public static bool InsertBeforeLast<T>(this IList list, T needle, T insert)
{
Debug.Assert(!list.IsReadOnly, ERR_MSG_IMMUTABLE_LIST);
var insertPoint = list.LastIndexOf(needle);
if (insertPoint < 0) return false;
list.Insert(insertPoint, insert);
return true;
}

public static int LastIndexOf<T>(this IList<T> list, T item)
{
if (list is T[] arr) return Array.LastIndexOf(arr, item);
if (list is List<T> bclList) return bclList.LastIndexOf(item);
if (item is null)
{
for (var i = list.Count - 1; i >= 0; i--) if (list[i] is null) return i;
}
else
{
for (var i = list.Count - 1; i >= 0; i--) if (item.Equals(list[i])) return i;
}
return -1;
}

[Obsolete(WARN_NONGENERIC)]
public static int LastIndexOf(this IList list, object? item)
{
if (item is null)
{
for (var i = list.Count - 1; i >= 0; i--) if (list[i] is null) return i;
}
else
{
for (var i = list.Count - 1; i >= 0; i--) if (item.Equals(list[i])) return i;
}
return -1;
}

public static T? FirstOrNull<T>(this IEnumerable<T> list, Func<T, bool> predicate)
where T : struct
{
Expand Down
28 changes: 28 additions & 0 deletions src/BizHawk.Common/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,34 @@ public static bool EqualsIgnoreCase(this string str, string other)
public static bool In(this string str, params string[] options)
=> options.Any(str.EqualsIgnoreCase);

public static string InsertAfter(this string str, char needle, string insert, out bool found)
{
var insertPoint = str.IndexOf(needle);
found = insertPoint >= 0;
return found ? str.Insert(insertPoint + 1, insert) : str;
}

public static string InsertAfterLast(this string str, char needle, string insert, out bool found)
{
var insertPoint = str.LastIndexOf(needle);
found = insertPoint >= 0;
return found ? str.Insert(insertPoint + 1, insert) : str;
}

public static string InsertBefore(this string str, char needle, string insert, out bool found)
{
var insertPoint = str.IndexOf(needle);
found = insertPoint >= 0;
return found ? str.Insert(insertPoint, insert) : str;
}

public static string InsertBeforeLast(this string str, char needle, string insert, out bool found)
{
var insertPoint = str.LastIndexOf(needle);
found = insertPoint >= 0;
return found ? str.Insert(insertPoint, insert) : str;
}

/// <returns>a copy of <paramref name="raw"/> with all characters outside <c>[0-9A-Za-z]</c> removed</returns>
public static string OnlyAlphanumeric(this string raw)
=> string.Concat(raw.Where(static c => c is (>= '0' and <= '9') or (>= 'A' and <= 'Z') or (>= 'a' and <= 'z')));
Expand Down

0 comments on commit 957029f

Please sign in to comment.