mirror of
https://github.com/ppy/osu.git
synced 2025-03-15 17:47:18 +08:00
Merge pull request #13230 from peppy/non-nullable-beatmapset-files
Make `BeatmapSet.Files` non-nullable
This commit is contained in:
commit
46b6f49a92
@ -24,6 +24,8 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
protected override bool EditorComponentsReady => Editor.ChildrenOfType<SetupScreen>().SingleOrDefault()?.IsLoaded == true;
|
||||
|
||||
protected override bool IsolateSavingFromDatabase => false;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmapManager { get; set; }
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
@ -241,12 +240,10 @@ namespace osu.Game.Beatmaps
|
||||
/// <param name="info">The <see cref="BeatmapInfo"/> to save the content against. The file referenced by <see cref="BeatmapInfo.Path"/> will be replaced.</param>
|
||||
/// <param name="beatmapContent">The <see cref="IBeatmap"/> content to write.</param>
|
||||
/// <param name="beatmapSkin">The beatmap <see cref="ISkin"/> content to write, null if to be omitted.</param>
|
||||
public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin beatmapSkin = null)
|
||||
public virtual void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin beatmapSkin = null)
|
||||
{
|
||||
var setInfo = info.BeatmapSet;
|
||||
|
||||
Debug.Assert(setInfo.Files != null);
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
||||
@ -283,25 +280,17 @@ namespace osu.Game.Beatmaps
|
||||
/// Retrieve a <see cref="WorkingBeatmap"/> instance for the provided <see cref="BeatmapInfo"/>
|
||||
/// </summary>
|
||||
/// <param name="beatmapInfo">The beatmap to lookup.</param>
|
||||
/// <param name="previous">The currently loaded <see cref="WorkingBeatmap"/>. Allows for optimisation where elements are shared with the new beatmap. May be returned if beatmapInfo requested matches</param>
|
||||
/// <returns>A <see cref="WorkingBeatmap"/> instance correlating to the provided <see cref="BeatmapInfo"/>.</returns>
|
||||
public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap previous = null)
|
||||
public virtual WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo)
|
||||
{
|
||||
if (beatmapInfo?.ID > 0 && previous != null && previous.BeatmapInfo?.ID == beatmapInfo.ID)
|
||||
return previous;
|
||||
|
||||
if (beatmapInfo?.BeatmapSet == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo)
|
||||
return DefaultBeatmap;
|
||||
|
||||
// force a re-query if files are not in a state which looks like the model has
|
||||
// full database information present.
|
||||
if (beatmapInfo.BeatmapSet.Files == null || beatmapInfo.BeatmapSet.Files.Count == 0)
|
||||
// if there are no files, presume the full beatmap info has not yet been fetched from the database.
|
||||
if (beatmapInfo?.BeatmapSet?.Files.Count == 0)
|
||||
{
|
||||
var info = beatmapInfo;
|
||||
beatmapInfo = QueryBeatmap(b => b.ID == info.ID);
|
||||
int lookupId = beatmapInfo.ID;
|
||||
beatmapInfo = QueryBeatmap(b => b.ID == lookupId);
|
||||
}
|
||||
|
||||
if (beatmapInfo == null)
|
||||
if (beatmapInfo?.BeatmapSet == null)
|
||||
return DefaultBeatmap;
|
||||
|
||||
lock (workingCache)
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Database;
|
||||
|
||||
@ -31,6 +32,9 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public List<BeatmapInfo> Beatmaps { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public List<BeatmapSetFileInfo> Files { get; set; } = new List<BeatmapSetFileInfo>();
|
||||
|
||||
[NotMapped]
|
||||
public BeatmapSetOnlineInfo OnlineInfo { get; set; }
|
||||
|
||||
@ -57,16 +61,14 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public string Hash { get; set; }
|
||||
|
||||
public string StoryboardFile => Files?.Find(f => f.Filename.EndsWith(".osb", StringComparison.OrdinalIgnoreCase))?.Filename;
|
||||
public string StoryboardFile => Files.Find(f => f.Filename.EndsWith(".osb", StringComparison.OrdinalIgnoreCase))?.Filename;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the storage path for the file in this beatmapset with the given filename, if any exists, otherwise null.
|
||||
/// The path returned is relative to the user file storage.
|
||||
/// </summary>
|
||||
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||
public string GetPathForFile(string filename) => Files?.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
|
||||
public List<BeatmapSetFileInfo> Files { get; set; }
|
||||
public string GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
|
||||
public override string ToString() => Metadata?.ToString() ?? base.ToString();
|
||||
|
||||
|
@ -252,7 +252,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
if (playable != null)
|
||||
{
|
||||
changeBeatmap(beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value));
|
||||
changeBeatmap(beatmaps.GetWorkingBeatmap(playable.Beatmaps.First()));
|
||||
restartTrack();
|
||||
return PreviousTrackResult.Previous;
|
||||
}
|
||||
@ -283,7 +283,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
if (playable != null)
|
||||
{
|
||||
changeBeatmap(beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value));
|
||||
changeBeatmap(beatmaps.GetWorkingBeatmap(playable.Beatmaps.First()));
|
||||
restartTrack();
|
||||
return true;
|
||||
}
|
||||
|
@ -505,12 +505,13 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
Logger.Log($"beatmap changed from \"{Beatmap.Value.BeatmapInfo}\" to \"{beatmap}\"");
|
||||
|
||||
WorkingBeatmap previous = Beatmap.Value;
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, previous);
|
||||
int? lastSetID = Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID;
|
||||
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap);
|
||||
|
||||
if (beatmap != null)
|
||||
{
|
||||
if (beatmap.BeatmapSetInfoID == previous?.BeatmapInfo.BeatmapSetInfoID)
|
||||
if (beatmap.BeatmapSetInfoID == lastSetID)
|
||||
sampleChangeDifficulty.Play();
|
||||
else
|
||||
sampleChangeBeatmap.Play();
|
||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(IBindable<WorkingBeatmap> beatmap, TextureStore textureStore)
|
||||
{
|
||||
var path = beatmap.Value.BeatmapSetInfo?.Files?.Find(f => f.Filename.Equals(Video.Path, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
var path = beatmap.Value.BeatmapSetInfo?.Files.Find(f => f.Filename.Equals(Video.Path, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
|
||||
if (path == null)
|
||||
return;
|
||||
|
@ -91,7 +91,7 @@ namespace osu.Game.Storyboards
|
||||
public Drawable CreateSpriteFromResourcePath(string path, TextureStore textureStore)
|
||||
{
|
||||
Drawable drawable = null;
|
||||
var storyboardPath = BeatmapInfo.BeatmapSet?.Files?.Find(f => f.Filename.Equals(path, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
var storyboardPath = BeatmapInfo.BeatmapSet?.Files.Find(f => f.Filename.Equals(path, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
|
||||
if (storyboardPath != null)
|
||||
drawable = new Sprite { Texture = textureStore.Get(storyboardPath) };
|
||||
|
@ -29,7 +29,6 @@ namespace osu.Game.Tests.Beatmaps
|
||||
BeatmapInfo.Ruleset = ruleset;
|
||||
BeatmapInfo.RulesetID = ruleset.ID ?? 0;
|
||||
BeatmapInfo.BeatmapSet.Metadata = BeatmapInfo.Metadata;
|
||||
BeatmapInfo.BeatmapSet.Files = new List<BeatmapSetFileInfo>();
|
||||
BeatmapInfo.BeatmapSet.Beatmaps = new List<BeatmapInfo> { BeatmapInfo };
|
||||
BeatmapInfo.Length = 75000;
|
||||
BeatmapInfo.OnlineInfo = new BeatmapOnlineInfo();
|
||||
|
@ -4,11 +4,18 @@
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.IO.Archives;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
@ -20,10 +27,20 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
protected EditorClock EditorClock { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether any saves performed by the editor should be isolate (and not persist) to the underlying <see cref="BeatmapManager"/>.
|
||||
/// </summary>
|
||||
protected virtual bool IsolateSavingFromDatabase => true;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
private void load(GameHost host, AudioManager audio, RulesetStore rulesets)
|
||||
{
|
||||
Beatmap.Value = CreateWorkingBeatmap(Ruleset.Value);
|
||||
var working = CreateWorkingBeatmap(Ruleset.Value);
|
||||
|
||||
Beatmap.Value = working;
|
||||
|
||||
if (IsolateSavingFromDatabase)
|
||||
Dependencies.CacheAs<BeatmapManager>(new TestBeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default, working));
|
||||
}
|
||||
|
||||
protected virtual bool EditorComponentsReady => Editor.ChildrenOfType<HitObjectComposer>().FirstOrDefault()?.IsLoaded == true
|
||||
@ -70,5 +87,27 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
public new bool HasUnsavedChanges => base.HasUnsavedChanges;
|
||||
}
|
||||
|
||||
private class TestBeatmapManager : BeatmapManager
|
||||
{
|
||||
private readonly WorkingBeatmap testBeatmap;
|
||||
|
||||
public TestBeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, GameHost host, WorkingBeatmap defaultBeatmap, WorkingBeatmap testBeatmap)
|
||||
: base(storage, contextFactory, rulesets, api, audioManager, host, defaultBeatmap, false)
|
||||
{
|
||||
this.testBeatmap = testBeatmap;
|
||||
}
|
||||
|
||||
protected override string ComputeHash(BeatmapSetInfo item, ArchiveReader reader = null)
|
||||
=> string.Empty;
|
||||
|
||||
public override WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo)
|
||||
=> testBeatmap;
|
||||
|
||||
public override void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin beatmapSkin = null)
|
||||
{
|
||||
// don't actually care about saving for this context.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user