mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 13:47:38 +08:00
Merge branch 'master' into moreOptionsFromSkin.ini
This commit is contained in:
commit
13f461099f
@ -1,17 +1,20 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
<option name="USE_MONO" value="0" />
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Desktop/osu.Desktop.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Desktop/osu.Desktop.csproj" />
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||||
<method />
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<Import Project="..\osu.Game.props" />
|
<Import Project="..\osu.Game.props" />
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
||||||
|
143
osu.Game.Tests/Visual/TestCasePollingComponent.cs
Normal file
143
osu.Game.Tests/Visual/TestCasePollingComponent.cs
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Online;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCasePollingComponent : OsuTestCase
|
||||||
|
{
|
||||||
|
private Container pollBox;
|
||||||
|
private TestPoller poller;
|
||||||
|
|
||||||
|
private const float safety_adjust = 1f;
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() => Schedule(() =>
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
pollBox = new Container
|
||||||
|
{
|
||||||
|
Alpha = 0,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Scale = new Vector2(0.4f),
|
||||||
|
Colour = Color4.LimeGreen,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Text = "Poll!",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestInstantPolling()
|
||||||
|
{
|
||||||
|
createPoller(true);
|
||||||
|
|
||||||
|
AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust);
|
||||||
|
checkCount(1);
|
||||||
|
checkCount(2);
|
||||||
|
checkCount(3);
|
||||||
|
|
||||||
|
AddStep("set poll interval to 5", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust * 5);
|
||||||
|
checkCount(4);
|
||||||
|
checkCount(4);
|
||||||
|
checkCount(4);
|
||||||
|
|
||||||
|
skip();
|
||||||
|
|
||||||
|
checkCount(5);
|
||||||
|
checkCount(5);
|
||||||
|
|
||||||
|
AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust);
|
||||||
|
checkCount(6);
|
||||||
|
checkCount(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Ignore("i have no idea how to fix the timing of this one")]
|
||||||
|
public void TestSlowPolling()
|
||||||
|
{
|
||||||
|
createPoller(false);
|
||||||
|
|
||||||
|
AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust * 5);
|
||||||
|
checkCount(0);
|
||||||
|
skip();
|
||||||
|
checkCount(0);
|
||||||
|
skip();
|
||||||
|
skip();
|
||||||
|
checkCount(0);
|
||||||
|
skip();
|
||||||
|
skip();
|
||||||
|
checkCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skip() => AddStep("skip", () =>
|
||||||
|
{
|
||||||
|
// could be 4 or 5 at this point due to timing discrepancies (safety_adjust @ 0.2 * 5 ~= 1)
|
||||||
|
// easiest to just ignore the value at this point and move on.
|
||||||
|
});
|
||||||
|
|
||||||
|
private void checkCount(int checkValue)
|
||||||
|
{
|
||||||
|
Logger.Log($"value is {count}");
|
||||||
|
AddAssert($"count is {checkValue}", () => count == checkValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPoller(bool instant) => AddStep("create poller", () =>
|
||||||
|
{
|
||||||
|
poller?.Expire();
|
||||||
|
|
||||||
|
Add(poller = instant ? new TestPoller() : new TestSlowPoller());
|
||||||
|
poller.OnPoll += () =>
|
||||||
|
{
|
||||||
|
pollBox.FadeOutFromOne(500);
|
||||||
|
count++;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
protected override double TimePerAction => 500;
|
||||||
|
|
||||||
|
public class TestPoller : PollingComponent
|
||||||
|
{
|
||||||
|
public event Action OnPoll;
|
||||||
|
|
||||||
|
protected override Task Poll()
|
||||||
|
{
|
||||||
|
Schedule(() => OnPoll?.Invoke());
|
||||||
|
return base.Poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestSlowPoller : TestPoller
|
||||||
|
{
|
||||||
|
protected override Task Poll() => Task.Delay((int)(TimeBetweenPolls / 2f / Clock.Rate)).ContinueWith(_ => base.Poll());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||||
|
@ -199,6 +199,12 @@ namespace osu.Game.Online.API
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Log($@"Performing request {req}", LoggingTarget.Network);
|
Logger.Log($@"Performing request {req}", LoggingTarget.Network);
|
||||||
|
req.Failure += ex =>
|
||||||
|
{
|
||||||
|
if (ex is WebException we)
|
||||||
|
handleWebException(we);
|
||||||
|
};
|
||||||
|
|
||||||
req.Perform(this);
|
req.Perform(this);
|
||||||
|
|
||||||
//we could still be in initialisation, at which point we don't want to say we're Online yet.
|
//we could still be in initialisation, at which point we don't want to say we're Online yet.
|
||||||
@ -210,37 +216,12 @@ namespace osu.Game.Online.API
|
|||||||
}
|
}
|
||||||
catch (WebException we)
|
catch (WebException we)
|
||||||
{
|
{
|
||||||
HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode
|
var removeFromQueue = handleWebException(we);
|
||||||
?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout);
|
|
||||||
|
|
||||||
// special cases for un-typed but useful message responses.
|
|
||||||
switch (we.Message)
|
|
||||||
{
|
|
||||||
case "Unauthorized":
|
|
||||||
statusCode = HttpStatusCode.Unauthorized;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (statusCode)
|
|
||||||
{
|
|
||||||
case HttpStatusCode.Unauthorized:
|
|
||||||
Logout(false);
|
|
||||||
return true;
|
|
||||||
case HttpStatusCode.RequestTimeout:
|
|
||||||
failureCount++;
|
|
||||||
log.Add($@"API failure count is now {failureCount}");
|
|
||||||
|
|
||||||
if (failureCount < 3)
|
|
||||||
//we might try again at an api level.
|
|
||||||
return false;
|
|
||||||
|
|
||||||
State = APIState.Failing;
|
|
||||||
flushQueue();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (removeFromQueue)
|
||||||
req.Fail(we);
|
req.Fail(we);
|
||||||
return true;
|
|
||||||
|
return removeFromQueue;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -276,6 +257,41 @@ namespace osu.Game.Online.API
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool handleWebException(WebException we)
|
||||||
|
{
|
||||||
|
HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode
|
||||||
|
?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout);
|
||||||
|
|
||||||
|
// special cases for un-typed but useful message responses.
|
||||||
|
switch (we.Message)
|
||||||
|
{
|
||||||
|
case "Unauthorized":
|
||||||
|
case "Forbidden":
|
||||||
|
statusCode = HttpStatusCode.Unauthorized;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (statusCode)
|
||||||
|
{
|
||||||
|
case HttpStatusCode.Unauthorized:
|
||||||
|
Logout(false);
|
||||||
|
return true;
|
||||||
|
case HttpStatusCode.RequestTimeout:
|
||||||
|
failureCount++;
|
||||||
|
log.Add($@"API failure count is now {failureCount}");
|
||||||
|
|
||||||
|
if (failureCount < 3)
|
||||||
|
//we might try again at an api level.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
State = APIState.Failing;
|
||||||
|
flushQueue();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsLoggedIn => LocalUser.Value.Id > 1;
|
public bool IsLoggedIn => LocalUser.Value.Id > 1;
|
||||||
|
|
||||||
public void Queue(APIRequest request)
|
public void Queue(APIRequest request)
|
||||||
|
@ -4,11 +4,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Threading;
|
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
@ -18,7 +17,7 @@ namespace osu.Game.Online.Chat
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Manages everything channel related
|
/// Manages everything channel related
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ChannelManager : Component, IOnlineComponent
|
public class ChannelManager : PollingComponent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The channels the player joins on startup
|
/// The channels the player joins on startup
|
||||||
@ -49,11 +48,14 @@ namespace osu.Game.Online.Chat
|
|||||||
public IBindableCollection<Channel> AvailableChannels => availableChannels;
|
public IBindableCollection<Channel> AvailableChannels => availableChannels;
|
||||||
|
|
||||||
private IAPIProvider api;
|
private IAPIProvider api;
|
||||||
private ScheduledDelegate fetchMessagesScheduleder;
|
|
||||||
|
public readonly BindableBool HighPollRate = new BindableBool();
|
||||||
|
|
||||||
public ChannelManager()
|
public ChannelManager()
|
||||||
{
|
{
|
||||||
CurrentChannel.ValueChanged += currentChannelChanged;
|
CurrentChannel.ValueChanged += currentChannelChanged;
|
||||||
|
|
||||||
|
HighPollRate.BindValueChanged(high => TimeBetweenPolls = high ? 1000 : 6000, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -360,32 +362,19 @@ namespace osu.Game.Online.Chat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void APIStateChanged(APIAccess api, APIState state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case APIState.Online:
|
|
||||||
fetchUpdates();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fetchMessagesScheduleder?.Cancel();
|
|
||||||
fetchMessagesScheduleder = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private long lastMessageId;
|
private long lastMessageId;
|
||||||
private const int update_poll_interval = 1000;
|
|
||||||
|
|
||||||
private bool channelsInitialised;
|
private bool channelsInitialised;
|
||||||
|
|
||||||
private void fetchUpdates()
|
protected override Task Poll()
|
||||||
{
|
|
||||||
fetchMessagesScheduleder?.Cancel();
|
|
||||||
fetchMessagesScheduleder = Scheduler.AddDelayed(() =>
|
|
||||||
{
|
{
|
||||||
|
if (!api.IsLoggedIn)
|
||||||
|
return base.Poll();
|
||||||
|
|
||||||
var fetchReq = new GetUpdatesRequest(lastMessageId);
|
var fetchReq = new GetUpdatesRequest(lastMessageId);
|
||||||
|
|
||||||
|
var tcs = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
fetchReq.Success += updates =>
|
fetchReq.Success += updates =>
|
||||||
{
|
{
|
||||||
if (updates?.Presence != null)
|
if (updates?.Presence != null)
|
||||||
@ -413,20 +402,20 @@ namespace osu.Game.Online.Chat
|
|||||||
initializeChannels();
|
initializeChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchUpdates();
|
tcs.SetResult(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchReq.Failure += delegate { fetchUpdates(); };
|
fetchReq.Failure += _ => tcs.SetResult(false);
|
||||||
|
|
||||||
api.Queue(fetchReq);
|
api.Queue(fetchReq);
|
||||||
}, update_poll_interval);
|
|
||||||
|
return tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(IAPIProvider api)
|
private void load(IAPIProvider api)
|
||||||
{
|
{
|
||||||
this.api = api;
|
this.api = api;
|
||||||
api.Register(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
118
osu.Game/Online/PollingComponent.cs
Normal file
118
osu.Game/Online/PollingComponent.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Threading;
|
||||||
|
|
||||||
|
namespace osu.Game.Online
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A component which requires a constant polling process.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class PollingComponent : Component
|
||||||
|
{
|
||||||
|
private double? lastTimePolled;
|
||||||
|
|
||||||
|
private ScheduledDelegate scheduledPoll;
|
||||||
|
|
||||||
|
private bool pollingActive;
|
||||||
|
|
||||||
|
private double timeBetweenPolls;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The time in milliseconds to wait between polls.
|
||||||
|
/// Setting to zero stops all polling.
|
||||||
|
/// </summary>
|
||||||
|
public double TimeBetweenPolls
|
||||||
|
{
|
||||||
|
get => timeBetweenPolls;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
timeBetweenPolls = value;
|
||||||
|
scheduledPoll?.Cancel();
|
||||||
|
pollIfNecessary();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timeBetweenPolls">The initial time in milliseconds to wait between polls. Setting to zero stops al polling.</param>
|
||||||
|
protected PollingComponent(double timeBetweenPolls = 0)
|
||||||
|
{
|
||||||
|
TimeBetweenPolls = timeBetweenPolls;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
pollIfNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool pollIfNecessary()
|
||||||
|
{
|
||||||
|
// we must be loaded so we have access to clock.
|
||||||
|
if (!IsLoaded) return false;
|
||||||
|
|
||||||
|
// there's already a poll process running.
|
||||||
|
if (pollingActive) return false;
|
||||||
|
|
||||||
|
// don't try polling if the time between polls hasn't been set.
|
||||||
|
if (timeBetweenPolls == 0) return false;
|
||||||
|
|
||||||
|
if (!lastTimePolled.HasValue)
|
||||||
|
{
|
||||||
|
doPoll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Time.Current - lastTimePolled.Value > timeBetweenPolls)
|
||||||
|
{
|
||||||
|
doPoll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not ennough time has passed since the last poll. we do want to schedule a poll to happen, though.
|
||||||
|
scheduleNextPoll();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPoll()
|
||||||
|
{
|
||||||
|
scheduledPoll = null;
|
||||||
|
pollingActive = true;
|
||||||
|
Poll().ContinueWith(_ => pollComplete());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Perform the polling in this method. Call <see cref="pollComplete"/> when done.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual Task Poll()
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call when a poll operation has completed.
|
||||||
|
/// </summary>
|
||||||
|
private void pollComplete()
|
||||||
|
{
|
||||||
|
lastTimePolled = Time.Current;
|
||||||
|
pollingActive = false;
|
||||||
|
|
||||||
|
if (scheduledPoll == null)
|
||||||
|
scheduleNextPoll();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleNextPoll()
|
||||||
|
{
|
||||||
|
scheduledPoll?.Cancel();
|
||||||
|
|
||||||
|
double lastPollDuration = lastTimePolled.HasValue ? Time.Current - lastTimePolled.Value : 0;
|
||||||
|
|
||||||
|
scheduledPoll = Scheduler.AddDelayed(doPoll, Math.Max(0, timeBetweenPolls - lastPollDuration));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -418,6 +418,8 @@ namespace osu.Game
|
|||||||
dependencies.Cache(notifications);
|
dependencies.Cache(notifications);
|
||||||
dependencies.Cache(dialogOverlay);
|
dependencies.Cache(dialogOverlay);
|
||||||
|
|
||||||
|
chatOverlay.StateChanged += state => channelManager.HighPollRate.Value = state == Visibility.Visible;
|
||||||
|
|
||||||
Add(externalLinkOpener = new ExternalLinkOpener());
|
Add(externalLinkOpener = new ExternalLinkOpener());
|
||||||
|
|
||||||
var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications };
|
var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications };
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections
|
|||||||
|
|
||||||
public override FontAwesome Icon => FontAwesome.fa_paint_brush;
|
public override FontAwesome Icon => FontAwesome.fa_paint_brush;
|
||||||
|
|
||||||
private readonly Bindable<SkinInfo> dropdownBindable = new Bindable<SkinInfo>();
|
private readonly Bindable<SkinInfo> dropdownBindable = new Bindable<SkinInfo> { Default = SkinInfo.Default };
|
||||||
private readonly Bindable<int> configBindable = new Bindable<int>();
|
private readonly Bindable<int> configBindable = new Bindable<int>();
|
||||||
|
|
||||||
private SkinManager skins;
|
private SkinManager skins;
|
||||||
|
@ -25,13 +25,20 @@ namespace osu.Game.Overlays
|
|||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
base.PopIn();
|
base.PopIn();
|
||||||
|
|
||||||
Waves.Show();
|
Waves.Show();
|
||||||
|
|
||||||
|
this.FadeIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
base.PopOut();
|
base.PopOut();
|
||||||
|
|
||||||
Waves.Hide();
|
Waves.Hide();
|
||||||
|
|
||||||
|
// this is required or we will remain present even though our waves are hidden.
|
||||||
|
this.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
Retries = RestartCount,
|
Retries = RestartCount,
|
||||||
OnRetry = Restart,
|
OnRetry = Restart,
|
||||||
OnQuit = Exit,
|
OnQuit = performUserRequestedExit,
|
||||||
CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded,
|
CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
@ -211,7 +211,7 @@ namespace osu.Game.Screens.Play
|
|||||||
failOverlay = new FailOverlay
|
failOverlay = new FailOverlay
|
||||||
{
|
{
|
||||||
OnRetry = Restart,
|
OnRetry = Restart,
|
||||||
OnQuit = Exit,
|
OnQuit = performUserRequestedExit,
|
||||||
},
|
},
|
||||||
new HotkeyRetryOverlay
|
new HotkeyRetryOverlay
|
||||||
{
|
{
|
||||||
@ -225,7 +225,7 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
hudOverlay.HoldToQuit.Action = Exit;
|
hudOverlay.HoldToQuit.Action = performUserRequestedExit;
|
||||||
hudOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded);
|
hudOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded);
|
||||||
|
|
||||||
RulesetContainer.IsPaused.BindTo(pauseContainer.IsPaused);
|
RulesetContainer.IsPaused.BindTo(pauseContainer.IsPaused);
|
||||||
@ -250,8 +250,16 @@ namespace osu.Game.Screens.Play
|
|||||||
mod.ApplyToClock(sourceClock);
|
mod.ApplyToClock(sourceClock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void performUserRequestedExit()
|
||||||
|
{
|
||||||
|
if (!IsCurrentScreen) return;
|
||||||
|
Exit();
|
||||||
|
}
|
||||||
|
|
||||||
public void Restart()
|
public void Restart()
|
||||||
{
|
{
|
||||||
|
if (!IsCurrentScreen) return;
|
||||||
|
|
||||||
sampleRestart?.Play();
|
sampleRestart?.Play();
|
||||||
ValidForResume = false;
|
ValidForResume = false;
|
||||||
RestartRequested?.Invoke();
|
RestartRequested?.Invoke();
|
||||||
|
@ -16,8 +16,8 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
public event Action SourceChanged;
|
public event Action SourceChanged;
|
||||||
|
|
||||||
private Bindable<bool> beatmapSkins = new Bindable<bool>();
|
private readonly Bindable<bool> beatmapSkins = new Bindable<bool>();
|
||||||
private Bindable<bool> beatmapHitsounds = new Bindable<bool>();
|
private readonly Bindable<bool> beatmapHitsounds = new Bindable<bool>();
|
||||||
|
|
||||||
public Drawable GetDrawableComponent(string componentName)
|
public Drawable GetDrawableComponent(string componentName)
|
||||||
{
|
{
|
||||||
@ -84,11 +84,8 @@ namespace osu.Game.Skinning
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
beatmapSkins = config.GetBindable<bool>(OsuSetting.BeatmapSkins);
|
config.BindWith(OsuSetting.BeatmapSkins, beatmapSkins);
|
||||||
beatmapSkins.BindValueChanged(_ => onSourceChanged());
|
config.BindWith(OsuSetting.BeatmapHitsounds, beatmapHitsounds);
|
||||||
|
|
||||||
beatmapHitsounds = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds);
|
|
||||||
beatmapHitsounds.BindValueChanged(_ => onSourceChanged(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -97,6 +94,9 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
if (fallbackSource != null)
|
if (fallbackSource != null)
|
||||||
fallbackSource.SourceChanged += onSourceChanged;
|
fallbackSource.SourceChanged += onSourceChanged;
|
||||||
|
|
||||||
|
beatmapSkins.BindValueChanged(_ => onSourceChanged());
|
||||||
|
beatmapHitsounds.BindValueChanged(_ => onSourceChanged(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2018.1207.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2018.1214.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user