Merge branch 'master' into fix-quick-delete-crash

This commit is contained in:
Dean Herbert 2020-11-16 13:54:54 +09:00 committed by GitHub
commit 7b79b9b9c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 81 additions and 27 deletions

View File

@ -207,11 +207,17 @@ private bool moveSelection(Vector2 delta)
Quad quad = getSurroundingQuad(hitObjects);
if (quad.TopLeft.X + delta.X < 0 ||
quad.TopLeft.Y + delta.Y < 0 ||
quad.BottomRight.X + delta.X > DrawWidth ||
quad.BottomRight.Y + delta.Y > DrawHeight)
return false;
Vector2 newTopLeft = quad.TopLeft + delta;
if (newTopLeft.X < 0)
delta.X -= newTopLeft.X;
if (newTopLeft.Y < 0)
delta.Y -= newTopLeft.Y;
Vector2 newBottomRight = quad.BottomRight + delta;
if (newBottomRight.X > DrawWidth)
delta.X -= newBottomRight.X - DrawWidth;
if (newBottomRight.Y > DrawHeight)
delta.Y -= newBottomRight.Y - DrawHeight;
foreach (var h in hitObjects)
h.Position += delta;

View File

@ -167,6 +167,21 @@ public void TestEnsureMutingCorrectly(bool stopAnyPlaying)
AddAssert("game not muted", () => audio.Tracks.AggregateVolume.Value != 0);
}
[Test]
public void TestOwnerNotRegistered()
{
PreviewTrack track = null;
AddStep("get track", () => Add(new TestTrackOwner(track = getTrack(), registerAsOwner: false)));
AddUntilStep("wait for loaded", () => track.IsLoaded);
AddStep("start track", () => track.Start());
AddUntilStep("track is running", () => track.IsRunning);
AddStep("cancel from anyone", () => trackManager.StopAnyPlaying(this));
AddAssert("track stopped", () => !track.IsRunning);
}
private TestPreviewTrack getTrack() => (TestPreviewTrack)trackManager.Get(null);
private TestPreviewTrack getOwnedTrack()
@ -181,10 +196,12 @@ private TestPreviewTrack getOwnedTrack()
private class TestTrackOwner : CompositeDrawable, IPreviewTrackOwner
{
private readonly PreviewTrack track;
private readonly bool registerAsOwner;
public TestTrackOwner(PreviewTrack track)
public TestTrackOwner(PreviewTrack track, bool registerAsOwner = true)
{
this.track = track;
this.registerAsOwner = registerAsOwner;
}
[BackgroundDependencyLoader]
@ -196,7 +213,8 @@ private void load()
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.CacheAs<IPreviewTrackOwner>(this);
if (registerAsOwner)
dependencies.CacheAs<IPreviewTrackOwner>(this);
return dependencies;
}
}

View File

@ -144,9 +144,9 @@ public bool Selected
if (selected)
{
selectionBox.Show();
if (editor)
if (editor && editorInfo != null)
editorInfo.Selected.Value = Match;
else
else if (ladderInfo != null)
ladderInfo.CurrentMatch.Value = Match;
}
else

View File

@ -11,6 +11,7 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.IO.Stores;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
namespace osu.Game.Audio
@ -76,7 +77,7 @@ public PreviewTrack Get(BeatmapSetInfo beatmapSetInfo)
/// <param name="source">The <see cref="IPreviewTrackOwner"/> which may be the owner of the <see cref="PreviewTrack"/>.</param>
public void StopAnyPlaying(IPreviewTrackOwner source)
{
if (CurrentTrack == null || CurrentTrack.Owner != source)
if (CurrentTrack == null || (CurrentTrack.Owner != null && CurrentTrack.Owner != source))
return;
CurrentTrack.Stop();
@ -86,11 +87,12 @@ public void StopAnyPlaying(IPreviewTrackOwner source)
/// <summary>
/// Creates the <see cref="TrackManagerPreviewTrack"/>.
/// </summary>
protected virtual TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) => new TrackManagerPreviewTrack(beatmapSetInfo, trackStore);
protected virtual TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) =>
new TrackManagerPreviewTrack(beatmapSetInfo, trackStore);
public class TrackManagerPreviewTrack : PreviewTrack
{
[Resolved]
[Resolved(canBeNull: true)]
public IPreviewTrackOwner Owner { get; private set; }
private readonly BeatmapSetInfo beatmapSetInfo;
@ -102,6 +104,12 @@ public TrackManagerPreviewTrack(BeatmapSetInfo beatmapSetInfo, ITrackStore track
this.trackManager = trackManager;
}
protected override void LoadComplete()
{
base.LoadComplete();
Logger.Log($"A {nameof(PreviewTrack)} was created without a containing {nameof(IPreviewTrackOwner)}. An owner should be added for correct behaviour.");
}
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
}

View File

@ -46,12 +46,15 @@ private void load()
{
if (modelInfo.NewValue == null)
attachDownload(null);
else if (manager.IsAvailableLocally(modelInfo.NewValue))
else if (manager?.IsAvailableLocally(modelInfo.NewValue) == true)
State.Value = DownloadState.LocallyAvailable;
else
attachDownload(manager.GetExistingDownload(modelInfo.NewValue));
attachDownload(manager?.GetExistingDownload(modelInfo.NewValue));
}, true);
if (manager == null)
return;
managerDownloadBegan = manager.DownloadBegan.GetBoundCopy();
managerDownloadBegan.BindValueChanged(downloadBegan);
managerDownloadFailed = manager.DownloadFailed.GetBoundCopy();

View File

@ -248,7 +248,9 @@ protected virtual void Reset()
[BackgroundDependencyLoader]
private void load()
{
apiState.BindTo(api.State);
if (api != null)
apiState.BindTo(api.State);
apiState.BindValueChanged(onlineStateChanged, true);
}
@ -303,7 +305,7 @@ protected void UpdateScores()
PlaceholderState = PlaceholderState.NetworkFailure;
});
api.Queue(getScoresRequest);
api?.Queue(getScoresRequest);
});
}

View File

@ -30,7 +30,7 @@ public class ScreenWarning : AccountCreationScreen
public override void OnEntering(IScreen last)
{
if (string.IsNullOrEmpty(api.ProvidedUsername))
if (string.IsNullOrEmpty(api?.ProvidedUsername))
{
this.FadeOut();
this.Push(new ScreenEntry());
@ -43,7 +43,7 @@ public override void OnEntering(IScreen last)
[BackgroundDependencyLoader(true)]
private void load(OsuColour colours, OsuGame game, TextureStore textures)
{
if (string.IsNullOrEmpty(api.ProvidedUsername))
if (string.IsNullOrEmpty(api?.ProvidedUsername))
return;
InternalChildren = new Drawable[]

View File

@ -217,7 +217,7 @@ private class LoginForm : FillFlowContainer
private void performLogin()
{
if (!string.IsNullOrEmpty(username.Text) && !string.IsNullOrEmpty(password.Text))
api.Login(username.Text, password.Text);
api?.Login(username.Text, password.Text);
else
shakeSignIn.Shake();
}

View File

@ -76,7 +76,7 @@ private void checkCanComplete()
// a dialog may be blocking the execution for now.
if (checkForDialog(current)) return;
game.CloseAllOverlays(false);
game?.CloseAllOverlays(false);
// we may already be at the target screen type.
if (validScreens.Contains(getCurrentScreen().GetType()) && !beatmap.Disabled)

View File

@ -105,7 +105,7 @@ private void addDrawable(HitObjectLifetimeEntry entry)
{
Debug.Assert(!drawableMap.ContainsKey(entry));
var drawable = pooledObjectProvider.GetPooledDrawableRepresentation(entry.HitObject);
var drawable = pooledObjectProvider?.GetPooledDrawableRepresentation(entry.HitObject);
if (drawable == null)
throw new InvalidOperationException($"A drawable representation could not be retrieved for hitobject type: {entry.HitObject.GetType().ReadableName()}.");

View File

@ -456,6 +456,9 @@ private bool moveCurrentSelection(DragEvent e)
if (movementBlueprint == null)
return false;
if (snapProvider == null)
return true;
Debug.Assert(movementBlueprintOriginalPosition != null);
HitObject draggedObject = movementBlueprint.HitObject;

View File

@ -110,7 +110,7 @@ public SelectionBox CreateSelectionBox()
/// </summary>
protected virtual void OnOperationBegan()
{
ChangeHandler.BeginChange();
ChangeHandler?.BeginChange();
}
/// <summary>
@ -118,7 +118,7 @@ protected virtual void OnOperationBegan()
/// </summary>
protected virtual void OnOperationEnded()
{
ChangeHandler.EndChange();
ChangeHandler?.EndChange();
}
#region User Input Handling

View File

@ -96,7 +96,7 @@ protected override void Update()
if (lastDragEvent != null)
OnDrag(lastDragEvent);
if (Composer != null)
if (Composer != null && timeline != null)
{
Composer.Playfield.PastLifetimeExtension = timeline.VisibleRange / 2;
Composer.Playfield.FutureLifetimeExtension = timeline.VisibleRange / 2;

View File

@ -128,7 +128,7 @@ protected override void LoadComplete()
controlPointGroups.BindCollectionChanged((sender, args) =>
{
table.ControlGroups = controlPointGroups;
changeHandler.SaveState();
changeHandler?.SaveState();
}, true);
}

View File

@ -59,6 +59,9 @@ private void updateFilter()
{
scheduledFilterUpdate?.Cancel();
if (filter == null)
return;
filter.Value = new FilterCriteria
{
SearchString = Search.Current.Value ?? string.Empty,

View File

@ -13,6 +13,7 @@
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Screens;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics;
@ -35,7 +36,8 @@
namespace osu.Game.Screens.Play
{
public class Spectator : OsuScreen
[Cached(typeof(IPreviewTrackOwner))]
public class Spectator : OsuScreen, IPreviewTrackOwner
{
private readonly User targetUser;
@ -62,6 +64,9 @@ public class Spectator : OsuScreen
[Resolved]
private RulesetStore rulesets { get; set; }
[Resolved]
private PreviewTrackManager previewTrackManager { get; set; }
private Score score;
private readonly object scoreLock = new object();
@ -275,6 +280,7 @@ private void clearDisplay()
{
watchButton.Enabled.Value = false;
beatmapPanelContainer.Clear();
previewTrackManager.StopAnyPlaying(this);
}
private void attemptStart()
@ -326,7 +332,6 @@ private void showBeatmapPanel(SpectatorState state)
{
if (state?.BeatmapID == null)
{
beatmapPanelContainer.Clear();
onlineBeatmap = null;
return;
}
@ -359,6 +364,12 @@ private void checkForAutomaticDownload()
beatmaps.Download(onlineBeatmap);
}
public override bool OnExiting(IScreen next)
{
previewTrackManager.StopAnyPlaying(this);
return base.OnExiting(next);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);