1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-27 14:52:55 +08:00

Make WorkingBeatmap non-disposable

This commit is contained in:
smoogipoo 2020-02-10 17:01:41 +09:00
parent 51e2a934bd
commit cef682aa03
4 changed files with 39 additions and 47 deletions

View File

@ -37,9 +37,9 @@ namespace osu.Game.Tests
trackStore = audioManager.GetTrackStore(getZipReader()); trackStore = audioManager.GetTrackStore(getZipReader());
} }
protected override void Dispose(bool isDisposing) ~WaveformTestBeatmap()
{ {
base.Dispose(isDisposing); // Remove the track store from the audio manager
trackStore?.Dispose(); trackStore?.Dispose();
} }

View File

@ -17,10 +17,11 @@ using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Skinning; using osu.Game.Skinning;
using osu.Framework.Graphics.Video; using osu.Framework.Graphics.Video;
using osu.Framework.Logging;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
public abstract class WorkingBeatmap : IWorkingBeatmap, IDisposable public abstract class WorkingBeatmap : IWorkingBeatmap
{ {
public readonly BeatmapInfo BeatmapInfo; public readonly BeatmapInfo BeatmapInfo;
@ -133,11 +134,29 @@ namespace osu.Game.Beatmaps
return converted; return converted;
} }
public override string ToString() => BeatmapInfo.ToString(); private CancellationTokenSource loadCancellation = new CancellationTokenSource();
public bool BeatmapLoaded => beatmapLoadTask?.IsCompleted ?? false; /// <summary>
/// Beings loading the contents of this <see cref="WorkingBeatmap"/> asynchronously.
/// </summary>
public void BeginAsyncLoad()
{
loadBeatmapAsync();
}
public Task<IBeatmap> LoadBeatmapAsync() => beatmapLoadTask ??= Task.Factory.StartNew(() => /// <summary>
/// Cancels the asynchronous loading of the contents of this <see cref="WorkingBeatmap"/>.
/// </summary>
public void CancelAsyncLoad()
{
loadCancellation?.Cancel();
loadCancellation = new CancellationTokenSource();
if (beatmapLoadTask?.IsCompleted != true)
beatmapLoadTask = null;
}
private Task<IBeatmap> loadBeatmapAsync() => beatmapLoadTask ??= Task.Factory.StartNew(() =>
{ {
// Todo: Handle cancellation during beatmap parsing // Todo: Handle cancellation during beatmap parsing
var b = GetBeatmap() ?? new Beatmap(); var b = GetBeatmap() ?? new Beatmap();
@ -149,7 +168,11 @@ namespace osu.Game.Beatmaps
b.BeatmapInfo = BeatmapInfo; b.BeatmapInfo = BeatmapInfo;
return b; return b;
}, beatmapCancellation.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }, loadCancellation.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
public override string ToString() => BeatmapInfo.ToString();
public bool BeatmapLoaded => beatmapLoadTask?.IsCompleted ?? false;
public IBeatmap Beatmap public IBeatmap Beatmap
{ {
@ -157,7 +180,7 @@ namespace osu.Game.Beatmaps
{ {
try try
{ {
return LoadBeatmapAsync().Result; return loadBeatmapAsync().Result;
} }
catch (AggregateException ae) catch (AggregateException ae)
{ {
@ -174,7 +197,6 @@ namespace osu.Game.Beatmaps
} }
} }
private readonly CancellationTokenSource beatmapCancellation = new CancellationTokenSource();
protected abstract IBeatmap GetBeatmap(); protected abstract IBeatmap GetBeatmap();
private Task<IBeatmap> beatmapLoadTask; private Task<IBeatmap> beatmapLoadTask;
@ -225,40 +247,11 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public virtual void RecycleTrack() => track.Recycle(); public virtual void RecycleTrack() => track.Recycle();
#region Disposal
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool isDisposed;
protected virtual void Dispose(bool isDisposing)
{
if (isDisposed)
return;
isDisposed = true;
// recycling logic is not here for the time being, as components which use
// retrieved objects from WorkingBeatmap may not hold a reference to the WorkingBeatmap itself.
// this should be fine as each retrieved component do have their own finalizers.
// cancelling the beatmap load is safe for now since the retrieval is a synchronous
// operation. if we add an async retrieval method this may need to be reconsidered.
beatmapCancellation?.Cancel();
total_count.Value--;
}
~WorkingBeatmap() ~WorkingBeatmap()
{ {
Dispose(false); total_count.Value--;
} }
#endregion
public class RecyclableLazy<T> public class RecyclableLazy<T>
{ {
private Lazy<T> lazy; private Lazy<T> lazy;

View File

@ -401,15 +401,14 @@ namespace osu.Game
if (nextBeatmap?.Track != null) if (nextBeatmap?.Track != null)
nextBeatmap.Track.Completed += currentTrackCompleted; nextBeatmap.Track.Completed += currentTrackCompleted;
using (var oldBeatmap = beatmap.OldValue) var oldBeatmap = beatmap.OldValue;
{
if (oldBeatmap?.Track != null) if (oldBeatmap?.Track != null)
oldBeatmap.Track.Completed -= currentTrackCompleted; oldBeatmap.Track.Completed -= currentTrackCompleted;
}
updateModDefaults(); updateModDefaults();
nextBeatmap?.LoadBeatmapAsync(); oldBeatmap?.CancelAsyncLoad();
nextBeatmap?.BeginAsyncLoad();
} }
private void modsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods) private void modsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)

View File

@ -191,9 +191,9 @@ namespace osu.Game.Tests.Visual
track = audio?.Tracks.GetVirtual(length); track = audio?.Tracks.GetVirtual(length);
} }
protected override void Dispose(bool isDisposing) ~ClockBackedTestWorkingBeatmap()
{ {
base.Dispose(isDisposing); // Remove the track store from the audio manager
store?.Dispose(); store?.Dispose();
} }