1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 12:42:54 +08:00

Merge remote-tracking branch 'upstream/master' into fix-network-stalls

This commit is contained in:
Dean Herbert 2019-11-06 19:06:28 +09:00
commit 91bcb5d4a7
9 changed files with 53 additions and 21 deletions

View File

@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Edit
editorClock = clock; editorClock = clock;
} }
public override void HandleMovement(MoveSelectionEvent moveEvent) public override bool HandleMovement(MoveSelectionEvent moveEvent)
{ {
var maniaBlueprint = (ManiaSelectionBlueprint)moveEvent.Blueprint; var maniaBlueprint = (ManiaSelectionBlueprint)moveEvent.Blueprint;
int lastColumn = maniaBlueprint.DrawableObject.HitObject.Column; int lastColumn = maniaBlueprint.DrawableObject.HitObject.Column;
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Edit
performDragMovement(moveEvent); performDragMovement(moveEvent);
performColumnMovement(lastColumn, moveEvent); performColumnMovement(lastColumn, moveEvent);
base.HandleMovement(moveEvent); return true;
} }
/// <summary> /// <summary>

View File

@ -4,13 +4,34 @@
using System.Linq; using System.Linq;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
namespace osu.Game.Rulesets.Osu.Edit namespace osu.Game.Rulesets.Osu.Edit
{ {
public class OsuSelectionHandler : SelectionHandler public class OsuSelectionHandler : SelectionHandler
{ {
public override void HandleMovement(MoveSelectionEvent moveEvent) public override bool HandleMovement(MoveSelectionEvent moveEvent)
{ {
Vector2 minPosition = new Vector2(float.MaxValue, float.MaxValue);
Vector2 maxPosition = new Vector2(float.MinValue, float.MinValue);
// Go through all hitobjects to make sure they would remain in the bounds of the editor after movement, before any movement is attempted
foreach (var h in SelectedHitObjects.OfType<OsuHitObject>())
{
if (h is Spinner)
{
// Spinners don't support position adjustments
continue;
}
// Stacking is not considered
minPosition = Vector2.ComponentMin(minPosition, Vector2.ComponentMin(h.EndPosition + moveEvent.InstantDelta, h.Position + moveEvent.InstantDelta));
maxPosition = Vector2.ComponentMax(maxPosition, Vector2.ComponentMax(h.EndPosition + moveEvent.InstantDelta, h.Position + moveEvent.InstantDelta));
}
if (minPosition.X < 0 || minPosition.Y < 0 || maxPosition.X > DrawWidth || maxPosition.Y > DrawHeight)
return false;
foreach (var h in SelectedHitObjects.OfType<OsuHitObject>()) foreach (var h in SelectedHitObjects.OfType<OsuHitObject>())
{ {
if (h is Spinner) if (h is Spinner)
@ -22,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Edit
h.Position += moveEvent.InstantDelta; h.Position += moveEvent.InstantDelta;
} }
base.HandleMovement(moveEvent); return true;
} }
} }
} }

View File

@ -237,6 +237,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("player not exited", () => Player.IsCurrentScreen()); AddUntilStep("player not exited", () => Player.IsCurrentScreen());
AddStep("exit", () => Player.Exit()); AddStep("exit", () => Player.Exit());
confirmExited(); confirmExited();
confirmNoTrackAdjustments();
} }
private void confirmPaused() private void confirmPaused()
@ -258,6 +259,11 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("player exited", () => !Player.IsCurrentScreen()); AddUntilStep("player exited", () => !Player.IsCurrentScreen());
} }
private void confirmNoTrackAdjustments()
{
AddAssert("track has no adjustments", () => Beatmap.Value.Track.AggregateFrequency.Value == 1);
}
private void restart() => AddStep("restart", () => Player.Restart()); private void restart() => AddStep("restart", () => Player.Restart());
private void pause() => AddStep("pause", () => Player.Pause()); private void pause() => AddStep("pause", () => Player.Pause());
private void resume() => AddStep("resume", () => Player.Resume()); private void resume() => AddStep("resume", () => Player.Resume());

View File

@ -14,11 +14,13 @@ namespace osu.Game.Audio
{ {
/// <summary> /// <summary>
/// Invoked when this <see cref="PreviewTrack"/> has stopped playing. /// Invoked when this <see cref="PreviewTrack"/> has stopped playing.
/// Not invoked in a thread-safe context.
/// </summary> /// </summary>
public event Action Stopped; public event Action Stopped;
/// <summary> /// <summary>
/// Invoked when this <see cref="PreviewTrack"/> has started playing. /// Invoked when this <see cref="PreviewTrack"/> has started playing.
/// Not invoked in a thread-safe context.
/// </summary> /// </summary>
public event Action Started; public event Action Started;
@ -30,7 +32,7 @@ namespace osu.Game.Audio
{ {
track = GetTrack(); track = GetTrack();
if (track != null) if (track != null)
track.Completed += () => Schedule(Stop); track.Completed += Stop;
} }
/// <summary> /// <summary>
@ -94,6 +96,7 @@ namespace osu.Game.Audio
hasStarted = false; hasStarted = false;
track.Stop(); track.Stop();
Stopped?.Invoke(); Stopped?.Invoke();
} }

View File

@ -46,18 +46,18 @@ namespace osu.Game.Audio
{ {
var track = CreatePreviewTrack(beatmapSetInfo, trackStore); var track = CreatePreviewTrack(beatmapSetInfo, trackStore);
track.Started += () => track.Started += () => Schedule(() =>
{ {
current?.Stop(); current?.Stop();
current = track; current = track;
audio.Tracks.AddAdjustment(AdjustableProperty.Volume, muteBindable); audio.Tracks.AddAdjustment(AdjustableProperty.Volume, muteBindable);
}; });
track.Stopped += () => track.Stopped += () => Schedule(() =>
{ {
current = null; current = null;
audio.Tracks.RemoveAdjustment(AdjustableProperty.Volume, muteBindable); audio.Tracks.RemoveAdjustment(AdjustableProperty.Volume, muteBindable);
}; });
return track; return track;
} }

View File

@ -367,7 +367,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
(Vector2 snappedPosition, double snappedTime) = composer.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime); (Vector2 snappedPosition, double snappedTime) = composer.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime);
// Move the hitobjects // Move the hitobjects
selectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprint, startPosition, ToScreenSpace(snappedPosition))); if (!selectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprint, startPosition, ToScreenSpace(snappedPosition))))
return true;
// Apply the start time at the newly snapped-to position // Apply the start time at the newly snapped-to position
double offset = snappedTime - draggedObject.StartTime; double offset = snappedTime - draggedObject.StartTime;

View File

@ -68,9 +68,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// Handles the selected <see cref="DrawableHitObject"/>s being moved. /// Handles the selected <see cref="DrawableHitObject"/>s being moved.
/// </summary> /// </summary>
/// <param name="moveEvent">The move event.</param> /// <param name="moveEvent">The move event.</param>
public virtual void HandleMovement(MoveSelectionEvent moveEvent) /// <returns>Whether any <see cref="DrawableHitObject"/>s were moved.</returns>
{ public virtual bool HandleMovement(MoveSelectionEvent moveEvent) => false;
}
public bool OnPressed(PlatformAction action) public bool OnPressed(PlatformAction action)
{ {

View File

@ -162,16 +162,12 @@ namespace osu.Game.Screens.Play
if (sourceClock != beatmap.Track) if (sourceClock != beatmap.Track)
return; return;
removeSourceClockAdjustments();
sourceClock = new TrackVirtual(beatmap.Track.Length); sourceClock = new TrackVirtual(beatmap.Track.Length);
adjustableClock.ChangeSource(sourceClock); adjustableClock.ChangeSource(sourceClock);
} }
public void ResetLocalAdjustments()
{
// In the case of replays, we may have changed the playback rate.
UserPlaybackRate.Value = 1;
}
protected override void Update() protected override void Update()
{ {
if (!IsPaused.Value) if (!IsPaused.Value)
@ -198,6 +194,14 @@ namespace osu.Game.Screens.Play
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
removeSourceClockAdjustments();
sourceClock = null;
}
private void removeSourceClockAdjustments()
{
sourceClock.ResetSpeedAdjustments();
(sourceClock as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); (sourceClock as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust);
} }
} }

View File

@ -536,8 +536,6 @@ namespace osu.Game.Screens.Play
return true; return true;
} }
GameplayClockContainer.ResetLocalAdjustments();
// GameplayClockContainer performs seeks / start / stop operations on the beatmap's track. // GameplayClockContainer performs seeks / start / stop operations on the beatmap's track.
// as we are no longer the current screen, we cannot guarantee the track is still usable. // as we are no longer the current screen, we cannot guarantee the track is still usable.
GameplayClockContainer.StopUsingBeatmapClock(); GameplayClockContainer.StopUsingBeatmapClock();