1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 07:22:54 +08:00

Merge remote-tracking branch 'upstream/master' into game-handles-links

This commit is contained in:
Dean Herbert 2019-11-03 13:04:18 +09:00
commit 5127b52c25
10 changed files with 109 additions and 40 deletions

View File

@ -38,9 +38,10 @@ namespace osu.Game.Rulesets.Osu.UI
});
}
public override void Show()
protected override void PopIn()
{
base.Show();
base.PopIn();
GameplayCursor.ActiveCursor.Hide();
cursorScaleContainer.MoveTo(GameplayCursor.ActiveCursor.Position);
clickToResumeCursor.Appear();
@ -55,13 +56,13 @@ namespace osu.Game.Rulesets.Osu.UI
}
}
public override void Hide()
protected override void PopOut()
{
base.PopOut();
localCursorContainer?.Expire();
localCursorContainer = null;
GameplayCursor.ActiveCursor.Show();
base.Hide();
GameplayCursor?.ActiveCursor?.Show();
}
protected override bool OnHover(HoverEvent e) => true;

View File

@ -69,6 +69,24 @@ namespace osu.Game.Tests.Visual.Gameplay
confirmClockRunning(true);
}
[Test]
public void TestPauseWithResumeOverlay()
{
AddStep("move cursor to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre));
AddUntilStep("wait for hitobjects", () => Player.ScoreProcessor.Health.Value < 1);
pauseAndConfirm();
resume();
confirmClockRunning(false);
confirmPauseOverlayShown(false);
pauseAndConfirm();
AddUntilStep("resume overlay is not active", () => Player.DrawableRuleset.ResumeOverlay.State.Value == Visibility.Hidden);
confirmPaused();
}
[Test]
public void TestResumeWithResumeOverlaySkipped()
{

View File

@ -392,8 +392,15 @@ namespace osu.Game.Beatmaps
req.Failure += e => { LogForModel(set, $"Online retrieval failed for {beatmap} ({e.Message})"); };
// intentionally blocking to limit web request concurrency
req.Perform(api);
try
{
// intentionally blocking to limit web request concurrency
req.Perform(api);
}
catch (Exception e)
{
LogForModel(set, $"Online retrieval failed for {beatmap} ({e.Message})");
}
}
}
}

View File

@ -86,16 +86,7 @@ namespace osu.Game.Database
}, TaskCreationOptions.LongRunning);
};
request.Failure += error =>
{
DownloadFailed?.Invoke(request);
if (error is OperationCanceledException) return;
notification.State = ProgressNotificationState.Cancelled;
Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!");
currentDownloads.Remove(request);
};
request.Failure += triggerFailure;
notification.CancelRequested += () =>
{
@ -108,11 +99,31 @@ namespace osu.Game.Database
currentDownloads.Add(request);
PostNotification?.Invoke(notification);
Task.Factory.StartNew(() => request.Perform(api), TaskCreationOptions.LongRunning);
Task.Factory.StartNew(() =>
{
try
{
request.Perform(api);
}
catch (Exception error)
{
triggerFailure(error);
}
}, TaskCreationOptions.LongRunning);
DownloadBegan?.Invoke(request);
return true;
void triggerFailure(Exception error)
{
DownloadFailed?.Invoke(request);
if (error is OperationCanceledException) return;
notification.State = ProgressNotificationState.Cancelled;
Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!");
currentDownloads.Remove(request);
}
}
public bool IsAvailableLocally(TModel model) => CheckLocalAvailability(model, modelStore.ConsumableItems.Where(m => !m.DeletePending));

View File

@ -44,7 +44,17 @@ namespace osu.Game.Overlays.Changelog
req.Failure += _ => complete = true;
// This is done on a separate thread to support cancellation below
Task.Run(() => req.Perform(api));
Task.Run(() =>
{
try
{
req.Perform(api);
}
catch
{
complete = true;
}
});
while (!complete)
{

View File

@ -170,6 +170,7 @@ namespace osu.Game.Overlays
var tcs = new TaskCompletionSource<bool>();
var req = new GetChangelogRequest();
req.Success += res => Schedule(() =>
{
// remap streams to builds to ensure model equality
@ -183,8 +184,22 @@ namespace osu.Game.Overlays
tcs.SetResult(true);
});
req.Failure += _ => initialFetchTask = null;
req.Perform(API);
req.Failure += _ =>
{
initialFetchTask = null;
tcs.SetResult(false);
};
try
{
req.Perform(API);
}
catch
{
initialFetchTask = null;
tcs.SetResult(false);
}
await tcs.Task;
});

View File

@ -239,6 +239,12 @@ namespace osu.Game.Rulesets.UI
continueResume();
}
public override void CancelResume()
{
// called if the user pauses while the resume overlay is open
ResumeOverlay?.Hide();
}
/// <summary>
/// Creates and adds the visual representation of a <see cref="TObject"/> to this <see cref="DrawableRuleset{TObject}"/>.
/// </summary>
@ -453,6 +459,11 @@ namespace osu.Game.Rulesets.UI
/// <param name="continueResume">The action to run when resuming is to be completed.</param>
public abstract void RequestResume(Action continueResume);
/// <summary>
/// Invoked when the user requests to pause while the resume overlay is active.
/// </summary>
public abstract void CancelResume();
/// <summary>
/// Create a <see cref="ScoreProcessor"/> for the associated ruleset and link with this
/// <see cref="DrawableRuleset"/>.

View File

@ -13,12 +13,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
{
public class ScrollingHitObjectContainer : HitObjectContainer
{
/// <summary>
/// A multiplier applied to the length of the scrolling area to determine a safe default lifetime end for hitobjects.
/// This is only used to limit the lifetime end within reason, as proper lifetime management should be implemented on hitobjects themselves.
/// </summary>
private const float safe_lifetime_end_multiplier = 2;
private readonly IBindable<double> timeRange = new BindableDouble();
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
@ -123,28 +117,22 @@ namespace osu.Game.Rulesets.UI.Scrolling
if (cached.IsValid)
return;
double endTime = hitObject.HitObject.StartTime;
if (hitObject.HitObject is IHasEndTime e)
{
endTime = e.EndTime;
switch (direction.Value)
{
case ScrollingDirection.Up:
case ScrollingDirection.Down:
hitObject.Height = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime, timeRange.Value, scrollLength);
hitObject.Height = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, e.EndTime, timeRange.Value, scrollLength);
break;
case ScrollingDirection.Left:
case ScrollingDirection.Right:
hitObject.Width = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime, timeRange.Value, scrollLength);
hitObject.Width = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, e.EndTime, timeRange.Value, scrollLength);
break;
}
}
hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, endTime, timeRange.Value, scrollLength);
foreach (var obj in hitObject.NestedHitObjects)
{
computeInitialStateRecursive(obj);

View File

@ -167,14 +167,17 @@ namespace osu.Game.Screens.Multi
public void APIStateChanged(IAPIProvider api, APIState state)
{
if (state != APIState.Online)
forcefullyExit();
Schedule(forcefullyExit);
}
private void forcefullyExit()
{
// This is temporary since we don't currently have a way to force screens to be exited
if (this.IsCurrentScreen())
this.Exit();
{
while (this.IsCurrentScreen())
this.Exit();
}
else
{
this.MakeCurrent();

View File

@ -443,7 +443,12 @@ namespace osu.Game.Screens.Play
{
if (!canPause) return;
IsResuming = false;
if (IsResuming)
{
DrawableRuleset.CancelResume();
IsResuming = false;
}
GameplayClockContainer.Stop();
PauseOverlay.Show();
lastPauseActionTime = GameplayClockContainer.GameplayClock.CurrentTime;