From 3b3bb266fc3ea615aec756492587cf98b48db6f9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 29 Jan 2026 02:31:24 +0900 Subject: [PATCH] Rewrite everything for code quality's sake --- .../Overlays/Settings/Sections/SkinSection.cs | 4 +- osu.Game/Skinning/SkinManager.cs | 84 ++++++++----------- 2 files changed, 37 insertions(+), 51 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 8cd1dfe5b2..84cfff6d1f 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -117,9 +117,7 @@ namespace osu.Game.Overlays.Settings.Sections return; // For simplicity repopulate the full list. dropdownItems.Clear(); - - var items = skins.GetAllUsableSkins().ToArray(); - dropdownItems.AddRange(items); + dropdownItems.AddRange(skins.GetAllUsableSkins()); Schedule(() => skinDropdown.Items = dropdownItems); } diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 0d8220009d..dfb5497542 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Threading; @@ -66,6 +67,12 @@ namespace osu.Game.Skinning private Skin retroSkin { get; } + private static readonly Live random_skin_info = new SkinInfo + { + ID = SkinInfo.RANDOM_SKIN, + Name = "", + }.ToLiveUnmanaged(); + public override bool PauseImports { get => base.PauseImports; @@ -135,37 +142,31 @@ namespace osu.Game.Skinning /// Inserts the defaults first, then 'random skin', then custom ones. /// Returns a list of items. /// - public IEnumerable> GetAllUsableSkins() + public IList> GetAllUsableSkins() { - var results = new List>(); + var skins = new List>(); - Realm.Run(r => + Realm.Run(realm => { - var all = r.All() - .Where(s => !s.DeletePending) - .OrderBy(s => s.Name, StringComparer.OrdinalIgnoreCase) - .ToArray(); + skins.Add(realm.Find(SkinInfo.ARGON_SKIN).ToLive(Realm)); + skins.Add(realm.Find(SkinInfo.ARGON_PRO_SKIN).ToLive(Realm)); + skins.Add(realm.Find(SkinInfo.TRIANGLES_SKIN).ToLive(Realm)); + skins.Add(realm.Find(SkinInfo.CLASSIC_SKIN).ToLive(Realm)); + skins.Add(realm.Find(SkinInfo.RETRO_SKIN).ToLive(Realm)); - // add defaults in fixed order (assumes they exist in the DB) - results.Add(all.Single(s => s.ID == SkinInfo.ARGON_SKIN).ToLive(Realm)); - results.Add(all.Single(s => s.ID == SkinInfo.ARGON_PRO_SKIN).ToLive(Realm)); - results.Add(all.Single(s => s.ID == SkinInfo.TRIANGLES_SKIN).ToLive(Realm)); - results.Add(all.Single(s => s.ID == SkinInfo.CLASSIC_SKIN).ToLive(Realm)); - results.Add(all.Single(s => s.ID == SkinInfo.RETRO_SKIN).ToLive(Realm)); + skins.Add(random_skin_info); - // random entry (unmanaged/live-unrelated) - results.Add(new SkinInfo - { - ID = SkinInfo.RANDOM_SKIN, - Name = "" - }.ToLiveUnmanaged()); + var userSkins = realm.All() + .Where(s => !s.DeletePending && !s.Protected) + .OrderBy(s => s.Name, StringComparer.OrdinalIgnoreCase) + .AsEnumerable() + .Select(s => s.ToLive(Realm)); - // append remaining non-protected skins (keeping the ordering from the realm query) - foreach (var s in all.Where(s => !s.Protected)) - results.Add(s.ToLive(Realm)); + foreach (var s in userSkins.Where(s => !s.Value.Protected)) + skins.Add(s); }); - return results; + return skins; } public void SelectRandomSkin() @@ -196,52 +197,39 @@ namespace osu.Game.Skinning }); } - /// - /// Cycle through skins. - /// Uses the skin selection UI ordering but skips the "Random Skin" entry. - /// - /// Optionally cycle in reverse. - private void cycleSkins(bool reverse = false) + private void cycleSkins(int direction) { + Debug.Assert(direction != 0); + // don't change selection if current skin is externally disabled/mounted for editing. if (CurrentSkinInfo.Disabled) return; - var availableSkins = GetAllUsableSkins().ToArray(); + var skins = GetAllUsableSkins(); - int currentIndex = Array.FindIndex(availableSkins, s => s.ID == CurrentSkinInfo.Value.ID); + int i = skins.IndexOf(CurrentSkinInfo.Value); // If the current skin isn't selectable anymore, start from the top. - if (currentIndex == -1) - currentIndex = 0; - - int desiredIndex = currentIndex; + if (i < 0 && direction < 0) + i = 0; do { - if (!reverse) - desiredIndex = (desiredIndex + 1) % availableSkins.Length; - else - desiredIndex = (desiredIndex - 1 + availableSkins.Length) % availableSkins.Length; - } while (availableSkins[desiredIndex].ID == SkinInfo.RANDOM_SKIN); + i = (i + direction + skins.Count) % skins.Count; + } while (skins[i].ID == SkinInfo.RANDOM_SKIN); - Realm.Run(r => - { - var chosenSkin = r.Find(availableSkins[desiredIndex].ID); - - CurrentSkinInfo.Value = chosenSkin.ToLive(Realm); - }); + CurrentSkinInfo.Value = skins[i]; } /// /// Cycle one skin backward. /// - public void SelectPreviousSkin() => cycleSkins(reverse: true); + public void SelectPreviousSkin() => cycleSkins(-1); /// /// Cycle one skin forward. /// - public void SelectNextSkin() => cycleSkins(); + public void SelectNextSkin() => cycleSkins(1); /// /// Retrieve a instance for the provided