Merge remote-tracking branch 'upstream/master' into update-scrollcontainer

This commit is contained in:
Dean Herbert
2019-06-14 23:25:17 +09:00
9 changed files with 143 additions and 35 deletions

View File

@ -0,0 +1,109 @@
// 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.
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.MathUtils;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using osuTK;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestSceneGameplayRewinding : PlayerTestScene
{
private RulesetExposingPlayer player => (RulesetExposingPlayer)Player;
[Resolved]
private AudioManager audioManager { get; set; }
public TestSceneGameplayRewinding()
: base(new OsuRuleset())
{
}
private Track track;
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap)
{
var working = new ClockBackedTestWorkingBeatmap(beatmap, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
track = working.Track;
return working;
}
[Test]
public void TestNoJudgementsOnRewind()
{
AddUntilStep("wait for track to start running", () => track.IsRunning);
addSeekStep(3000);
AddAssert("all judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged));
AddStep("clear results", () => player.AppliedResults.Clear());
addSeekStep(0);
AddAssert("none judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
AddAssert("no results triggered", () => player.AppliedResults.Count == 0);
}
private void addSeekStep(double time)
{
AddStep($"seek to {time}", () => track.Seek(time));
// Allow a few frames of lenience
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
}
protected override Player CreatePlayer(Ruleset ruleset)
{
Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
return new RulesetExposingPlayer();
}
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{
var beatmap = new Beatmap
{
BeatmapInfo = { BaseDifficulty = { ApproachRate = 9 } },
};
for (int i = 0; i < 15; i++)
{
beatmap.HitObjects.Add(new HitCircle
{
Position = new Vector2(256, 192),
StartTime = 1000 + 30 * i
});
}
return beatmap;
}
private class RulesetExposingPlayer : Player
{
public readonly List<JudgementResult> AppliedResults = new List<JudgementResult>();
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
public new DrawableRuleset DrawableRuleset => base.DrawableRuleset;
public RulesetExposingPlayer()
: base(false, false)
{
}
[BackgroundDependencyLoader]
private void load()
{
ScoreProcessor.NewJudgement += r => AppliedResults.Add(r);
}
}
}
}

View File

@ -18,6 +18,7 @@ using osu.Game.Beatmaps;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Taiko; using osu.Game.Rulesets.Taiko;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
@ -100,8 +101,11 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
[SetUp] [SetUp]
public virtual void SetUp() => public virtual void SetUp() => Schedule(() =>
Schedule(() => { manager?.Delete(manager.GetAllUsableBeatmapSets()); }); {
Ruleset.Value = new OsuRuleset().RulesetInfo;
manager?.Delete(manager.GetAllUsableBeatmapSets());
});
[Test] [Test]
public void TestDummy() public void TestDummy()
@ -185,7 +189,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("empty mods", () => !Mods.Value.Any()); AddAssert("empty mods", () => !Mods.Value.Any());
void onModChange(ValueChangedEvent<IReadOnlyList<Mod>> e) => modChangeIndex = actionIndex++; void onModChange(ValueChangedEvent<IReadOnlyList<Mod>> e) => modChangeIndex = actionIndex++;
void onRulesetChange(ValueChangedEvent<RulesetInfo> e) => rulesetChangeIndex = actionIndex--; void onRulesetChange(ValueChangedEvent<RulesetInfo> e) => rulesetChangeIndex = actionIndex++;
} }
[Test] [Test]

View File

@ -26,8 +26,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
new NamedIconButton("No change", new IconButton()), new NamedIconButton("No change", new IconButton()),
new NamedIconButton("Background colours", new ColouredIconButton()), new NamedIconButton("Background colours", new ColouredIconButton()),
new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }), new NamedIconButton("Full-width", new IconButton { Size = new Vector2(200, 30) }),
new NamedIconButton("Unchanging size", new IconButton(), false),
new NamedIconButton("Icon colours", new IconButton new NamedIconButton("Icon colours", new IconButton
{ {
IconColour = Color4.Green, IconColour = Color4.Green,
@ -48,7 +47,7 @@ namespace osu.Game.Tests.Visual.UserInterface
private class NamedIconButton : Container private class NamedIconButton : Container
{ {
public NamedIconButton(string name, IconButton button, bool allowSizeChange = true) public NamedIconButton(string name, IconButton button)
{ {
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
Width = 200; Width = 200;
@ -101,13 +100,7 @@ namespace osu.Game.Tests.Visual.UserInterface
} }
}; };
if (allowSizeChange) iconContainer.AutoSizeAxes = Axes.Both;
iconContainer.AutoSizeAxes = Axes.Both;
else
{
iconContainer.RelativeSizeAxes = Axes.X;
iconContainer.Height = 30;
}
button.Anchor = Anchor.Centre; button.Anchor = Anchor.Centre;
button.Origin = Anchor.Centre; button.Origin = Anchor.Centre;

View File

@ -3,7 +3,6 @@
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Overlays; using osu.Game.Overlays;
@ -23,9 +22,9 @@ namespace osu.Game.Tests.Visual.UserInterface
}; };
Add(mc); Add(mc);
AddToggleStep(@"toggle visibility", state => mc.State.Value = state ? Visibility.Visible : Visibility.Hidden);
AddStep(@"show", () => mc.Show()); AddStep(@"show", () => mc.Show());
AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state); AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state);
AddStep(@"show", () => mc.Hide());
} }
} }
} }

View File

@ -11,7 +11,7 @@ namespace osu.Game.Graphics.UserInterface
{ {
public class IconButton : OsuAnimatedButton public class IconButton : OsuAnimatedButton
{ {
public const float BUTTON_SIZE = 30; public const float DEFAULT_BUTTON_SIZE = 30;
private Color4? iconColour; private Color4? iconColour;
@ -57,26 +57,11 @@ namespace osu.Game.Graphics.UserInterface
set => icon.Scale = value; set => icon.Scale = value;
} }
/// <summary>
/// The size of the <see cref="IconButton"/> while it is not being pressed.
/// </summary>
public Vector2 ButtonSize
{
get => Content.Size;
set
{
Content.RelativeSizeAxes = Axes.None;
Content.AutoSizeAxes = Axes.None;
Content.Size = value;
}
}
private readonly SpriteIcon icon; private readonly SpriteIcon icon;
public IconButton() public IconButton()
{ {
AutoSizeAxes = Axes.Both; Size = new Vector2(DEFAULT_BUTTON_SIZE);
ButtonSize = new Vector2(BUTTON_SIZE);
Add(icon = new SpriteIcon Add(icon = new SpriteIcon
{ {

View File

@ -464,12 +464,26 @@ namespace osu.Game.Overlays
private class MusicIconButton : IconButton private class MusicIconButton : IconButton
{ {
public MusicIconButton()
{
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
HoverColour = colours.YellowDark.Opacity(0.6f); HoverColour = colours.YellowDark.Opacity(0.6f);
FlashColour = colours.Yellow; FlashColour = colours.Yellow;
} }
protected override void LoadComplete()
{
base.LoadComplete();
// works with AutoSizeAxes above to make buttons autosize with the scale animation.
Content.AutoSizeAxes = Axes.None;
Content.Size = new Vector2(DEFAULT_BUTTON_SIZE);
}
} }
private class Background : BufferedContainer private class Background : BufferedContainer

View File

@ -244,6 +244,10 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// <returns>Whether a scoring result has occurred from this <see cref="DrawableHitObject"/> or any nested <see cref="DrawableHitObject"/>.</returns> /// <returns>Whether a scoring result has occurred from this <see cref="DrawableHitObject"/> or any nested <see cref="DrawableHitObject"/>.</returns>
protected bool UpdateResult(bool userTriggered) protected bool UpdateResult(bool userTriggered)
{ {
// It's possible for input to get into a bad state when rewinding gameplay, so results should not be processed
if (Time.Elapsed < 0)
return false;
judgementOccurred = false; judgementOccurred = false;
if (AllJudged) if (AllJudged)

View File

@ -171,7 +171,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
// Small offset to look a bit better centered along with the divisor text // Small offset to look a bit better centered along with the divisor text
Y = 1; Y = 1;
ButtonSize = new Vector2(20); Size = new Vector2(20);
IconScale = new Vector2(0.6f); IconScale = new Vector2(0.6f);
} }

View File

@ -31,14 +31,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
InternalChild = button = new TimelineIconButton { Action = () => Action?.Invoke() }; InternalChild = button = new TimelineIconButton { Action = () => Action?.Invoke() };
button.Enabled.BindTo(Enabled); button.Enabled.BindTo(Enabled);
Width = button.ButtonSize.X; Width = button.Width;
} }
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();
button.ButtonSize = new Vector2(button.ButtonSize.X, DrawHeight); button.Size = new Vector2(button.Width, DrawHeight);
} }
private class TimelineIconButton : IconButton private class TimelineIconButton : IconButton