mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 16:12:57 +08:00
Merge branch 'master' into fix-quick-delete-crash
This commit is contained in:
commit
7b79b9b9c1
@ -207,11 +207,17 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
Quad quad = getSurroundingQuad(hitObjects);
|
Quad quad = getSurroundingQuad(hitObjects);
|
||||||
|
|
||||||
if (quad.TopLeft.X + delta.X < 0 ||
|
Vector2 newTopLeft = quad.TopLeft + delta;
|
||||||
quad.TopLeft.Y + delta.Y < 0 ||
|
if (newTopLeft.X < 0)
|
||||||
quad.BottomRight.X + delta.X > DrawWidth ||
|
delta.X -= newTopLeft.X;
|
||||||
quad.BottomRight.Y + delta.Y > DrawHeight)
|
if (newTopLeft.Y < 0)
|
||||||
return false;
|
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)
|
foreach (var h in hitObjects)
|
||||||
h.Position += delta;
|
h.Position += delta;
|
||||||
|
@ -167,6 +167,21 @@ namespace osu.Game.Tests.Visual.Components
|
|||||||
AddAssert("game not muted", () => audio.Tracks.AggregateVolume.Value != 0);
|
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 getTrack() => (TestPreviewTrack)trackManager.Get(null);
|
||||||
|
|
||||||
private TestPreviewTrack getOwnedTrack()
|
private TestPreviewTrack getOwnedTrack()
|
||||||
@ -181,10 +196,12 @@ namespace osu.Game.Tests.Visual.Components
|
|||||||
private class TestTrackOwner : CompositeDrawable, IPreviewTrackOwner
|
private class TestTrackOwner : CompositeDrawable, IPreviewTrackOwner
|
||||||
{
|
{
|
||||||
private readonly PreviewTrack track;
|
private readonly PreviewTrack track;
|
||||||
|
private readonly bool registerAsOwner;
|
||||||
|
|
||||||
public TestTrackOwner(PreviewTrack track)
|
public TestTrackOwner(PreviewTrack track, bool registerAsOwner = true)
|
||||||
{
|
{
|
||||||
this.track = track;
|
this.track = track;
|
||||||
|
this.registerAsOwner = registerAsOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -196,7 +213,8 @@ namespace osu.Game.Tests.Visual.Components
|
|||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
if (registerAsOwner)
|
||||||
|
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,9 +144,9 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
if (selected)
|
if (selected)
|
||||||
{
|
{
|
||||||
selectionBox.Show();
|
selectionBox.Show();
|
||||||
if (editor)
|
if (editor && editorInfo != null)
|
||||||
editorInfo.Selected.Value = Match;
|
editorInfo.Selected.Value = Match;
|
||||||
else
|
else if (ladderInfo != null)
|
||||||
ladderInfo.CurrentMatch.Value = Match;
|
ladderInfo.CurrentMatch.Value = Match;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Audio.Track;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Audio
|
namespace osu.Game.Audio
|
||||||
@ -76,7 +77,7 @@ namespace osu.Game.Audio
|
|||||||
/// <param name="source">The <see cref="IPreviewTrackOwner"/> which may be the owner of the <see cref="PreviewTrack"/>.</param>
|
/// <param name="source">The <see cref="IPreviewTrackOwner"/> which may be the owner of the <see cref="PreviewTrack"/>.</param>
|
||||||
public void StopAnyPlaying(IPreviewTrackOwner source)
|
public void StopAnyPlaying(IPreviewTrackOwner source)
|
||||||
{
|
{
|
||||||
if (CurrentTrack == null || CurrentTrack.Owner != source)
|
if (CurrentTrack == null || (CurrentTrack.Owner != null && CurrentTrack.Owner != source))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CurrentTrack.Stop();
|
CurrentTrack.Stop();
|
||||||
@ -86,11 +87,12 @@ namespace osu.Game.Audio
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the <see cref="TrackManagerPreviewTrack"/>.
|
/// Creates the <see cref="TrackManagerPreviewTrack"/>.
|
||||||
/// </summary>
|
/// </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
|
public class TrackManagerPreviewTrack : PreviewTrack
|
||||||
{
|
{
|
||||||
[Resolved]
|
[Resolved(canBeNull: true)]
|
||||||
public IPreviewTrackOwner Owner { get; private set; }
|
public IPreviewTrackOwner Owner { get; private set; }
|
||||||
|
|
||||||
private readonly BeatmapSetInfo beatmapSetInfo;
|
private readonly BeatmapSetInfo beatmapSetInfo;
|
||||||
@ -102,6 +104,12 @@ namespace osu.Game.Audio
|
|||||||
this.trackManager = trackManager;
|
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");
|
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,12 +46,15 @@ namespace osu.Game.Online
|
|||||||
{
|
{
|
||||||
if (modelInfo.NewValue == null)
|
if (modelInfo.NewValue == null)
|
||||||
attachDownload(null);
|
attachDownload(null);
|
||||||
else if (manager.IsAvailableLocally(modelInfo.NewValue))
|
else if (manager?.IsAvailableLocally(modelInfo.NewValue) == true)
|
||||||
State.Value = DownloadState.LocallyAvailable;
|
State.Value = DownloadState.LocallyAvailable;
|
||||||
else
|
else
|
||||||
attachDownload(manager.GetExistingDownload(modelInfo.NewValue));
|
attachDownload(manager?.GetExistingDownload(modelInfo.NewValue));
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
if (manager == null)
|
||||||
|
return;
|
||||||
|
|
||||||
managerDownloadBegan = manager.DownloadBegan.GetBoundCopy();
|
managerDownloadBegan = manager.DownloadBegan.GetBoundCopy();
|
||||||
managerDownloadBegan.BindValueChanged(downloadBegan);
|
managerDownloadBegan.BindValueChanged(downloadBegan);
|
||||||
managerDownloadFailed = manager.DownloadFailed.GetBoundCopy();
|
managerDownloadFailed = manager.DownloadFailed.GetBoundCopy();
|
||||||
|
@ -248,7 +248,9 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
apiState.BindTo(api.State);
|
if (api != null)
|
||||||
|
apiState.BindTo(api.State);
|
||||||
|
|
||||||
apiState.BindValueChanged(onlineStateChanged, true);
|
apiState.BindValueChanged(onlineStateChanged, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +305,7 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
PlaceholderState = PlaceholderState.NetworkFailure;
|
PlaceholderState = PlaceholderState.NetworkFailure;
|
||||||
});
|
});
|
||||||
|
|
||||||
api.Queue(getScoresRequest);
|
api?.Queue(getScoresRequest);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Overlays.AccountCreation
|
|||||||
|
|
||||||
public override void OnEntering(IScreen last)
|
public override void OnEntering(IScreen last)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(api.ProvidedUsername))
|
if (string.IsNullOrEmpty(api?.ProvidedUsername))
|
||||||
{
|
{
|
||||||
this.FadeOut();
|
this.FadeOut();
|
||||||
this.Push(new ScreenEntry());
|
this.Push(new ScreenEntry());
|
||||||
@ -43,7 +43,7 @@ namespace osu.Game.Overlays.AccountCreation
|
|||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuColour colours, OsuGame game, TextureStore textures)
|
private void load(OsuColour colours, OsuGame game, TextureStore textures)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(api.ProvidedUsername))
|
if (string.IsNullOrEmpty(api?.ProvidedUsername))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
|
@ -217,7 +217,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
private void performLogin()
|
private void performLogin()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(username.Text) && !string.IsNullOrEmpty(password.Text))
|
if (!string.IsNullOrEmpty(username.Text) && !string.IsNullOrEmpty(password.Text))
|
||||||
api.Login(username.Text, password.Text);
|
api?.Login(username.Text, password.Text);
|
||||||
else
|
else
|
||||||
shakeSignIn.Shake();
|
shakeSignIn.Shake();
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ namespace osu.Game
|
|||||||
// a dialog may be blocking the execution for now.
|
// a dialog may be blocking the execution for now.
|
||||||
if (checkForDialog(current)) return;
|
if (checkForDialog(current)) return;
|
||||||
|
|
||||||
game.CloseAllOverlays(false);
|
game?.CloseAllOverlays(false);
|
||||||
|
|
||||||
// we may already be at the target screen type.
|
// we may already be at the target screen type.
|
||||||
if (validScreens.Contains(getCurrentScreen().GetType()) && !beatmap.Disabled)
|
if (validScreens.Contains(getCurrentScreen().GetType()) && !beatmap.Disabled)
|
||||||
|
@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
Debug.Assert(!drawableMap.ContainsKey(entry));
|
Debug.Assert(!drawableMap.ContainsKey(entry));
|
||||||
|
|
||||||
var drawable = pooledObjectProvider.GetPooledDrawableRepresentation(entry.HitObject);
|
var drawable = pooledObjectProvider?.GetPooledDrawableRepresentation(entry.HitObject);
|
||||||
if (drawable == null)
|
if (drawable == null)
|
||||||
throw new InvalidOperationException($"A drawable representation could not be retrieved for hitobject type: {entry.HitObject.GetType().ReadableName()}.");
|
throw new InvalidOperationException($"A drawable representation could not be retrieved for hitobject type: {entry.HitObject.GetType().ReadableName()}.");
|
||||||
|
|
||||||
|
@ -456,6 +456,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
if (movementBlueprint == null)
|
if (movementBlueprint == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (snapProvider == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
Debug.Assert(movementBlueprintOriginalPosition != null);
|
Debug.Assert(movementBlueprintOriginalPosition != null);
|
||||||
|
|
||||||
HitObject draggedObject = movementBlueprint.HitObject;
|
HitObject draggedObject = movementBlueprint.HitObject;
|
||||||
|
@ -110,7 +110,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnOperationBegan()
|
protected virtual void OnOperationBegan()
|
||||||
{
|
{
|
||||||
ChangeHandler.BeginChange();
|
ChangeHandler?.BeginChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnOperationEnded()
|
protected virtual void OnOperationEnded()
|
||||||
{
|
{
|
||||||
ChangeHandler.EndChange();
|
ChangeHandler?.EndChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region User Input Handling
|
#region User Input Handling
|
||||||
|
@ -96,7 +96,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
if (lastDragEvent != null)
|
if (lastDragEvent != null)
|
||||||
OnDrag(lastDragEvent);
|
OnDrag(lastDragEvent);
|
||||||
|
|
||||||
if (Composer != null)
|
if (Composer != null && timeline != null)
|
||||||
{
|
{
|
||||||
Composer.Playfield.PastLifetimeExtension = timeline.VisibleRange / 2;
|
Composer.Playfield.PastLifetimeExtension = timeline.VisibleRange / 2;
|
||||||
Composer.Playfield.FutureLifetimeExtension = timeline.VisibleRange / 2;
|
Composer.Playfield.FutureLifetimeExtension = timeline.VisibleRange / 2;
|
||||||
|
@ -128,7 +128,7 @@ namespace osu.Game.Screens.Edit.Timing
|
|||||||
controlPointGroups.BindCollectionChanged((sender, args) =>
|
controlPointGroups.BindCollectionChanged((sender, args) =>
|
||||||
{
|
{
|
||||||
table.ControlGroups = controlPointGroups;
|
table.ControlGroups = controlPointGroups;
|
||||||
changeHandler.SaveState();
|
changeHandler?.SaveState();
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
{
|
{
|
||||||
scheduledFilterUpdate?.Cancel();
|
scheduledFilterUpdate?.Cancel();
|
||||||
|
|
||||||
|
if (filter == null)
|
||||||
|
return;
|
||||||
|
|
||||||
filter.Value = new FilterCriteria
|
filter.Value = new FilterCriteria
|
||||||
{
|
{
|
||||||
SearchString = Search.Current.Value ?? string.Empty,
|
SearchString = Search.Current.Value ?? string.Empty,
|
||||||
|
@ -13,6 +13,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
@ -35,7 +36,8 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
public class Spectator : OsuScreen
|
[Cached(typeof(IPreviewTrackOwner))]
|
||||||
|
public class Spectator : OsuScreen, IPreviewTrackOwner
|
||||||
{
|
{
|
||||||
private readonly User targetUser;
|
private readonly User targetUser;
|
||||||
|
|
||||||
@ -62,6 +64,9 @@ namespace osu.Game.Screens.Play
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private RulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private PreviewTrackManager previewTrackManager { get; set; }
|
||||||
|
|
||||||
private Score score;
|
private Score score;
|
||||||
|
|
||||||
private readonly object scoreLock = new object();
|
private readonly object scoreLock = new object();
|
||||||
@ -275,6 +280,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
watchButton.Enabled.Value = false;
|
watchButton.Enabled.Value = false;
|
||||||
beatmapPanelContainer.Clear();
|
beatmapPanelContainer.Clear();
|
||||||
|
previewTrackManager.StopAnyPlaying(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attemptStart()
|
private void attemptStart()
|
||||||
@ -326,7 +332,6 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
if (state?.BeatmapID == null)
|
if (state?.BeatmapID == null)
|
||||||
{
|
{
|
||||||
beatmapPanelContainer.Clear();
|
|
||||||
onlineBeatmap = null;
|
onlineBeatmap = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -359,6 +364,12 @@ namespace osu.Game.Screens.Play
|
|||||||
beatmaps.Download(onlineBeatmap);
|
beatmaps.Download(onlineBeatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool OnExiting(IScreen next)
|
||||||
|
{
|
||||||
|
previewTrackManager.StopAnyPlaying(this);
|
||||||
|
return base.OnExiting(next);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
Loading…
Reference in New Issue
Block a user