mirror of
https://github.com/ppy/osu.git
synced 2024-11-15 13:07:24 +08:00
Merge pull request #30073 from peppy/updates-outside-of-gameplay-only-2
Avoid updates (and update notifications) from appearing in more gameplay cases
This commit is contained in:
commit
b658d9a681
@ -6,28 +6,29 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game;
|
using osu.Game;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Android
|
namespace osu.Android
|
||||||
{
|
{
|
||||||
public partial class GameplayScreenRotationLocker : Component
|
public partial class GameplayScreenRotationLocker : Component
|
||||||
{
|
{
|
||||||
private Bindable<bool> localUserPlaying = null!;
|
private IBindable<LocalUserPlayingState> localUserPlaying = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameActivity gameActivity { get; set; } = null!;
|
private OsuGameActivity gameActivity { get; set; } = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGame game)
|
private void load(ILocalUserPlayInfo localUserPlayInfo)
|
||||||
{
|
{
|
||||||
localUserPlaying = game.LocalUserPlaying.GetBoundCopy();
|
localUserPlaying = localUserPlayInfo.PlayingState.GetBoundCopy();
|
||||||
localUserPlaying.BindValueChanged(updateLock, true);
|
localUserPlaying.BindValueChanged(updateLock, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLock(ValueChangedEvent<bool> userPlaying)
|
private void updateLock(ValueChangedEvent<LocalUserPlayingState> userPlaying)
|
||||||
{
|
{
|
||||||
gameActivity.RunOnUiThread(() =>
|
gameActivity.RunOnUiThread(() =>
|
||||||
{
|
{
|
||||||
gameActivity.RequestedOrientation = userPlaying.NewValue ? ScreenOrientation.Locked : gameActivity.DefaultOrientation;
|
gameActivity.RequestedOrientation = userPlaying.NewValue != LocalUserPlayingState.NotPlaying ? ScreenOrientation.Locked : gameActivity.DefaultOrientation;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ namespace osu.Desktop.Updater
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private ILocalUserPlayInfo? localUserInfo { get; set; }
|
private ILocalUserPlayInfo? localUserInfo { get; set; }
|
||||||
|
|
||||||
|
private bool isInGameplay => localUserInfo?.PlayingState.Value != LocalUserPlayingState.NotPlaying;
|
||||||
|
|
||||||
private UpdateInfo? pendingUpdate;
|
private UpdateInfo? pendingUpdate;
|
||||||
|
|
||||||
public VelopackUpdateManager()
|
public VelopackUpdateManager()
|
||||||
@ -43,7 +45,7 @@ namespace osu.Desktop.Updater
|
|||||||
|
|
||||||
protected override async Task<bool> PerformUpdateCheck() => await checkForUpdateAsync().ConfigureAwait(false);
|
protected override async Task<bool> PerformUpdateCheck() => await checkForUpdateAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
private async Task<bool> checkForUpdateAsync(UpdateProgressNotification? notification = null)
|
private async Task<bool> checkForUpdateAsync()
|
||||||
{
|
{
|
||||||
// whether to check again in 30 minutes. generally only if there's an error or no update was found (yet).
|
// whether to check again in 30 minutes. generally only if there's an error or no update was found (yet).
|
||||||
bool scheduleRecheck = false;
|
bool scheduleRecheck = false;
|
||||||
@ -51,10 +53,10 @@ namespace osu.Desktop.Updater
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Avoid any kind of update checking while gameplay is running.
|
// Avoid any kind of update checking while gameplay is running.
|
||||||
if (localUserInfo?.IsPlaying.Value == true)
|
if (isInGameplay)
|
||||||
{
|
{
|
||||||
scheduleRecheck = true;
|
scheduleRecheck = true;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we should probably be checking if there's a more recent update, rather than shortcutting here.
|
// TODO: we should probably be checking if there's a more recent update, rather than shortcutting here.
|
||||||
@ -84,27 +86,22 @@ namespace osu.Desktop.Updater
|
|||||||
}
|
}
|
||||||
|
|
||||||
// An update is found, let's notify the user and start downloading it.
|
// An update is found, let's notify the user and start downloading it.
|
||||||
if (notification == null)
|
UpdateProgressNotification notification = new UpdateProgressNotification
|
||||||
{
|
{
|
||||||
notification = new UpdateProgressNotification
|
CompletionClickAction = () =>
|
||||||
{
|
{
|
||||||
CompletionClickAction = () =>
|
Task.Run(restartToApplyUpdate);
|
||||||
{
|
return true;
|
||||||
Task.Run(restartToApplyUpdate);
|
},
|
||||||
return true;
|
};
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
Schedule(() => notificationOverlay.Post(notification));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
runOutsideOfGameplay(() => notificationOverlay.Post(notification));
|
||||||
notification.StartDownload();
|
notification.StartDownload();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await updateManager.DownloadUpdatesAsync(pendingUpdate, p => notification.Progress = p / 100f).ConfigureAwait(false);
|
await updateManager.DownloadUpdatesAsync(pendingUpdate, p => notification.Progress = p / 100f).ConfigureAwait(false);
|
||||||
|
runOutsideOfGameplay(() => notification.State = ProgressNotificationState.Completed);
|
||||||
notification.State = ProgressNotificationState.Completed;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -131,6 +128,17 @@ namespace osu.Desktop.Updater
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void runOutsideOfGameplay(Action action)
|
||||||
|
{
|
||||||
|
if (isInGameplay)
|
||||||
|
{
|
||||||
|
Scheduler.AddDelayed(() => runOutsideOfGameplay(action), 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task restartToApplyUpdate()
|
private async Task restartToApplyUpdate()
|
||||||
{
|
{
|
||||||
await updateManager.WaitExitThenApplyUpdatesAsync(pendingUpdate?.TargetFullRelease).ConfigureAwait(false);
|
await updateManager.WaitExitThenApplyUpdatesAsync(pendingUpdate?.TargetFullRelease).ConfigureAwait(false);
|
||||||
|
@ -13,7 +13,7 @@ namespace osu.Desktop.Windows
|
|||||||
public partial class GameplayWinKeyBlocker : Component
|
public partial class GameplayWinKeyBlocker : Component
|
||||||
{
|
{
|
||||||
private Bindable<bool> disableWinKey = null!;
|
private Bindable<bool> disableWinKey = null!;
|
||||||
private IBindable<bool> localUserPlaying = null!;
|
private IBindable<LocalUserPlayingState> localUserPlaying = null!;
|
||||||
private IBindable<bool> isActive = null!;
|
private IBindable<bool> isActive = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
@ -22,7 +22,7 @@ namespace osu.Desktop.Windows
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(ILocalUserPlayInfo localUserInfo, OsuConfigManager config)
|
private void load(ILocalUserPlayInfo localUserInfo, OsuConfigManager config)
|
||||||
{
|
{
|
||||||
localUserPlaying = localUserInfo.IsPlaying.GetBoundCopy();
|
localUserPlaying = localUserInfo.PlayingState.GetBoundCopy();
|
||||||
localUserPlaying.BindValueChanged(_ => updateBlocking());
|
localUserPlaying.BindValueChanged(_ => updateBlocking());
|
||||||
|
|
||||||
isActive = host.IsActive.GetBoundCopy();
|
isActive = host.IsActive.GetBoundCopy();
|
||||||
@ -34,7 +34,7 @@ namespace osu.Desktop.Windows
|
|||||||
|
|
||||||
private void updateBlocking()
|
private void updateBlocking()
|
||||||
{
|
{
|
||||||
bool shouldDisable = isActive.Value && disableWinKey.Value && localUserPlaying.Value;
|
bool shouldDisable = isActive.Value && disableWinKey.Value && localUserPlaying.Value == LocalUserPlayingState.Playing;
|
||||||
|
|
||||||
if (shouldDisable)
|
if (shouldDisable)
|
||||||
host.InputThread.Scheduler.Add(WindowsKey.Disable);
|
host.InputThread.Scheduler.Add(WindowsKey.Disable);
|
||||||
|
@ -22,9 +22,9 @@ namespace osu.Game.Tests.Database
|
|||||||
[HeadlessTest]
|
[HeadlessTest]
|
||||||
public partial class BackgroundDataStoreProcessorTests : OsuTestScene, ILocalUserPlayInfo
|
public partial class BackgroundDataStoreProcessorTests : OsuTestScene, ILocalUserPlayInfo
|
||||||
{
|
{
|
||||||
public IBindable<bool> IsPlaying => isPlaying;
|
public IBindable<LocalUserPlayingState> PlayingState => isPlaying;
|
||||||
|
|
||||||
private readonly Bindable<bool> isPlaying = new Bindable<bool>();
|
private readonly Bindable<LocalUserPlayingState> isPlaying = new Bindable<LocalUserPlayingState>();
|
||||||
|
|
||||||
private BeatmapSetInfo importedSet = null!;
|
private BeatmapSetInfo importedSet = null!;
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ namespace osu.Game.Tests.Database
|
|||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public void SetUpSteps()
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
AddStep("Set not playing", () => isPlaying.Value = false);
|
AddStep("Set not playing", () => isPlaying.Value = LocalUserPlayingState.NotPlaying);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -89,7 +89,7 @@ namespace osu.Game.Tests.Database
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("Set playing", () => isPlaying.Value = true);
|
AddStep("Set playing", () => isPlaying.Value = LocalUserPlayingState.Playing);
|
||||||
|
|
||||||
AddStep("Reset difficulty", () =>
|
AddStep("Reset difficulty", () =>
|
||||||
{
|
{
|
||||||
@ -117,7 +117,7 @@ namespace osu.Game.Tests.Database
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("Set not playing", () => isPlaying.Value = false);
|
AddStep("Set not playing", () => isPlaying.Value = LocalUserPlayingState.NotPlaying);
|
||||||
|
|
||||||
AddUntilStep("wait for difficulties repopulated", () =>
|
AddUntilStep("wait for difficulties repopulated", () =>
|
||||||
{
|
{
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Input;
|
using osu.Game.Input;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Input
|
namespace osu.Game.Tests.Input
|
||||||
@ -15,9 +17,20 @@ namespace osu.Game.Tests.Input
|
|||||||
[HeadlessTest]
|
[HeadlessTest]
|
||||||
public partial class ConfineMouseTrackerTest : OsuGameTestScene
|
public partial class ConfineMouseTrackerTest : OsuGameTestScene
|
||||||
{
|
{
|
||||||
|
private readonly Bindable<LocalUserPlayingState> playingState = new Bindable<LocalUserPlayingState>();
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private FrameworkConfigManager frameworkConfigManager { get; set; } = null!;
|
private FrameworkConfigManager frameworkConfigManager { get; set; } = null!;
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
|
// a bit dodgy.
|
||||||
|
AddStep("bind playing state", () => ((IBindable<LocalUserPlayingState>)playingState).BindTo(((ILocalUserPlayInfo)Game).PlayingState));
|
||||||
|
}
|
||||||
|
|
||||||
[TestCase(WindowMode.Windowed)]
|
[TestCase(WindowMode.Windowed)]
|
||||||
[TestCase(WindowMode.Borderless)]
|
[TestCase(WindowMode.Borderless)]
|
||||||
public void TestDisableConfining(WindowMode windowMode)
|
public void TestDisableConfining(WindowMode windowMode)
|
||||||
@ -88,7 +101,7 @@ namespace osu.Game.Tests.Input
|
|||||||
=> AddStep($"set {mode} game-side", () => Game.LocalConfig.SetValue(OsuSetting.ConfineMouseMode, mode));
|
=> AddStep($"set {mode} game-side", () => Game.LocalConfig.SetValue(OsuSetting.ConfineMouseMode, mode));
|
||||||
|
|
||||||
private void setLocalUserPlayingTo(bool playing)
|
private void setLocalUserPlayingTo(bool playing)
|
||||||
=> AddStep($"local user {(playing ? "playing" : "not playing")}", () => Game.LocalUserPlaying.Value = playing);
|
=> AddStep($"local user {(playing ? "playing" : "not playing")}", () => playingState.Value = playing ? LocalUserPlayingState.Playing : LocalUserPlayingState.NotPlaying);
|
||||||
|
|
||||||
private void gameSideModeIs(OsuConfineMouseMode mode)
|
private void gameSideModeIs(OsuConfineMouseMode mode)
|
||||||
=> AddAssert($"mode is {mode} game-side", () => Game.LocalConfig.Get<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode) == mode);
|
=> AddAssert($"mode is {mode} game-side", () => Game.LocalConfig.Get<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode) == mode);
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
@ -12,7 +10,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
public partial class TestSceneOverlayActivation : OsuPlayerTestScene
|
public partial class TestSceneOverlayActivation : OsuPlayerTestScene
|
||||||
{
|
{
|
||||||
protected new OverlayTestPlayer Player => base.Player as OverlayTestPlayer;
|
protected new OverlayTestPlayer Player => (OverlayTestPlayer)base.Player;
|
||||||
|
|
||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
{
|
{
|
||||||
|
@ -25,14 +25,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Cached(typeof(ILocalUserPlayInfo))]
|
[Cached(typeof(ILocalUserPlayInfo))]
|
||||||
private ILocalUserPlayInfo localUserInfo;
|
private ILocalUserPlayInfo localUserInfo;
|
||||||
|
|
||||||
private readonly Bindable<bool> localUserPlaying = new Bindable<bool>();
|
private readonly Bindable<LocalUserPlayingState> playingState = new Bindable<LocalUserPlayingState>();
|
||||||
|
|
||||||
private TextBox textBox => chatDisplay.ChildrenOfType<TextBox>().First();
|
private TextBox textBox => chatDisplay.ChildrenOfType<TextBox>().First();
|
||||||
|
|
||||||
public TestSceneGameplayChatDisplay()
|
public TestSceneGameplayChatDisplay()
|
||||||
{
|
{
|
||||||
var mockLocalUserInfo = new Mock<ILocalUserPlayInfo>();
|
var mockLocalUserInfo = new Mock<ILocalUserPlayInfo>();
|
||||||
mockLocalUserInfo.SetupGet(i => i.IsPlaying).Returns(localUserPlaying);
|
mockLocalUserInfo.SetupGet(i => i.PlayingState).Returns(playingState);
|
||||||
|
|
||||||
localUserInfo = mockLocalUserInfo.Object;
|
localUserInfo = mockLocalUserInfo.Object;
|
||||||
}
|
}
|
||||||
@ -124,6 +124,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddAssert($"chat {(isFocused ? "focused" : "not focused")}", () => textBox.HasFocus == isFocused);
|
AddAssert($"chat {(isFocused ? "focused" : "not focused")}", () => textBox.HasFocus == isFocused);
|
||||||
|
|
||||||
private void setLocalUserPlaying(bool playing) =>
|
private void setLocalUserPlaying(bool playing) =>
|
||||||
AddStep($"local user {(playing ? "playing" : "not playing")}", () => localUserPlaying.Value = playing);
|
AddStep($"local user {(playing ? "playing" : "not playing")}", () => playingState.Value = playing ? LocalUserPlayingState.Playing : LocalUserPlayingState.NotPlaying);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,7 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
// Importantly, also sleep if high performance session is active.
|
// Importantly, also sleep if high performance session is active.
|
||||||
// If we don't do this, memory usage can become runaway due to GC running in a more lenient mode.
|
// If we don't do this, memory usage can become runaway due to GC running in a more lenient mode.
|
||||||
while (localUserPlayInfo?.IsPlaying.Value == true || highPerformanceSessionManager?.IsSessionActive == true)
|
while (localUserPlayInfo?.PlayingState.Value != LocalUserPlayingState.NotPlaying || highPerformanceSessionManager?.IsSessionActive == true)
|
||||||
{
|
{
|
||||||
Logger.Log("Background processing sleeping due to active gameplay...");
|
Logger.Log("Background processing sleeping due to active gameplay...");
|
||||||
Thread.Sleep(TimeToSleepDuringGameplay);
|
Thread.Sleep(TimeToSleepDuringGameplay);
|
||||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Input
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connects <see cref="OsuSetting.ConfineMouseMode"/> with <see cref="FrameworkSetting.ConfineMouseMode"/>.
|
/// Connects <see cref="OsuSetting.ConfineMouseMode"/> with <see cref="FrameworkSetting.ConfineMouseMode"/>.
|
||||||
/// If <see cref="OsuGame.LocalUserPlaying"/> is true, we should also confine the mouse cursor if it has been
|
/// If <see cref="ILocalUserPlayInfo.PlayingState"/> is playing, we should also confine the mouse cursor if it has been
|
||||||
/// requested with <see cref="OsuConfineMouseMode.DuringGameplay"/>.
|
/// requested with <see cref="OsuConfineMouseMode.DuringGameplay"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ConfineMouseTracker : Component
|
public partial class ConfineMouseTracker : Component
|
||||||
@ -25,7 +25,7 @@ namespace osu.Game.Input
|
|||||||
private Bindable<bool> frameworkMinimiseOnFocusLossInFullscreen;
|
private Bindable<bool> frameworkMinimiseOnFocusLossInFullscreen;
|
||||||
|
|
||||||
private Bindable<OsuConfineMouseMode> osuConfineMode;
|
private Bindable<OsuConfineMouseMode> osuConfineMode;
|
||||||
private IBindable<bool> localUserPlaying;
|
private IBindable<LocalUserPlayingState> localUserPlaying;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(ILocalUserPlayInfo localUserInfo, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager)
|
private void load(ILocalUserPlayInfo localUserInfo, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager)
|
||||||
@ -37,7 +37,7 @@ namespace osu.Game.Input
|
|||||||
frameworkMinimiseOnFocusLossInFullscreen.BindValueChanged(_ => updateConfineMode());
|
frameworkMinimiseOnFocusLossInFullscreen.BindValueChanged(_ => updateConfineMode());
|
||||||
|
|
||||||
osuConfineMode = osuConfigManager.GetBindable<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode);
|
osuConfineMode = osuConfigManager.GetBindable<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode);
|
||||||
localUserPlaying = localUserInfo.IsPlaying.GetBoundCopy();
|
localUserPlaying = localUserInfo.PlayingState.GetBoundCopy();
|
||||||
|
|
||||||
osuConfineMode.ValueChanged += _ => updateConfineMode();
|
osuConfineMode.ValueChanged += _ => updateConfineMode();
|
||||||
localUserPlaying.BindValueChanged(_ => updateConfineMode(), true);
|
localUserPlaying.BindValueChanged(_ => updateConfineMode(), true);
|
||||||
@ -63,7 +63,7 @@ namespace osu.Game.Input
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OsuConfineMouseMode.DuringGameplay:
|
case OsuConfineMouseMode.DuringGameplay:
|
||||||
frameworkConfineMode.Value = localUserPlaying.Value ? ConfineMouseMode.Always : ConfineMouseMode.Never;
|
frameworkConfineMode.Value = localUserPlaying.Value == LocalUserPlayingState.Playing ? ConfineMouseMode.Always : ConfineMouseMode.Never;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OsuConfineMouseMode.Always:
|
case OsuConfineMouseMode.Always:
|
||||||
|
@ -3,15 +3,16 @@
|
|||||||
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Input
|
namespace osu.Game.Input
|
||||||
{
|
{
|
||||||
public partial class OsuUserInputManager : UserInputManager
|
public partial class OsuUserInputManager : UserInputManager
|
||||||
{
|
{
|
||||||
protected override bool AllowRightClickFromLongTouch => !LocalUserPlaying.Value;
|
protected override bool AllowRightClickFromLongTouch => PlayingState.Value != LocalUserPlayingState.Playing;
|
||||||
|
|
||||||
public readonly BindableBool LocalUserPlaying = new BindableBool();
|
public readonly IBindable<LocalUserPlayingState> PlayingState = new Bindable<LocalUserPlayingState>();
|
||||||
|
|
||||||
internal OsuUserInputManager()
|
internal OsuUserInputManager()
|
||||||
{
|
{
|
||||||
|
@ -175,14 +175,9 @@ namespace osu.Game
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly IBindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
public readonly IBindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
||||||
|
|
||||||
/// <summary>
|
IBindable<LocalUserPlayingState> ILocalUserPlayInfo.PlayingState => playingState;
|
||||||
/// Whether the local user is currently interacting with the game in a way that should not be interrupted.
|
|
||||||
/// </summary>
|
private readonly Bindable<LocalUserPlayingState> playingState = new Bindable<LocalUserPlayingState>();
|
||||||
/// <remarks>
|
|
||||||
/// This is exclusively managed by <see cref="Player"/>. If other components are mutating this state, a more
|
|
||||||
/// resilient method should be used to ensure correct state.
|
|
||||||
/// </remarks>
|
|
||||||
public Bindable<bool> LocalUserPlaying = new BindableBool();
|
|
||||||
|
|
||||||
protected OsuScreenStack ScreenStack;
|
protected OsuScreenStack ScreenStack;
|
||||||
|
|
||||||
@ -302,7 +297,7 @@ namespace osu.Game
|
|||||||
protected override UserInputManager CreateUserInputManager()
|
protected override UserInputManager CreateUserInputManager()
|
||||||
{
|
{
|
||||||
var userInputManager = base.CreateUserInputManager();
|
var userInputManager = base.CreateUserInputManager();
|
||||||
(userInputManager as OsuUserInputManager)?.LocalUserPlaying.BindTo(LocalUserPlaying);
|
(userInputManager as OsuUserInputManager)?.PlayingState.BindTo(playingState);
|
||||||
return userInputManager;
|
return userInputManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,11 +386,11 @@ namespace osu.Game
|
|||||||
// Transfer any runtime changes back to configuration file.
|
// Transfer any runtime changes back to configuration file.
|
||||||
SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString();
|
SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString();
|
||||||
|
|
||||||
LocalUserPlaying.BindValueChanged(p =>
|
playingState.BindValueChanged(p =>
|
||||||
{
|
{
|
||||||
BeatmapManager.PauseImports = p.NewValue;
|
BeatmapManager.PauseImports = p.NewValue != LocalUserPlayingState.NotPlaying;
|
||||||
SkinManager.PauseImports = p.NewValue;
|
SkinManager.PauseImports = p.NewValue != LocalUserPlayingState.NotPlaying;
|
||||||
ScoreManager.PauseImports = p.NewValue;
|
ScoreManager.PauseImports = p.NewValue != LocalUserPlayingState.NotPlaying;
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true);
|
IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true);
|
||||||
@ -1553,6 +1548,16 @@ namespace osu.Game
|
|||||||
scope.SetTag(@"screen", newScreen?.GetType().ReadableName() ?? @"none");
|
scope.SetTag(@"screen", newScreen?.GetType().ReadableName() ?? @"none");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
switch (current)
|
||||||
|
{
|
||||||
|
case Player player:
|
||||||
|
player.PlayingState.UnbindFrom(playingState);
|
||||||
|
|
||||||
|
// reset for sanity.
|
||||||
|
playingState.Value = LocalUserPlayingState.NotPlaying;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (newScreen)
|
switch (newScreen)
|
||||||
{
|
{
|
||||||
case IntroScreen intro:
|
case IntroScreen intro:
|
||||||
@ -1565,14 +1570,15 @@ namespace osu.Game
|
|||||||
versionManager?.Show();
|
versionManager?.Show();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Player player:
|
||||||
|
player.PlayingState.BindTo(playingState);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
versionManager?.Hide();
|
versionManager?.Hide();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset on screen change for sanity.
|
|
||||||
LocalUserPlaying.Value = false;
|
|
||||||
|
|
||||||
if (current is IOsuScreen currentOsuScreen)
|
if (current is IOsuScreen currentOsuScreen)
|
||||||
{
|
{
|
||||||
OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode);
|
OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode);
|
||||||
@ -1621,7 +1627,5 @@ namespace osu.Game
|
|||||||
if (newScreen == null)
|
if (newScreen == null)
|
||||||
Exit();
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
IBindable<bool> ILocalUserPlayInfo.IsPlaying => LocalUserPlaying;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ namespace osu.Game.Overlays
|
|||||||
apiUser.BindValueChanged(_ => Schedule(() =>
|
apiUser.BindValueChanged(_ => Schedule(() =>
|
||||||
{
|
{
|
||||||
if (api.IsLoggedIn)
|
if (api.IsLoggedIn)
|
||||||
replaceResultsAreaContent(Drawable.Empty());
|
replaceResultsAreaContent(Empty());
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
Height = LineHeight,
|
Height = LineHeight,
|
||||||
Colour = colourProvider?.Background5 ?? Colour4.White,
|
Colour = colourProvider?.Background5 ?? Colour4.White,
|
||||||
},
|
},
|
||||||
Drawable.Empty(),
|
Empty(),
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreRight,
|
Anchor = Anchor.CentreRight,
|
||||||
@ -87,7 +87,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Drawable.Empty(),
|
Empty(),
|
||||||
new Circle
|
new Circle
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
|
@ -66,7 +66,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Size = new Vector2(SettingsSidebar.EXPANDED_WIDTH);
|
Size = new Vector2(EXPANDED_WIDTH);
|
||||||
|
|
||||||
Padding = new MarginPadding(40);
|
Padding = new MarginPadding(40);
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private ILocalUserPlayInfo localUserInfo { get; set; }
|
private ILocalUserPlayInfo localUserInfo { get; set; }
|
||||||
|
|
||||||
private readonly IBindable<bool> localUserPlaying = new Bindable<bool>();
|
private readonly IBindable<LocalUserPlayingState> localUserPlaying = new Bindable<LocalUserPlayingState>();
|
||||||
|
|
||||||
public override bool PropagatePositionalInputSubTree => !localUserPlaying.Value;
|
public override bool PropagatePositionalInputSubTree => localUserPlaying.Value != LocalUserPlayingState.Playing;
|
||||||
|
|
||||||
public Bindable<bool> Expanded = new Bindable<bool>();
|
public Bindable<bool> Expanded = new Bindable<bool>();
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
if (localUserInfo != null)
|
if (localUserInfo != null)
|
||||||
localUserPlaying.BindTo(localUserInfo.IsPlaying);
|
localUserPlaying.BindTo(localUserInfo.PlayingState);
|
||||||
|
|
||||||
localUserPlaying.BindValueChanged(playing =>
|
localUserPlaying.BindValueChanged(playing =>
|
||||||
{
|
{
|
||||||
@ -67,7 +67,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
TextBox.HoldFocus = false;
|
TextBox.HoldFocus = false;
|
||||||
|
|
||||||
// only hold focus (after sending a message) during breaks
|
// only hold focus (after sending a message) during breaks
|
||||||
TextBox.ReleaseFocusOnCommit = playing.NewValue;
|
TextBox.ReleaseFocusOnCommit = playing.NewValue == LocalUserPlayingState.Playing;
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
Expanded.BindValueChanged(_ => updateExpandedState(), true);
|
Expanded.BindValueChanged(_ => updateExpandedState(), true);
|
||||||
|
@ -10,8 +10,8 @@ namespace osu.Game.Screens.Play
|
|||||||
public interface ILocalUserPlayInfo
|
public interface ILocalUserPlayInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the local user is currently playing.
|
/// Whether the local user is currently interacting (playing) with the game in a way that should not be interrupted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IBindable<bool> IsPlaying { get; }
|
IBindable<LocalUserPlayingState> PlayingState { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
osu.Game/Screens/Play/LocalUserPlayingState.cs
Normal file
23
osu.Game/Screens/Play/LocalUserPlayingState.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play
|
||||||
|
{
|
||||||
|
public enum LocalUserPlayingState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The local player is not current in gameplay. If watching a replay, gameplay always remains in this state.
|
||||||
|
/// </summary>
|
||||||
|
NotPlaying,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The local player is in a break, paused, or failed but still at the gameplay screen.
|
||||||
|
/// </summary>
|
||||||
|
Break,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The local user is in active gameplay.
|
||||||
|
/// </summary>
|
||||||
|
Playing,
|
||||||
|
}
|
||||||
|
}
|
@ -94,6 +94,7 @@ namespace osu.Game.Screens.Play
|
|||||||
public IBindable<bool> LocalUserPlaying => localUserPlaying;
|
public IBindable<bool> LocalUserPlaying => localUserPlaying;
|
||||||
|
|
||||||
private readonly Bindable<bool> localUserPlaying = new Bindable<bool>();
|
private readonly Bindable<bool> localUserPlaying = new Bindable<bool>();
|
||||||
|
private readonly Bindable<LocalUserPlayingState> playingState = new Bindable<LocalUserPlayingState>();
|
||||||
|
|
||||||
public int RestartCount;
|
public int RestartCount;
|
||||||
|
|
||||||
@ -231,9 +232,6 @@ namespace osu.Game.Screens.Play
|
|||||||
if (game != null)
|
if (game != null)
|
||||||
gameActive.BindTo(game.IsActive);
|
gameActive.BindTo(game.IsActive);
|
||||||
|
|
||||||
if (game is OsuGame osuGame)
|
|
||||||
LocalUserPlaying.BindTo(osuGame.LocalUserPlaying);
|
|
||||||
|
|
||||||
DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods);
|
DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods);
|
||||||
dependencies.CacheAs(DrawableRuleset);
|
dependencies.CacheAs(DrawableRuleset);
|
||||||
|
|
||||||
@ -510,9 +508,16 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private void updateGameplayState()
|
private void updateGameplayState()
|
||||||
{
|
{
|
||||||
bool inGameplay = !DrawableRuleset.HasReplayLoaded.Value && !DrawableRuleset.IsPaused.Value && !breakTracker.IsBreakTime.Value && !GameplayState.HasFailed;
|
bool inGameplay = !DrawableRuleset.HasReplayLoaded.Value && !GameplayState.HasPassed && !GameplayState.HasFailed;
|
||||||
OverlayActivationMode.Value = inGameplay ? OverlayActivation.Disabled : OverlayActivation.UserTriggered;
|
bool inBreak = breakTracker.IsBreakTime.Value || DrawableRuleset.IsPaused.Value;
|
||||||
localUserPlaying.Value = inGameplay;
|
|
||||||
|
if (inGameplay)
|
||||||
|
playingState.Value = inBreak ? LocalUserPlayingState.Break : LocalUserPlayingState.Playing;
|
||||||
|
else
|
||||||
|
playingState.Value = LocalUserPlayingState.NotPlaying;
|
||||||
|
|
||||||
|
localUserPlaying.Value = playingState.Value == LocalUserPlayingState.Playing;
|
||||||
|
OverlayActivationMode.Value = playingState.Value == LocalUserPlayingState.Playing ? OverlayActivation.Disabled : OverlayActivation.UserTriggered;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSampleDisabledState()
|
private void updateSampleDisabledState()
|
||||||
@ -1279,6 +1284,6 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
IBindable<bool> ISamplePlaybackDisabler.SamplePlaybackDisabled => samplePlaybackDisabled;
|
IBindable<bool> ISamplePlaybackDisabler.SamplePlaybackDisabled => samplePlaybackDisabled;
|
||||||
|
|
||||||
IBindable<bool> ILocalUserPlayInfo.IsPlaying => LocalUserPlaying;
|
public IBindable<LocalUserPlayingState> PlayingState => playingState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user