Remove beatmap bindable from PlaylistItem

This commit is contained in:
Dan Balasescu
2022-02-15 23:33:26 +09:00
parent 94a974e1c9
commit bdc3b76df0
48 changed files with 227 additions and 395 deletions

View File

@ -727,10 +727,9 @@ namespace osu.Game.Online.Multiplayer
RoomUpdated?.Invoke();
}
private PlaylistItem createPlaylistItem(MultiplayerPlaylistItem item) => new PlaylistItem
private PlaylistItem createPlaylistItem(MultiplayerPlaylistItem item) => new PlaylistItem(new APIBeatmap { OnlineID = item.BeatmapID })
{
ID = item.ID,
BeatmapID = item.BeatmapID,
OwnerID = item.OwnerID,
RulesetID = item.RulesetID,
Expired = item.Expired,
@ -740,14 +739,6 @@ namespace osu.Game.Online.Multiplayer
AllowedMods = item.AllowedMods.ToArray()
};
/// <summary>
/// Retrieves a <see cref="APIBeatmap"/> from an online source.
/// </summary>
/// <param name="beatmapId">The beatmap ID.</param>
/// <param name="cancellationToken">A token to cancel the request.</param>
/// <returns>The <see cref="APIBeatmap"/> retrieval task.</returns>
public abstract Task<APIBeatmap> GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default);
/// <summary>
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.
/// </summary>

View File

@ -9,9 +9,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Database;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
namespace osu.Game.Online.Multiplayer
@ -29,9 +27,6 @@ namespace osu.Game.Online.Multiplayer
private HubConnection? connection => connector?.CurrentConnection;
[Resolved]
private BeatmapLookupCache beatmapLookupCache { get; set; } = null!;
public OnlineMultiplayerClient(EndpointConfiguration endpoints)
{
endpoint = endpoints.MultiplayerEndpointUrl;
@ -186,11 +181,6 @@ namespace osu.Game.Online.Multiplayer
return connection.InvokeAsync(nameof(IMultiplayerServer.RemovePlaylistItem), playlistItemId);
}
public override Task<APIBeatmap> GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default)
{
return beatmapLookupCache.GetBeatmapAsync(beatmapId, cancellationToken);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);

View File

@ -63,8 +63,8 @@ namespace osu.Game.Online.Rooms
{
ID = item.ID;
OwnerID = item.OwnerID;
BeatmapID = item.BeatmapID;
BeatmapChecksum = item.Beatmap.Value?.MD5Hash ?? string.Empty;
BeatmapID = item.Beatmap.OnlineID;
BeatmapChecksum = item.Beatmap.MD5Hash;
RulesetID = item.RulesetID;
RequiredMods = item.RequiredMods.ToArray();
AllowedMods = item.AllowedMods.ToArray();

View File

@ -64,11 +64,11 @@ namespace osu.Game.Online.Rooms
downloadTracker?.RemoveAndDisposeImmediately();
beatmapLookupCache.GetBeatmapAsync(item.NewValue.Beatmap.Value.OnlineID).ContinueWith(task => Schedule(() =>
beatmapLookupCache.GetBeatmapAsync(item.NewValue.Beatmap.OnlineID).ContinueWith(task => Schedule(() =>
{
var beatmap = task.GetResultSafely();
if (SelectedItem.Value?.Beatmap.Value.OnlineID == beatmap.OnlineID)
if (SelectedItem.Value?.Beatmap.OnlineID == beatmap.OnlineID)
beginTracking(beatmap);
}), TaskContinuationOptions.OnlyOnRanToCompletion);
}, true);
@ -96,7 +96,7 @@ namespace osu.Game.Online.Rooms
// handles changes to hash that didn't occur from the import process (ie. a user editing the beatmap in the editor, somehow).
realmSubscription?.Dispose();
realmSubscription = realm.RegisterForNotifications(r => QueryBeatmapForOnlinePlay(r, SelectedItem.Value.Beatmap.Value), (items, changes, ___) =>
realmSubscription = realm.RegisterForNotifications(r => QueryBeatmapForOnlinePlay(r, SelectedItem.Value.Beatmap), (items, changes, ___) =>
{
if (changes == null)
return;

View File

@ -41,6 +41,6 @@ namespace osu.Game.Online.Rooms
}
public static string GetTotalDuration(this BindableList<PlaylistItem> playlist) =>
playlist.Select(p => p.Beatmap.Value.Length).Sum().Milliseconds().Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 2);
playlist.Select(p => p.Beatmap.Length).Sum().Milliseconds().Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 2);
}
}

View File

@ -1,6 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable enable
using System;
using System.Linq;
using JetBrains.Annotations;
@ -12,6 +14,7 @@ using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.Rooms
{
[JsonObject(MemberSerialization.OptIn)]
public class PlaylistItem : IEquatable<PlaylistItem>
{
[JsonProperty("id")]
@ -20,9 +23,6 @@ namespace osu.Game.Online.Rooms
[JsonProperty("owner_id")]
public int OwnerID { get; set; }
[JsonProperty("beatmap_id")]
public int BeatmapID { get; set; }
[JsonProperty("ruleset_id")]
public int RulesetID { get; set; }
@ -38,35 +38,50 @@ namespace osu.Game.Online.Rooms
[JsonProperty("played_at")]
public DateTimeOffset? PlayedAt { get; set; }
[JsonIgnore]
public IBindable<bool> Valid => valid;
private readonly Bindable<bool> valid = new BindableBool(true);
[JsonIgnore]
public readonly Bindable<IBeatmapInfo> Beatmap = new Bindable<IBeatmapInfo>();
[JsonProperty("beatmap")]
private APIBeatmap apiBeatmap { get; set; }
[JsonProperty("allowed_mods")]
public APIMod[] AllowedMods { get; set; } = Array.Empty<APIMod>();
[JsonProperty("required_mods")]
public APIMod[] RequiredMods { get; set; } = Array.Empty<APIMod>();
public PlaylistItem()
/// <summary>
/// Used for deserialising from the API.
/// </summary>
[JsonProperty("beatmap")]
private APIBeatmap apiBeatmap
{
Beatmap.BindValueChanged(beatmap => BeatmapID = beatmap.NewValue?.OnlineID ?? -1);
// This getter is required/used internally by JSON.NET during deserialisation to do default-value comparisons. It is never used during serialisation (see: ShouldSerializeapiBeatmap()).
// It will always return a null value on deserialisation, which JSON.NET will handle gracefully.
get => (APIBeatmap)Beatmap;
set => Beatmap = value;
}
/// <summary>
/// Used for serialising to the API.
/// </summary>
[JsonProperty("beatmap_id")]
private int onlineBeatmapId => Beatmap.OnlineID;
[JsonIgnore]
public IBeatmapInfo Beatmap { get; set; } = null!;
[JsonIgnore]
public IBindable<bool> Valid => valid;
private readonly Bindable<bool> valid = new BindableBool(true);
[JsonConstructor]
private PlaylistItem()
{
}
public PlaylistItem(IBeatmapInfo beatmap)
{
Beatmap = beatmap;
}
public void MarkInvalid() => valid.Value = false;
public void MapObjects()
{
Beatmap.Value ??= apiBeatmap;
}
#region Newtonsoft.Json implicit ShouldSerialize() methods
// The properties in this region are used implicitly by Newtonsoft.Json to not serialise certain fields in some cases.
@ -82,9 +97,22 @@ namespace osu.Game.Online.Rooms
#endregion
public bool Equals(PlaylistItem other)
public PlaylistItem With(IBeatmapInfo beatmap) => new PlaylistItem(beatmap)
{
ID = ID,
OwnerID = OwnerID,
RulesetID = RulesetID,
Expired = Expired,
PlaylistOrder = PlaylistOrder,
PlayedAt = PlayedAt,
AllowedMods = AllowedMods,
RequiredMods = RequiredMods,
valid = { Value = Valid.Value },
};
public bool Equals(PlaylistItem? other)
=> ID == other?.ID
&& BeatmapID == other.BeatmapID
&& Beatmap.OnlineID == other.Beatmap.OnlineID
&& RulesetID == other.RulesetID
&& Expired == other.Expired
&& AllowedMods.SequenceEqual(other.AllowedMods)