Change `PlaylistOverlay` to use `ILive`

This commit is contained in:
Dean Herbert 2022-01-26 12:19:05 +09:00
parent 64914c45a4
commit dda513dd08
6 changed files with 76 additions and 64 deletions

View File

@ -8,6 +8,7 @@
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays.Music;
using osu.Game.Tests.Resources;
@ -18,11 +19,11 @@ namespace osu.Game.Tests.Visual.UserInterface
{
public class TestScenePlaylistOverlay : OsuManualInputManagerTestScene
{
private readonly BindableList<BeatmapSetInfo> beatmapSets = new BindableList<BeatmapSetInfo>();
private readonly BindableList<ILive<BeatmapSetInfo>> beatmapSets = new BindableList<ILive<BeatmapSetInfo>>();
private PlaylistOverlay playlistOverlay;
private BeatmapSetInfo first;
private ILive<BeatmapSetInfo> first;
[SetUp]
public void Setup() => Schedule(() =>
@ -45,7 +46,7 @@ public void Setup() => Schedule(() =>
for (int i = 0; i < 100; i++)
{
beatmapSets.Add(TestResources.CreateTestBeatmapSetInfo());
beatmapSets.Add(TestResources.CreateTestBeatmapSetInfo().ToLiveUnmanaged());
}
first = beatmapSets.First();
@ -60,7 +61,7 @@ public void TestRearrangeItems()
AddStep("hold 1st item handle", () =>
{
var handle = this.ChildrenOfType<OsuRearrangeableListItem<BeatmapSetInfo>.PlaylistItemHandle>().First();
var handle = this.ChildrenOfType<OsuRearrangeableListItem<ILive<BeatmapSetInfo>>.PlaylistItemHandle>().First();
InputManager.MoveMouseTo(handle.ScreenSpaceDrawQuad.Centre);
InputManager.PressButton(MouseButton.Left);
});

View File

@ -25,7 +25,7 @@ public class BeatmapCollection
/// <summary>
/// The beatmaps contained by the collection.
/// </summary>
public readonly BindableList<IBeatmapInfo> Beatmaps = new BindableList<IBeatmapInfo>();
public readonly BindableList<BeatmapInfo> Beatmaps = new BindableList<BeatmapInfo>();
/// <summary>
/// The date when this collection was last modified.

View File

@ -38,7 +38,7 @@ public class CollectionFilterDropdown : OsuDropdown<CollectionFilterMenuItem>
}
private readonly IBindableList<BeatmapCollection> collections = new BindableList<BeatmapCollection>();
private readonly IBindableList<IBeatmapInfo> beatmaps = new BindableList<IBeatmapInfo>();
private readonly IBindableList<BeatmapInfo> beatmaps = new BindableList<BeatmapInfo>();
private readonly BindableList<CollectionFilterMenuItem> filters = new BindableList<CollectionFilterMenuItem>();
[Resolved(CanBeNull = true)]
@ -196,7 +196,7 @@ protected class CollectionDropdownMenuItem : OsuDropdownMenu.DrawableOsuDropdown
private IBindable<WorkingBeatmap> beatmap { get; set; }
[CanBeNull]
private readonly BindableList<IBeatmapInfo> collectionBeatmaps;
private readonly BindableList<BeatmapInfo> collectionBeatmaps;
[NotNull]
private readonly Bindable<string> collectionName;

View File

@ -7,16 +7,17 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Containers;
using osuTK;
namespace osu.Game.Overlays.Music
{
public class Playlist : OsuRearrangeableListContainer<BeatmapSetInfo>
public class Playlist : OsuRearrangeableListContainer<ILive<BeatmapSetInfo>>
{
public Action<BeatmapSetInfo> RequestSelection;
public Action<ILive<BeatmapSetInfo>> RequestSelection;
public readonly Bindable<BeatmapSetInfo> SelectedSet = new Bindable<BeatmapSetInfo>();
public readonly Bindable<ILive<BeatmapSetInfo>> SelectedSet = new Bindable<ILive<BeatmapSetInfo>>();
public new MarginPadding Padding
{
@ -26,23 +27,23 @@ public class Playlist : OsuRearrangeableListContainer<BeatmapSetInfo>
public void Filter(FilterCriteria criteria)
{
var items = (SearchContainer<RearrangeableListItem<BeatmapSetInfo>>)ListContainer;
var items = (SearchContainer<RearrangeableListItem<ILive<BeatmapSetInfo>>>)ListContainer;
foreach (var item in items.OfType<PlaylistItem>())
item.InSelectedCollection = criteria.Collection?.Beatmaps.Any(b => item.Model.Equals(b.BeatmapSet)) ?? true;
item.InSelectedCollection = criteria.Collection?.Beatmaps.Any(b => item.Model.ID == b.BeatmapSet?.ID) ?? true;
items.SearchTerm = criteria.SearchText;
}
public BeatmapSetInfo FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter);
public ILive<BeatmapSetInfo> FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter);
protected override OsuRearrangeableListItem<BeatmapSetInfo> CreateOsuDrawable(BeatmapSetInfo item) => new PlaylistItem(item)
protected override OsuRearrangeableListItem<ILive<BeatmapSetInfo>> CreateOsuDrawable(ILive<BeatmapSetInfo> item) => new PlaylistItem(item)
{
SelectedSet = { BindTarget = SelectedSet },
RequestSelection = set => RequestSelection?.Invoke(set)
};
protected override FillFlowContainer<RearrangeableListItem<BeatmapSetInfo>> CreateListFillFlowContainer() => new SearchContainer<RearrangeableListItem<BeatmapSetInfo>>
protected override FillFlowContainer<RearrangeableListItem<ILive<BeatmapSetInfo>>> CreateListFillFlowContainer() => new SearchContainer<RearrangeableListItem<ILive<BeatmapSetInfo>>>
{
Spacing = new Vector2(0, 3),
LayoutDuration = 200,

View File

@ -10,17 +10,18 @@
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osuTK.Graphics;
namespace osu.Game.Overlays.Music
{
public class PlaylistItem : OsuRearrangeableListItem<BeatmapSetInfo>, IFilterable
public class PlaylistItem : OsuRearrangeableListItem<ILive<BeatmapSetInfo>>, IFilterable
{
public readonly Bindable<BeatmapSetInfo> SelectedSet = new Bindable<BeatmapSetInfo>();
public readonly Bindable<ILive<BeatmapSetInfo>> SelectedSet = new Bindable<ILive<BeatmapSetInfo>>();
public Action<BeatmapSetInfo> RequestSelection;
public Action<ILive<BeatmapSetInfo>> RequestSelection;
private TextFlowContainer text;
private ITextPart titlePart;
@ -28,7 +29,7 @@ public class PlaylistItem : OsuRearrangeableListItem<BeatmapSetInfo>, IFilterabl
[Resolved]
private OsuColour colours { get; set; }
public PlaylistItem(BeatmapSetInfo item)
public PlaylistItem(ILive<BeatmapSetInfo> item)
: base(item)
{
Padding = new MarginPadding { Left = 5 };
@ -44,34 +45,37 @@ protected override void LoadComplete()
{
base.LoadComplete();
var metadata = Model.Metadata;
var title = new RomanisableString(metadata.TitleUnicode, metadata.Title);
var artist = new RomanisableString(metadata.ArtistUnicode, metadata.Artist);
titlePart = text.AddText(title, sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular));
titlePart.DrawablePartsRecreated += _ => updateSelectionState(true);
text.AddText(@" "); // to separate the title from the artist.
text.AddText(artist, sprite =>
Model.PerformRead(m =>
{
sprite.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold);
sprite.Colour = colours.Gray9;
sprite.Padding = new MarginPadding { Top = 1 };
var metadata = m.Metadata;
var title = new RomanisableString(metadata.TitleUnicode, metadata.Title);
var artist = new RomanisableString(metadata.ArtistUnicode, metadata.Artist);
titlePart = text.AddText(title, sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular));
titlePart.DrawablePartsRecreated += _ => updateSelectionState(true);
text.AddText(@" "); // to separate the title from the artist.
text.AddText(artist, sprite =>
{
sprite.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold);
sprite.Colour = colours.Gray9;
sprite.Padding = new MarginPadding { Top = 1 };
});
SelectedSet.BindValueChanged(set =>
{
bool newSelected = set.NewValue?.Equals(Model) == true;
if (newSelected == selected)
return;
selected = newSelected;
updateSelectionState(false);
});
updateSelectionState(true);
});
SelectedSet.BindValueChanged(set =>
{
bool newSelected = set.NewValue?.Equals(Model) == true;
if (newSelected == selected)
return;
selected = newSelected;
updateSelectionState(false);
});
updateSelectionState(true);
}
private bool selected;
@ -109,7 +113,7 @@ public bool InSelectedCollection
}
}
public IEnumerable<string> FilterTerms => Model.Metadata.GetSearchableTerms();
public IEnumerable<string> FilterTerms => Model.PerformRead(m => m.Metadata.GetSearchableTerms());
private bool matchingFilter = true;

View File

@ -24,9 +24,9 @@ public class PlaylistOverlay : VisibilityContainer
private const float transition_duration = 600;
private const float playlist_height = 510;
public IBindableList<BeatmapSetInfo> BeatmapSets => beatmapSets;
public IBindableList<ILive<BeatmapSetInfo>> BeatmapSets => beatmapSets;
private readonly BindableList<BeatmapSetInfo> beatmapSets = new BindableList<BeatmapSetInfo>();
private readonly BindableList<ILive<BeatmapSetInfo>> beatmapSets = new BindableList<ILive<BeatmapSetInfo>>();
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
@ -85,13 +85,16 @@ private void load(OsuColour colours, Bindable<WorkingBeatmap> beatmap)
filter.Search.OnCommit += (sender, newText) =>
{
BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps.FirstOrDefault();
if (toSelect != null)
list.FirstVisibleSet.PerformRead(set =>
{
beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect);
beatmap.Value.Track.Restart();
}
BeatmapInfo toSelect = set.Beatmaps.FirstOrDefault();
if (toSelect != null)
{
beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect);
beatmap.Value.Track.Restart();
}
});
};
}
@ -104,7 +107,7 @@ protected override void LoadComplete()
beatmapSubscription = realm.RegisterForNotifications(r => r.All<BeatmapSetInfo>().Where(s => !s.DeletePending), beatmapsChanged);
list.Items.BindTo(beatmapSets);
beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo, true);
beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo.ToLive(realm), true);
}
private void beatmapsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet changes, Exception error)
@ -113,12 +116,12 @@ private void beatmapsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet
{
beatmapSets.Clear();
// must use AddRange to avoid RearrangeableList sort overhead per add op.
beatmapSets.AddRange(sender);
beatmapSets.AddRange(sender.ToLive(realm));
return;
}
foreach (int i in changes.InsertedIndices)
beatmapSets.Insert(i, sender[i]);
beatmapSets.Insert(i, sender[i].ToLive(realm));
foreach (int i in changes.DeletedIndices.OrderByDescending(i => i))
beatmapSets.RemoveAt(i);
@ -141,16 +144,19 @@ protected override void PopOut()
this.FadeOut(transition_duration);
}
private void itemSelected(BeatmapSetInfo set)
private void itemSelected(ILive<BeatmapSetInfo> beatmapSet)
{
if (set.Equals((beatmap.Value?.BeatmapSetInfo)))
beatmapSet.PerformRead(set =>
{
beatmap.Value?.Track.Seek(0);
return;
}
if (set.Equals((beatmap.Value?.BeatmapSetInfo)))
{
beatmap.Value?.Track.Seek(0);
return;
}
beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First());
beatmap.Value.Track.Restart();
beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First());
beatmap.Value.Track.Restart();
});
}
protected override void Dispose(bool isDisposing)