Merge remote-tracking branch 'upstream/master' into net471

This commit is contained in:
Dean Herbert 2018-04-23 22:00:11 +09:00
commit 843385af0d
24 changed files with 164 additions and 88 deletions

@ -1 +1 @@
Subproject commit 4e66fca95e2801bee55c24abd77ccb59cdac8bb8
Subproject commit 61e676094d25436bb9e8858946f65c43d15d8e01

View File

@ -110,11 +110,13 @@ private void testNullBeatmap()
private void selectBeatmap(string name)
{
var infoBefore = infoWedge.Info;
BeatmapInfoWedge.BufferedWedgeInfo infoBefore = null;
AddStep($"select {name} beatmap", () =>
{
beatmap.Value = new TestWorkingBeatmap(beatmaps.First(b => b.BeatmapInfo.Ruleset.ShortName == name));
infoBefore = infoWedge.Info;
WorkingBeatmap bm = new TestWorkingBeatmap(beatmaps.First(b => b.BeatmapInfo.Ruleset.ShortName == name));
beatmap.Value = bm;
infoWedge.UpdateBeatmap(beatmap);
});

View File

@ -0,0 +1,24 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Game.Beatmaps;
using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
{
public class TestCasePlayerLoader : OsuTestCase
{
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
AddStep("load dummy beatmap", () => Add(new PlayerLoader(new Player
{
InitialBeatmap = new DummyWorkingBeatmap(game),
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
})));
}
}
}

View File

@ -5,7 +5,9 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile;
using osu.Game.Overlays.Profile.Header;
@ -17,6 +19,7 @@ namespace osu.Game.Tests.Visual
public class TestCaseUserProfile : OsuTestCase
{
private readonly TestUserProfileOverlay profile;
private APIAccess api;
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -32,6 +35,12 @@ public TestCaseUserProfile()
Add(profile = new TestUserProfileOverlay());
}
[BackgroundDependencyLoader]
private void load(APIAccess api)
{
this.api = api;
}
protected override void LoadComplete()
{
base.LoadComplete();
@ -79,9 +88,10 @@ protected override void LoadComplete()
{
Username = @"peppy",
Id = 2,
IsSupporter = true,
Country = new Country { FullName = @"Australia", FlagName = @"AU" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg"
}));
}, api.IsLoggedIn));
checkSupporterTag(true);
@ -91,7 +101,7 @@ protected override void LoadComplete()
Id = 3103765,
Country = new Country { FullName = @"Japan", FlagName = @"JP" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
}));
}, api.IsLoggedIn));
AddStep("Hide", profile.Hide);
AddStep("Show without reload", profile.Show);

View File

@ -21,7 +21,7 @@ public TOutput Decode(StreamReader primaryStream, params StreamReader[] otherStr
return output;
}
protected abstract void ParseStreamInto(StreamReader stream, TOutput beatmap);
protected abstract void ParseStreamInto(StreamReader stream, TOutput output);
}
public abstract class Decoder

View File

@ -13,15 +13,15 @@ public static void Register()
AddDecoder<Beatmap>("{", m => new JsonBeatmapDecoder());
}
protected override void ParseStreamInto(StreamReader stream, Beatmap beatmap)
protected override void ParseStreamInto(StreamReader stream, Beatmap output)
{
stream.BaseStream.Position = 0;
stream.DiscardBufferedData();
stream.ReadToEnd().DeserializeInto(beatmap);
stream.ReadToEnd().DeserializeInto(output);
foreach (var hitObject in beatmap.HitObjects)
hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
foreach (var hitObject in output.HitObjects)
hitObject.ApplyDefaults(output.ControlPointInfo, output.BeatmapInfo.BaseDifficulty);
}
}
}

View File

@ -19,7 +19,7 @@ protected LegacyDecoder(int version)
FormatVersion = version;
}
protected override void ParseStreamInto(StreamReader stream, T beatmap)
protected override void ParseStreamInto(StreamReader stream, T output)
{
Section section = Section.None;
@ -33,14 +33,21 @@ protected override void ParseStreamInto(StreamReader stream, T beatmap)
{
if (!Enum.TryParse(line.Substring(1, line.Length - 2), out section))
{
Logger.Log($"Unknown section \"{line}\" in {beatmap}");
Logger.Log($"Unknown section \"{line}\" in {output}");
section = Section.None;
}
continue;
}
ParseLine(beatmap, section, line);
try
{
ParseLine(output, section, line);
}
catch (Exception e)
{
Logger.Error(e, $"Failed to process line \"{line}\" into {output}");
}
}
}

View File

@ -1,14 +1,13 @@
// 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.Collections.Generic;
using System.IO;
using osu.Framework.IO.Stores;
namespace osu.Game.IO.Archives
{
public abstract class ArchiveReader : IDisposable, IResourceStore<byte[]>
public abstract class ArchiveReader : IResourceStore<byte[]>
{
/// <summary>
/// Opens a stream for reading a specific file from this archive.

View File

@ -11,7 +11,7 @@ namespace osu.Game.Online.API.Requests
public class GetMessagesRequest : APIRequest<List<Message>>
{
private readonly List<Channel> channels;
private long? since;
private readonly long? since;
public GetMessagesRequest(List<Channel> channels, long? sinceId)
{

View File

@ -7,7 +7,7 @@ namespace osu.Game.Online.API.Requests
{
public class GetUserRequest : APIRequest<User>
{
private long? userId;
private readonly long? userId;
public GetUserRequest(long? userId = null)
{

View File

@ -188,6 +188,20 @@ private void load()
FileStore.Cleanup();
AddInternal(api);
GlobalActionContainer globalBinding;
CursorOverrideContainer = new CursorOverrideContainer { RelativeSizeAxes = Axes.Both };
CursorOverrideContainer.Child = globalBinding = new GlobalActionContainer(this)
{
RelativeSizeAxes = Axes.Both,
Child = content = new OsuTooltipContainer(CursorOverrideContainer.Cursor) { RelativeSizeAxes = Axes.Both }
};
base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorOverrideContainer });
KeyBindingStore.Register(globalBinding);
dependencies.Cache(globalBinding);
}
private void runMigrations()
@ -217,20 +231,6 @@ protected override void LoadComplete()
{
base.LoadComplete();
GlobalActionContainer globalBinding;
CursorOverrideContainer = new CursorOverrideContainer { RelativeSizeAxes = Axes.Both };
CursorOverrideContainer.Child = globalBinding = new GlobalActionContainer(this)
{
RelativeSizeAxes = Axes.Both,
Child = content = new OsuTooltipContainer(CursorOverrideContainer.Cursor) { RelativeSizeAxes = Axes.Both }
};
base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorOverrideContainer });
KeyBindingStore.Register(globalBinding);
dependencies.Cache(globalBinding);
// TODO: This is temporary until we reimplement the local FPS display.
// It's just to allow end-users to access the framework FPS display without knowing the shortcut key.
fpsDisplayVisible = LocalConfig.GetBindable<bool>(OsuSetting.ShowFpsDisplay);

View File

@ -92,22 +92,18 @@ private void rotateBadges()
public void ShowBadges(Badge[] badges)
{
switch (badges.Length)
if (badges == null || badges.Length == 0)
{
case 0:
Hide();
return;
case 1:
badgeCountText.Hide();
break;
default:
badgeCountText.Show();
badgeCountText.Text = $"{badges.Length} badges";
break;
Hide();
return;
}
Show();
badgeCount = badges.Length;
badgeCountText.FadeTo(badgeCount > 1 ? 1 : 0);
badgeCountText.Text = $"{badges.Length} badges";
Show();
visibleBadge = 0;
badgeFlowContainer.Clear();

View File

@ -26,14 +26,14 @@ protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
return false;
}
public override bool Push(Screen screen)
public override void Push(Screen screen)
{
// When trying to push a non-loaded screen, load it asynchronously and re-invoke Push
// once it's done.
if (screen.LoadState == LoadState.NotLoaded)
{
LoadComponentAsync(screen, d => Push((BackgroundScreen)d));
return true;
return;
}
// Make sure the in-progress loading is complete before pushing the screen.
@ -41,8 +41,6 @@ public override bool Push(Screen screen)
Thread.Sleep(1);
base.Push(screen);
return true;
}
protected override void Update()

View File

@ -178,7 +178,7 @@ private void onModeChanged(EditorScreenMode mode)
}
currentScreen.Beatmap.BindTo(Beatmap);
screenContainer.Add(currentScreen);
LoadComponentAsync(currentScreen, screenContainer.Add);
}
protected override bool OnWheel(InputState state)

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
@ -43,6 +44,8 @@ public MaskContainer()
public override void Add(HitObjectMask drawable)
{
if (drawable == null) throw new ArgumentNullException(nameof(drawable));
base.Add(drawable);
drawable.Selected += onMaskSelected;
@ -51,8 +54,10 @@ public override void Add(HitObjectMask drawable)
drawable.DragRequested += onDragRequested;
}
public override bool Remove(HitObjectMask drawable)
public override bool Remove([NotNull] HitObjectMask drawable)
{
if (drawable == null) throw new ArgumentNullException(nameof(drawable));
var result = base.Remove(drawable);
if (result)

View File

@ -39,6 +39,7 @@ public class Intro : OsuScreen
private Bindable<bool> menuVoice;
private Bindable<bool> menuMusic;
private Track track;
private WorkingBeatmap beatmap;
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game)
@ -69,9 +70,8 @@ private void load(AudioManager audio, OsuConfigManager config, BeatmapManager be
}
}
Beatmap.Value = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
track = Beatmap.Value.Track;
beatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
track = beatmap.Track;
welcome = audio.Sample.Get(@"welcome");
seeya = audio.Sample.Get(@"seeya");
@ -81,6 +81,8 @@ protected override void OnEntering(Screen last)
{
base.OnEntering(last);
Game.Beatmap.Value = beatmap;
if (menuVoice)
welcome.Play();

View File

@ -77,7 +77,7 @@ public class Player : ScreenWithBeatmapBackground, IProvideCursor
private DrawableStoryboard storyboard;
private Container storyboardContainer;
private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true;
public bool LoadedBeatmapSuccessfully => RulesetContainer?.Objects.Any() == true;
[BackgroundDependencyLoader]
private void load(AudioManager audio, APIAccess api, OsuConfigManager config)
@ -86,10 +86,7 @@ private void load(AudioManager audio, APIAccess api, OsuConfigManager config)
WorkingBeatmap working = Beatmap.Value;
if (working is DummyWorkingBeatmap)
{
Exit();
return;
}
sampleRestart = audio.Sample.Get(@"Gameplay/restart");
@ -122,14 +119,15 @@ private void load(AudioManager audio, APIAccess api, OsuConfigManager config)
}
if (!RulesetContainer.Objects.Any())
throw new InvalidOperationException("Beatmap contains no hit objects!");
{
Logger.Error(new InvalidOperationException("Beatmap contains no hit objects!"), "Beatmap contains no hit objects!");
return;
}
}
catch (Exception e)
{
Logger.Error(e, "Could not load beatmap sucessfully!");
//couldn't load, hard abort!
Exit();
return;
}
@ -293,7 +291,7 @@ protected override void OnEntering(Screen last)
{
base.OnEntering(last);
if (!loadedSuccessfully)
if (!LoadedBeatmapSuccessfully)
return;
Content.Alpha = 0;
@ -343,7 +341,7 @@ protected override bool OnExiting(Screen next)
return base.OnExiting(next);
}
if (loadedSuccessfully)
if (LoadedBeatmapSuccessfully)
pauseContainer?.Pause();
return true;

View File

@ -159,14 +159,14 @@ private void pushWhenLoaded()
loadTask = null;
if (!Push(player))
Exit();
//By default, we want to load the player and never be returned to.
//Note that this may change if the player we load requested a re-run.
ValidForResume = false;
if (player.LoadedBeatmapSuccessfully)
Push(player);
else
{
//By default, we want to load the player and never be returned to.
//Note that this may change if the player we load requested a re-run.
ValidForResume = false;
}
Exit();
});
}, 500);
}

View File

@ -223,11 +223,11 @@ private void load(OsuColour colours)
private class DateTimeDisplay : Container
{
private DateTime datetime;
private readonly DateTime date;
public DateTimeDisplay(DateTime datetime)
public DateTimeDisplay(DateTime date)
{
this.datetime = datetime;
this.date = date;
AutoSizeAxes = Axes.Y;
@ -251,7 +251,7 @@ private void load(OsuColour colours)
{
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
Text = datetime.ToShortDateString(),
Text = date.ToShortDateString(),
Padding = new MarginPadding { Horizontal = 10, Vertical = 5 },
Colour = Color4.White,
},
@ -259,7 +259,7 @@ private void load(OsuColour colours)
{
Origin = Anchor.CentreRight,
Anchor = Anchor.CentreRight,
Text = datetime.ToShortTimeString(),
Text = date.ToShortTimeString(),
Padding = new MarginPadding { Horizontal = 10, Vertical = 5 },
Colour = Color4.White,
}

View File

@ -16,6 +16,12 @@ public class CarouselGroup : CarouselItem
protected List<CarouselItem> InternalChildren = new List<CarouselItem>();
/// <summary>
/// Used to assign a monotonically increasing ID to children as they are added. This member is
/// incremented whenever a child is added.
/// </summary>
private ulong currentChildID;
public override List<DrawableCarouselItem> Drawables
{
get
@ -39,6 +45,7 @@ public virtual void RemoveChild(CarouselItem i)
public virtual void AddChild(CarouselItem i)
{
i.State.ValueChanged += v => ChildItemStateChanged(i, v);
i.ChildID = ++currentChildID;
InternalChildren.Add(i);
}

View File

@ -31,6 +31,8 @@ public virtual List<DrawableCarouselItem> Drawables
}
}
private int creationOrder;
protected CarouselItem()
{
drawableRepresentation = new Lazy<DrawableCarouselItem>(CreateDrawableRepresentation);
@ -44,13 +46,18 @@ protected CarouselItem()
private readonly Lazy<DrawableCarouselItem> drawableRepresentation;
/// <summary>
/// Used as a default sort method for <see cref="CarouselItem"/>s of differing types.
/// </summary>
internal ulong ChildID;
protected abstract DrawableCarouselItem CreateDrawableRepresentation();
public virtual void Filter(FilterCriteria criteria)
{
}
public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => GetHashCode().CompareTo(other.GetHashCode());
public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ChildID.CompareTo(other.ChildID);
}
public enum CarouselItemState

View File

@ -113,6 +113,31 @@ byte[] IResourceStore<byte[]>.Get(string name)
string path = getPathForFile(name);
return path == null ? null : underlyingStore.Get(path);
}
#region IDisposable Support
private bool isDisposed;
protected virtual void Dispose(bool disposing)
{
if (!isDisposed)
{
isDisposed = true;
}
}
~LegacySkinResourceStore()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
}

View File

@ -12,7 +12,7 @@ public LegacySkinDecoder()
{
}
protected override void ParseLine(SkinConfiguration output, Section section, string line)
protected override void ParseLine(SkinConfiguration skin, Section section, string line)
{
switch (section)
{
@ -22,17 +22,17 @@ protected override void ParseLine(SkinConfiguration output, Section section, str
switch (pair.Key)
{
case @"Name":
output.SkinInfo.Name = pair.Value;
skin.SkinInfo.Name = pair.Value;
break;
case @"Author":
output.SkinInfo.Creator = pair.Value;
skin.SkinInfo.Creator = pair.Value;
break;
}
break;
}
base.ParseLine(output, section, line);
base.ParseLine(skin, section, line);
}
}
}

View File

@ -15,18 +15,14 @@ public class OsuTestCaseTestRunner : OsuGameBase, ITestCaseTestRunner
{
protected override string MainResourceFile => File.Exists(base.MainResourceFile) ? base.MainResourceFile : Assembly.GetExecutingAssembly().Location;
private readonly TestCaseTestRunner.TestRunner runner;
private TestCaseTestRunner.TestRunner runner;
public OsuTestCaseTestRunner()
protected override void LoadAsyncComplete()
{
runner = new TestCaseTestRunner.TestRunner();
}
protected override void LoadComplete()
{
base.LoadComplete();
Add(runner);
// this has to be run here rather than LoadComplete because
// TestCase.cs is checking the IsLoaded state (on another thread) and expects
// the runner to be loaded at that point.
Add(runner = new TestCaseTestRunner.TestRunner());
}
public void RunTestBlocking(TestCase test) => runner.RunTestBlocking(test);