Change event flow to avoid firing store delete events on update

This commit is contained in:
Dean Herbert 2020-05-27 16:08:47 +09:00
parent ad10a7f0b2
commit f989f1aa00
12 changed files with 49 additions and 43 deletions

View File

@ -156,7 +156,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get<BeatmapManager>();
// ReSharper disable once AccessToModifiedClosure
manager.ItemAdded.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
manager.ItemUpdated.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
manager.ItemRemoved.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
var imported = await LoadOszIntoOsu(osu);
@ -166,7 +166,7 @@ namespace osu.Game.Tests.Beatmaps.IO
imported.Hash += "-changed";
manager.Update(imported);
Assert.AreEqual(0, itemAddRemoveFireCount -= 2);
Assert.AreEqual(0, itemAddRemoveFireCount -= 1);
checkBeatmapSetCount(osu, 1);
checkBeatmapCount(osu, 12);

View File

@ -55,12 +55,12 @@ namespace osu.Game.Database
public Action<Notification> PostNotification { protected get; set; }
/// <summary>
/// Fired when a new <typeparamref name="TModel"/> becomes available in the database.
/// Fired when a new or updated <typeparamref name="TModel"/> becomes available in the database.
/// This is not guaranteed to run on the update thread.
/// </summary>
public IBindable<WeakReference<TModel>> ItemAdded => itemAdded;
public IBindable<WeakReference<TModel>> ItemUpdated => itemUpdated;
private readonly Bindable<WeakReference<TModel>> itemAdded = new Bindable<WeakReference<TModel>>();
private readonly Bindable<WeakReference<TModel>> itemUpdated = new Bindable<WeakReference<TModel>>();
/// <summary>
/// Fired when a <typeparamref name="TModel"/> is removed from the database.
@ -90,7 +90,7 @@ namespace osu.Game.Database
ContextFactory = contextFactory;
ModelStore = modelStore;
ModelStore.ItemAdded += item => handleEvent(() => itemAdded.Value = new WeakReference<TModel>(item));
ModelStore.ItemUpdated += item => handleEvent(() => itemUpdated.Value = new WeakReference<TModel>(item));
ModelStore.ItemRemoved += item => handleEvent(() => itemRemoved.Value = new WeakReference<TModel>(item));
exportStorage = storage.GetStorageForDirectory("exports");

View File

@ -13,7 +13,7 @@ namespace osu.Game.Database
public interface IModelManager<TModel>
where TModel : class
{
IBindable<WeakReference<TModel>> ItemAdded { get; }
IBindable<WeakReference<TModel>> ItemUpdated { get; }
IBindable<WeakReference<TModel>> ItemRemoved { get; }
}

View File

@ -16,7 +16,14 @@ namespace osu.Game.Database
public abstract class MutableDatabaseBackedStore<T> : DatabaseBackedStore
where T : class, IHasPrimaryKey, ISoftDelete
{
public event Action<T> ItemAdded;
/// <summary>
/// Fired when an item was added or updated.
/// </summary>
public event Action<T> ItemUpdated;
/// <summary>
/// Fired when an item was removed.
/// </summary>
public event Action<T> ItemRemoved;
protected MutableDatabaseBackedStore(IDatabaseContextFactory contextFactory, Storage storage = null)
@ -41,7 +48,7 @@ namespace osu.Game.Database
context.Attach(item);
}
ItemAdded?.Invoke(item);
ItemUpdated?.Invoke(item);
}
/// <summary>
@ -53,8 +60,7 @@ namespace osu.Game.Database
using (var usage = ContextFactory.GetForWrite())
usage.Context.Update(item);
ItemRemoved?.Invoke(item);
ItemAdded?.Invoke(item);
ItemUpdated?.Invoke(item);
}
/// <summary>
@ -91,7 +97,7 @@ namespace osu.Game.Database
item.DeletePending = false;
}
ItemAdded?.Invoke(item);
ItemUpdated?.Invoke(item);
return true;
}

View File

@ -34,7 +34,7 @@ namespace osu.Game.Online
Model.Value = model;
}
private IBindable<WeakReference<TModel>> managerAdded;
private IBindable<WeakReference<TModel>> managedUpdated;
private IBindable<WeakReference<TModel>> managerRemoved;
private IBindable<WeakReference<ArchiveDownloadRequest<TModel>>> managerDownloadBegan;
private IBindable<WeakReference<ArchiveDownloadRequest<TModel>>> managerDownloadFailed;
@ -56,8 +56,8 @@ namespace osu.Game.Online
managerDownloadBegan.BindValueChanged(downloadBegan);
managerDownloadFailed = manager.DownloadFailed.GetBoundCopy();
managerDownloadFailed.BindValueChanged(downloadFailed);
managerAdded = manager.ItemAdded.GetBoundCopy();
managerAdded.BindValueChanged(itemAdded);
managedUpdated = manager.ItemUpdated.GetBoundCopy();
managedUpdated.BindValueChanged(itemUpdated);
managerRemoved = manager.ItemRemoved.GetBoundCopy();
managerRemoved.BindValueChanged(itemRemoved);
}
@ -128,7 +128,7 @@ namespace osu.Game.Online
private void onRequestFailure(Exception e) => Schedule(() => attachDownload(null));
private void itemAdded(ValueChangedEvent<WeakReference<TModel>> weakItem)
private void itemUpdated(ValueChangedEvent<WeakReference<TModel>> weakItem)
{
if (weakItem.NewValue.TryGetTarget(out var item))
setDownloadStateFromManager(item, DownloadState.LocallyAvailable);

View File

@ -192,7 +192,7 @@ namespace osu.Game
ScoreManager.Delete(getBeatmapScores(item), true);
});
BeatmapManager.ItemAdded.BindValueChanged(i =>
BeatmapManager.ItemUpdated.BindValueChanged(i =>
{
if (i.NewValue.TryGetTarget(out var item))
ScoreManager.Undelete(getBeatmapScores(item), true);

View File

@ -60,14 +60,14 @@ namespace osu.Game.Overlays
[Resolved(canBeNull: true)]
private OnScreenDisplay onScreenDisplay { get; set; }
private IBindable<WeakReference<BeatmapSetInfo>> managerAdded;
private IBindable<WeakReference<BeatmapSetInfo>> managerUpdated;
private IBindable<WeakReference<BeatmapSetInfo>> managerRemoved;
[BackgroundDependencyLoader]
private void load()
{
managerAdded = beatmaps.ItemAdded.GetBoundCopy();
managerAdded.BindValueChanged(beatmapAdded);
managerUpdated = beatmaps.ItemUpdated.GetBoundCopy();
managerUpdated.BindValueChanged(beatmapUpdated);
managerRemoved = beatmaps.ItemRemoved.GetBoundCopy();
managerRemoved.BindValueChanged(beatmapRemoved);
@ -98,14 +98,14 @@ namespace osu.Game.Overlays
/// </summary>
public bool IsPlaying => current?.Track.IsRunning ?? false;
private void beatmapAdded(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakSet)
private void beatmapUpdated(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakSet)
{
if (weakSet.NewValue.TryGetTarget(out var set))
{
Schedule(() =>
{
if (!beatmapSets.Contains(set))
beatmapSets.Add(set);
beatmapSets.Remove(set);
beatmapSets.Add(set);
});
}
}

View File

@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Settings.Sections
[Resolved]
private SkinManager skins { get; set; }
private IBindable<WeakReference<SkinInfo>> managerAdded;
private IBindable<WeakReference<SkinInfo>> managerUpdated;
private IBindable<WeakReference<SkinInfo>> managerRemoved;
[BackgroundDependencyLoader]
@ -73,8 +73,8 @@ namespace osu.Game.Overlays.Settings.Sections
},
};
managerAdded = skins.ItemAdded.GetBoundCopy();
managerAdded.BindValueChanged(itemAdded);
managerUpdated = skins.ItemUpdated.GetBoundCopy();
managerUpdated.BindValueChanged(itemUpdated);
managerRemoved = skins.ItemRemoved.GetBoundCopy();
managerRemoved.BindValueChanged(itemRemoved);
@ -92,10 +92,10 @@ namespace osu.Game.Overlays.Settings.Sections
dropdownBindable.BindValueChanged(skin => configBindable.Value = skin.NewValue.ID);
}
private void itemAdded(ValueChangedEvent<WeakReference<SkinInfo>> weakItem)
private void itemUpdated(ValueChangedEvent<WeakReference<SkinInfo>> weakItem)
{
if (weakItem.NewValue.TryGetTarget(out var item))
Schedule(() => skinDropdown.Items = skinDropdown.Items.Append(item).ToArray());
Schedule(() => skinDropdown.Items = skinDropdown.Items.Where(i => !i.Equals(item)).Append(item).ToArray());
}
private void itemRemoved(ValueChangedEvent<WeakReference<SkinInfo>> weakItem)

View File

@ -32,14 +32,14 @@ namespace osu.Game.Screens.Multi.Match.Components
Text = "Start";
}
private IBindable<WeakReference<BeatmapSetInfo>> managerAdded;
private IBindable<WeakReference<BeatmapSetInfo>> managerUpdated;
private IBindable<WeakReference<BeatmapSetInfo>> managerRemoved;
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
managerAdded = beatmaps.ItemAdded.GetBoundCopy();
managerAdded.BindValueChanged(beatmapAdded);
managerUpdated = beatmaps.ItemUpdated.GetBoundCopy();
managerUpdated.BindValueChanged(beatmapUpdated);
managerRemoved = beatmaps.ItemRemoved.GetBoundCopy();
managerRemoved.BindValueChanged(beatmapRemoved);
@ -61,7 +61,7 @@ namespace osu.Game.Screens.Multi.Match.Components
hasBeatmap = beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId) != null;
}
private void beatmapAdded(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakSet)
private void beatmapUpdated(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakSet)
{
if (weakSet.NewValue.TryGetTarget(out var set))
{

View File

@ -50,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match
private LeaderboardChatDisplay leaderboardChatDisplay;
private MatchSettingsOverlay settingsOverlay;
private IBindable<WeakReference<BeatmapSetInfo>> managerAdded;
private IBindable<WeakReference<BeatmapSetInfo>> managerUpdated;
public MatchSubScreen(Room room)
{
@ -183,8 +183,8 @@ namespace osu.Game.Screens.Multi.Match
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged));
SelectedItem.Value = playlist.FirstOrDefault();
managerAdded = beatmapManager.ItemAdded.GetBoundCopy();
managerAdded.BindValueChanged(beatmapAdded);
managerUpdated = beatmapManager.ItemUpdated.GetBoundCopy();
managerUpdated.BindValueChanged(beatmapUpdated);
}
public override bool OnExiting(IScreen next)
@ -217,7 +217,7 @@ namespace osu.Game.Screens.Multi.Match
Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap);
}
private void beatmapAdded(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakSet)
private void beatmapUpdated(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakSet)
{
Schedule(() =>
{

View File

@ -131,7 +131,7 @@ namespace osu.Game.Screens.Select
private CarouselRoot root;
private IBindable<WeakReference<BeatmapSetInfo>> itemAdded;
private IBindable<WeakReference<BeatmapSetInfo>> itemUpdated;
private IBindable<WeakReference<BeatmapSetInfo>> itemRemoved;
private IBindable<WeakReference<BeatmapInfo>> itemHidden;
private IBindable<WeakReference<BeatmapInfo>> itemRestored;
@ -166,8 +166,8 @@ namespace osu.Game.Screens.Select
RightClickScrollingEnabled.ValueChanged += enabled => scroll.RightMouseScrollbar = enabled.NewValue;
RightClickScrollingEnabled.TriggerChange();
itemAdded = beatmaps.ItemAdded.GetBoundCopy();
itemAdded.BindValueChanged(beatmapAdded);
itemUpdated = beatmaps.ItemUpdated.GetBoundCopy();
itemUpdated.BindValueChanged(beatmapUpdated);
itemRemoved = beatmaps.ItemRemoved.GetBoundCopy();
itemRemoved.BindValueChanged(beatmapRemoved);
itemHidden = beatmaps.BeatmapHidden.GetBoundCopy();
@ -582,7 +582,7 @@ namespace osu.Game.Screens.Select
RemoveBeatmapSet(item);
}
private void beatmapAdded(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakItem)
private void beatmapUpdated(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakItem)
{
if (weakItem.NewValue.TryGetTarget(out var item))
UpdateBeatmapSet(item);

View File

@ -28,7 +28,7 @@ namespace osu.Game.Screens.Select.Carousel
[Resolved]
private IAPIProvider api { get; set; }
private IBindable<WeakReference<ScoreInfo>> itemAdded;
private IBindable<WeakReference<ScoreInfo>> itemUpdated;
private IBindable<WeakReference<ScoreInfo>> itemRemoved;
public TopLocalRank(BeatmapInfo beatmap)
@ -40,8 +40,8 @@ namespace osu.Game.Screens.Select.Carousel
[BackgroundDependencyLoader]
private void load()
{
itemAdded = scores.ItemAdded.GetBoundCopy();
itemAdded.BindValueChanged(scoreChanged);
itemUpdated = scores.ItemUpdated.GetBoundCopy();
itemUpdated.BindValueChanged(scoreChanged);
itemRemoved = scores.ItemRemoved.GetBoundCopy();
itemRemoved.BindValueChanged(scoreChanged);