1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-21 03:53:21 +08:00

Merge branch 'master' into catcher-area-catcher

This commit is contained in:
Dean Herbert 2021-07-21 18:00:35 +09:00
commit 6effa24157
11 changed files with 251 additions and 192 deletions

View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Dual client test" type="CompoundRunConfigurationType">
<toRun name="osu!" type="DotNetProject" />
<toRun name="osu! (Second Client)" type="DotNetProject" />
<method v="2" />
</configuration>
</component>

View File

@ -0,0 +1,20 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="osu! (Second Client)" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0/osu!.dll" />
<option name="PROGRAM_PARAMETERS" value="--debug-client-id=1" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" 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_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value="net5.0" />
<method v="2">
<option name="Build" />
</method>
</configuration>
</component>

View File

@ -3,7 +3,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework; using osu.Framework;
@ -17,13 +16,43 @@ namespace osu.Desktop
{ {
public static class Program public static class Program
{ {
private const string base_game_name = @"osu";
[STAThread] [STAThread]
public static int Main(string[] args) public static int Main(string[] args)
{ {
// Back up the cwd before DesktopGameHost changes it // Back up the cwd before DesktopGameHost changes it
var cwd = Environment.CurrentDirectory; var cwd = Environment.CurrentDirectory;
using (DesktopGameHost host = Host.GetSuitableHost(@"osu", true)) string gameName = base_game_name;
bool tournamentClient = false;
foreach (var arg in args)
{
var split = arg.Split('=');
var key = split[0];
var val = split[1];
switch (key)
{
case "--tournament":
tournamentClient = true;
break;
case "--debug-client-id":
if (!DebugUtils.IsDebugBuild)
throw new InvalidOperationException("Cannot use this argument in a non-debug build.");
if (!int.TryParse(val, out int clientID))
throw new ArgumentException("Provided client ID must be an integer.");
gameName = $"{base_game_name}-{clientID}";
break;
}
}
using (DesktopGameHost host = Host.GetSuitableHost(gameName, true))
{ {
host.ExceptionThrown += handleException; host.ExceptionThrown += handleException;
@ -48,16 +77,10 @@ namespace osu.Desktop
return 0; return 0;
} }
switch (args.FirstOrDefault() ?? string.Empty) if (tournamentClient)
{
default:
host.Run(new OsuGameDesktop(args));
break;
case "--tournament":
host.Run(new TournamentGame()); host.Run(new TournamentGame());
break; else
} host.Run(new OsuGameDesktop(args));
return 0; return 0;
} }

View File

@ -12,6 +12,7 @@ using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Screens.Ranking; using osu.Game.Screens.Ranking;
@ -50,9 +51,33 @@ namespace osu.Game.Tests.Visual.Ranking
AddAssert("mapped by text not present", () => AddAssert("mapped by text not present", () =>
this.ChildrenOfType<OsuSpriteText>().All(spriteText => !containsAny(spriteText.Text.ToString(), "mapped", "by"))); this.ChildrenOfType<OsuSpriteText>().All(spriteText => !containsAny(spriteText.Text.ToString(), "mapped", "by")));
AddAssert("play time displayed", () => this.ChildrenOfType<ExpandedPanelMiddleContent.PlayedOnText>().Any());
} }
private void showPanel(ScoreInfo score) => Child = new ExpandedPanelMiddleContentContainer(score); [Test]
public void TestWithDefaultDate()
{
AddStep("show autoplay score", () =>
{
var ruleset = new OsuRuleset();
var mods = new Mod[] { ruleset.GetAutoplayMod() };
var beatmap = createTestBeatmap(null);
showPanel(new TestScoreInfo(ruleset.RulesetInfo)
{
Mods = mods,
Beatmap = beatmap,
Date = default,
});
});
AddAssert("play time not displayed", () => !this.ChildrenOfType<ExpandedPanelMiddleContent.PlayedOnText>().Any());
}
private void showPanel(ScoreInfo score) =>
Child = new ExpandedPanelMiddleContentContainer(score);
private BeatmapInfo createTestBeatmap(User author) private BeatmapInfo createTestBeatmap(User author)
{ {

View File

@ -11,10 +11,8 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
public class TestSceneModDisplay : OsuTestScene public class TestSceneModDisplay : OsuTestScene
{ {
[TestCase(ExpansionMode.ExpandOnHover)] [Test]
[TestCase(ExpansionMode.AlwaysExpanded)] public void TestMode([Values] ExpansionMode mode)
[TestCase(ExpansionMode.AlwaysContracted)]
public void TestMode(ExpansionMode mode)
{ {
AddStep("create mod display", () => AddStep("create mod display", () =>
{ {

View File

@ -416,7 +416,6 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Position = new Vector2(-5, 25), Position = new Vector2(-5, 25),
Current = { BindTarget = modSelect.SelectedMods } Current = { BindTarget = modSelect.SelectedMods }
} }

View File

@ -172,7 +172,6 @@ namespace osu.Game.Screens.Play
{ {
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = 20 }, Margin = new MarginPadding { Top = 20 },
Current = mods Current = mods
}, },

View File

@ -15,24 +15,26 @@ using osuTK;
namespace osu.Game.Screens.Play.HUD namespace osu.Game.Screens.Play.HUD
{ {
public class ModDisplay : Container, IHasCurrentValue<IReadOnlyList<Mod>> /// <summary>
/// Displays a single-line horizontal auto-sized flow of mods.
/// </summary>
public class ModDisplay : CompositeDrawable, IHasCurrentValue<IReadOnlyList<Mod>>
{ {
private const int fade_duration = 1000; private const int fade_duration = 1000;
public ExpansionMode ExpansionMode = ExpansionMode.ExpandOnHover; public ExpansionMode ExpansionMode = ExpansionMode.ExpandOnHover;
private readonly Bindable<IReadOnlyList<Mod>> current = new Bindable<IReadOnlyList<Mod>>(); private readonly BindableWithCurrent<IReadOnlyList<Mod>> current = new BindableWithCurrent<IReadOnlyList<Mod>>();
public Bindable<IReadOnlyList<Mod>> Current public Bindable<IReadOnlyList<Mod>> Current
{ {
get => current; get => current.Current;
set set
{ {
if (value == null) if (value == null)
throw new ArgumentNullException(nameof(value)); throw new ArgumentNullException(nameof(value));
current.UnbindBindings(); current.Current = value;
current.BindTo(value);
} }
} }
@ -42,50 +44,33 @@ namespace osu.Game.Screens.Play.HUD
{ {
AutoSizeAxes = Axes.Both; AutoSizeAxes = Axes.Both;
Child = new FillFlowContainer InternalChild = iconsContainer = new ReverseChildIDFillFlowContainer<ModIcon>
{ {
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
iconsContainer = new ReverseChildIDFillFlowContainer<ModIcon>
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
},
},
}; };
} }
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
Current.UnbindAll();
}
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
Current.BindValueChanged(mods => Current.BindValueChanged(updateDisplay, true);
iconsContainer.FadeInFromZero(fade_duration, Easing.OutQuint);
}
private void updateDisplay(ValueChangedEvent<IReadOnlyList<Mod>> mods)
{ {
iconsContainer.Clear(); iconsContainer.Clear();
if (mods.NewValue != null) if (mods.NewValue == null) return;
{
foreach (Mod mod in mods.NewValue) foreach (Mod mod in mods.NewValue)
iconsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.6f) }); iconsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.6f) });
appearTransform(); appearTransform();
} }
}, true);
iconsContainer.FadeInFromZero(fade_duration, Easing.OutQuint);
}
private void appearTransform() private void appearTransform()
{ {

View File

@ -282,7 +282,6 @@ namespace osu.Game.Screens.Play
{ {
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
}; };
protected PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); protected PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay();

View File

@ -135,7 +135,6 @@ namespace osu.Game.Screens.Ranking.Contracted
{ {
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
ExpansionMode = ExpansionMode.AlwaysExpanded, ExpansionMode = ExpansionMode.AlwaysExpanded,
Current = { Value = score.Mods }, Current = { Value = score.Mods },
Scale = new Vector2(0.5f), Scale = new Vector2(0.5f),

View File

@ -1,6 +1,7 @@
// 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.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -79,9 +80,7 @@ namespace osu.Game.Screens.Ranking.Expanded
var starDifficulty = beatmapDifficultyCache.GetDifficultyAsync(beatmap, score.Ruleset, score.Mods).Result; var starDifficulty = beatmapDifficultyCache.GetDifficultyAsync(beatmap, score.Ruleset, score.Mods).Result;
InternalChildren = new Drawable[] AddInternal(new FillFlowContainer
{
new FillFlowContainer
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
@ -226,15 +225,10 @@ namespace osu.Game.Screens.Ranking.Expanded
} }
} }
} }
}, });
new OsuSpriteText
{ if (score.Date != default)
Anchor = Anchor.BottomCentre, AddInternal(new PlayedOnText(score.Date));
Origin = Anchor.BottomCentre,
Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold),
Text = $"Played on {score.Date.ToLocalTime():d MMMM yyyy HH:mm}"
}
};
if (score.Mods.Any()) if (score.Mods.Any())
{ {
@ -276,5 +270,16 @@ namespace osu.Game.Screens.Ranking.Expanded
FinishTransforms(true); FinishTransforms(true);
}); });
} }
public class PlayedOnText : OsuSpriteText
{
public PlayedOnText(DateTimeOffset time)
{
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold);
Text = $"Played on {time.ToLocalTime():d MMMM yyyy HH:mm}";
}
}
} }
} }