From f5c974dd897b0a7006b944e0103e4158d3d7667a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 May 2020 13:40:16 +0900 Subject: [PATCH 1/4] Hide non-alive selection blueprints by default --- .../Edit/Blueprints/OsuSelectionBlueprint.cs | 2 ++ osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs index b0e13808a5..8dd550bb96 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs @@ -12,6 +12,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints { protected new T HitObject => (T)DrawableObject.HitObject; + protected override bool AlwaysShowWhenSelected => true; + protected OsuSelectionBlueprint(DrawableHitObject drawableObject) : base(drawableObject) { diff --git a/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs b/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs index 8202d3a1d1..75200e3027 100644 --- a/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs @@ -15,7 +15,12 @@ namespace osu.Game.Rulesets.Edit /// public readonly DrawableHitObject DrawableObject; - protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || State == SelectionState.Selected; + /// + /// Whether the blueprint should be shown even when the is not alive. + /// + protected virtual bool AlwaysShowWhenSelected => false; + + protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || (AlwaysShowWhenSelected && State == SelectionState.Selected); protected OverlaySelectionBlueprint(DrawableHitObject drawableObject) : base(drawableObject.HitObject) From f989f1aa0034d6283ee3d49169316a80713c0a55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 May 2020 16:08:47 +0900 Subject: [PATCH 2/4] Change event flow to avoid firing store delete events on update --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 4 ++-- osu.Game/Database/ArchiveModelManager.cs | 8 ++++---- osu.Game/Database/IModelManager.cs | 2 +- osu.Game/Database/MutableDatabaseBackedStore.cs | 16 +++++++++++----- osu.Game/Online/DownloadTrackingComposite.cs | 8 ++++---- osu.Game/OsuGameBase.cs | 2 +- osu.Game/Overlays/MusicController.cs | 12 ++++++------ .../Overlays/Settings/Sections/SkinSection.cs | 10 +++++----- .../Multi/Match/Components/ReadyButton.cs | 8 ++++---- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 8 ++++---- osu.Game/Screens/Select/BeatmapCarousel.cs | 8 ++++---- osu.Game/Screens/Select/Carousel/TopLocalRank.cs | 6 +++--- 12 files changed, 49 insertions(+), 43 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 43fab186aa..5eb11a3264 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -156,7 +156,7 @@ namespace osu.Game.Tests.Beatmaps.IO var manager = osu.Dependencies.Get(); // 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); diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index f21f708f95..ae55a7b14a 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -55,12 +55,12 @@ namespace osu.Game.Database public Action PostNotification { protected get; set; } /// - /// Fired when a new becomes available in the database. + /// Fired when a new or updated becomes available in the database. /// This is not guaranteed to run on the update thread. /// - public IBindable> ItemAdded => itemAdded; + public IBindable> ItemUpdated => itemUpdated; - private readonly Bindable> itemAdded = new Bindable>(); + private readonly Bindable> itemUpdated = new Bindable>(); /// /// Fired when a 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(item)); + ModelStore.ItemUpdated += item => handleEvent(() => itemUpdated.Value = new WeakReference(item)); ModelStore.ItemRemoved += item => handleEvent(() => itemRemoved.Value = new WeakReference(item)); exportStorage = storage.GetStorageForDirectory("exports"); diff --git a/osu.Game/Database/IModelManager.cs b/osu.Game/Database/IModelManager.cs index 852b385798..7f7e5565f1 100644 --- a/osu.Game/Database/IModelManager.cs +++ b/osu.Game/Database/IModelManager.cs @@ -13,7 +13,7 @@ namespace osu.Game.Database public interface IModelManager where TModel : class { - IBindable> ItemAdded { get; } + IBindable> ItemUpdated { get; } IBindable> ItemRemoved { get; } } diff --git a/osu.Game/Database/MutableDatabaseBackedStore.cs b/osu.Game/Database/MutableDatabaseBackedStore.cs index 4ca1eef989..c9d0c4bc41 100644 --- a/osu.Game/Database/MutableDatabaseBackedStore.cs +++ b/osu.Game/Database/MutableDatabaseBackedStore.cs @@ -16,7 +16,14 @@ namespace osu.Game.Database public abstract class MutableDatabaseBackedStore : DatabaseBackedStore where T : class, IHasPrimaryKey, ISoftDelete { - public event Action ItemAdded; + /// + /// Fired when an item was added or updated. + /// + public event Action ItemUpdated; + + /// + /// Fired when an item was removed. + /// public event Action 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); } /// @@ -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); } /// @@ -91,7 +97,7 @@ namespace osu.Game.Database item.DeletePending = false; } - ItemAdded?.Invoke(item); + ItemUpdated?.Invoke(item); return true; } diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 47de7d75ed..5d9cf612bb 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -34,7 +34,7 @@ namespace osu.Game.Online Model.Value = model; } - private IBindable> managerAdded; + private IBindable> managedUpdated; private IBindable> managerRemoved; private IBindable>> managerDownloadBegan; private IBindable>> 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> weakItem) + private void itemUpdated(ValueChangedEvent> weakItem) { if (weakItem.NewValue.TryGetTarget(out var item)) setDownloadStateFromManager(item, DownloadState.LocallyAvailable); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 453587df18..e7446975b9 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -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); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 35f3cb0e25..92cf490be2 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -60,14 +60,14 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - private IBindable> managerAdded; + private IBindable> managerUpdated; private IBindable> 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 /// public bool IsPlaying => current?.Track.IsRunning ?? false; - private void beatmapAdded(ValueChangedEvent> weakSet) + private void beatmapUpdated(ValueChangedEvent> weakSet) { if (weakSet.NewValue.TryGetTarget(out var set)) { Schedule(() => { - if (!beatmapSets.Contains(set)) - beatmapSets.Add(set); + beatmapSets.Remove(set); + beatmapSets.Add(set); }); } } diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index b84b9fec37..04390a1193 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Settings.Sections [Resolved] private SkinManager skins { get; set; } - private IBindable> managerAdded; + private IBindable> managerUpdated; private IBindable> 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> weakItem) + private void itemUpdated(ValueChangedEvent> 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> weakItem) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index 4420b2d58a..e1f86fcc97 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -32,14 +32,14 @@ namespace osu.Game.Screens.Multi.Match.Components Text = "Start"; } - private IBindable> managerAdded; + private IBindable> managerUpdated; private IBindable> 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> weakSet) + private void beatmapUpdated(ValueChangedEvent> weakSet) { if (weakSet.NewValue.TryGetTarget(out var set)) { diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index caa547ac72..e1d72d9600 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match private LeaderboardChatDisplay leaderboardChatDisplay; private MatchSettingsOverlay settingsOverlay; - private IBindable> managerAdded; + private IBindable> 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> weakSet) + private void beatmapUpdated(ValueChangedEvent> weakSet) { Schedule(() => { diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index f23e1b1ef2..2d714d1794 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -131,7 +131,7 @@ namespace osu.Game.Screens.Select private CarouselRoot root; - private IBindable> itemAdded; + private IBindable> itemUpdated; private IBindable> itemRemoved; private IBindable> itemHidden; private IBindable> 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> weakItem) + private void beatmapUpdated(ValueChangedEvent> weakItem) { if (weakItem.NewValue.TryGetTarget(out var item)) UpdateBeatmapSet(item); diff --git a/osu.Game/Screens/Select/Carousel/TopLocalRank.cs b/osu.Game/Screens/Select/Carousel/TopLocalRank.cs index aed25787b0..3ad57c1cb0 100644 --- a/osu.Game/Screens/Select/Carousel/TopLocalRank.cs +++ b/osu.Game/Screens/Select/Carousel/TopLocalRank.cs @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Select.Carousel [Resolved] private IAPIProvider api { get; set; } - private IBindable> itemAdded; + private IBindable> itemUpdated; private IBindable> 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); From 9a060cfb3acfac28816eb68f245e365153a9af46 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 May 2020 20:44:15 +0900 Subject: [PATCH 3/4] Allow drag selections to occur from outside the playfield --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 1 + osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 3453bfbf63..99759bde3d 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -102,6 +102,7 @@ namespace osu.Game.Rulesets.Edit { Name = "Content", RelativeSizeAxes = Axes.Both, + Masking = true, Children = new Drawable[] { // layers below playfield diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index cc417bbb10..d07cffff0c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -44,6 +44,8 @@ namespace osu.Game.Screens.Edit.Compose.Components private readonly BindableList selectedHitObjects = new BindableList(); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; + [Resolved(canBeNull: true)] private IPositionSnapProvider snapProvider { get; set; } From e4de20f0a5b6721519d6fa1baa4b2b2daf9222e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 May 2020 11:54:27 +0900 Subject: [PATCH 4/4] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b7d08fb120..7ea1f3140b 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d5017a436f..3d2a4f3081 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 19a36f1e1f..8a7f75b515 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - +