1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 05:27:23 +08:00

Refactor SkinSection to avoid unnecessary realm queries

This commit is contained in:
Dean Herbert 2022-01-26 17:48:11 +09:00
parent 4a51bab9ac
commit d1a2256262

View File

@ -18,6 +18,7 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation; using osu.Game.Localisation;
using osu.Game.Skinning; using osu.Game.Skinning;
using osu.Game.Skinning.Editor; using osu.Game.Skinning.Editor;
using Realms;
namespace osu.Game.Overlays.Settings.Sections namespace osu.Game.Overlays.Settings.Sections
{ {
@ -51,12 +52,6 @@ namespace osu.Game.Overlays.Settings.Sections
private IDisposable realmSubscription; private IDisposable realmSubscription;
private IQueryable<SkinInfo> queryRealmSkins() =>
realm.Realm.All<SkinInfo>()
.Where(s => !s.DeletePending)
.OrderByDescending(s => s.Protected) // protected skins should be at the top.
.ThenBy(s => s.Name, StringComparer.OrdinalIgnoreCase);
[BackgroundDependencyLoader(permitNulls: true)] [BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuConfigManager config, [CanBeNull] SkinEditorOverlay skinEditor) private void load(OsuConfigManager config, [CanBeNull] SkinEditorOverlay skinEditor)
{ {
@ -83,37 +78,54 @@ namespace osu.Game.Overlays.Settings.Sections
skinDropdown.Current = dropdownBindable; skinDropdown.Current = dropdownBindable;
realmSubscription = realm.RegisterForNotifications(r => queryRealmSkins(), (sender, changes, error) => realmSubscription = realm.RegisterForNotifications(r => realm.Realm.All<SkinInfo>()
{ .Where(s => !s.DeletePending)
// The first fire of this is a bit redundant due to the call below, .OrderByDescending(s => s.Protected) // protected skins should be at the top.
// but this is safest in case the subscription is restored after a context recycle. .ThenBy(s => s.Name, StringComparer.OrdinalIgnoreCase), skinsChanged);
updateItems();
});
updateItems();
configBindable.BindValueChanged(id => Scheduler.AddOnce(updateSelectedSkinFromConfig)); configBindable.BindValueChanged(id => Scheduler.AddOnce(updateSelectedSkinFromConfig));
updateSelectedSkinFromConfig();
dropdownBindable.BindValueChanged(skin => dropdownBindable.BindValueChanged(dropdownSelectionChanged);
}
private void dropdownSelectionChanged(ValueChangedEvent<Live<SkinInfo>> skin)
{
// Only handle cases where it's clear the user has intent to change skins.
if (skin.OldValue == null) return;
if (skin.NewValue.Equals(random_skin_info))
{ {
if (skin.NewValue.Equals(random_skin_info)) var skinBefore = skins.CurrentSkinInfo.Value;
skins.SelectRandomSkin();
if (skinBefore == skins.CurrentSkinInfo.Value)
{ {
var skinBefore = skins.CurrentSkinInfo.Value; // the random selection didn't change the skin, so we should manually update the dropdown to match.
dropdownBindable.Value = skins.CurrentSkinInfo.Value;
skins.SelectRandomSkin();
if (skinBefore == skins.CurrentSkinInfo.Value)
{
// the random selection didn't change the skin, so we should manually update the dropdown to match.
dropdownBindable.Value = skins.CurrentSkinInfo.Value;
}
return;
} }
configBindable.Value = skin.NewValue.ID.ToString(); return;
}); }
configBindable.Value = skin.NewValue.ID.ToString();
}
private void skinsChanged(IRealmCollection<SkinInfo> skins, ChangeSet changes, Exception error)
{
// This can only mean that realm is recycling, else we would see the protected skins.
// Because we are using `Live<>` in this class, we don't need to worry about this scenario too much.
if (!skins.Any())
return;
int protectedCount = skins.Count(s => s.Protected);
skinItems = skins.ToLive(realm);
skinItems.Insert(protectedCount, random_skin_info);
skinDropdown.Items = skinItems;
updateSelectedSkinFromConfig();
} }
private void updateSelectedSkinFromConfig() private void updateSelectedSkinFromConfig()
@ -126,17 +138,6 @@ namespace osu.Game.Overlays.Settings.Sections
dropdownBindable.Value = skin ?? skinDropdown.Items.First(); dropdownBindable.Value = skin ?? skinDropdown.Items.First();
} }
private void updateItems()
{
int protectedCount = queryRealmSkins().Count(s => s.Protected);
skinItems = queryRealmSkins().ToLive(realm);
skinItems.Insert(protectedCount, random_skin_info);
skinDropdown.Items = skinItems;
}
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);