Merge branch 'updateable-beatmap-sprite' into timeshift-wip

# Conflicts:
#	osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs
#	osu.Game/Graphics/Containers/LinkFlowContainer.cs
This commit is contained in:
Dean Herbert 2018-12-26 20:52:36 +09:00
commit 171287591c
10 changed files with 117 additions and 62 deletions

View File

@ -29,7 +29,7 @@ namespace osu.Game.Tests.Beatmaps.IO
{
try
{
loadOszIntoOsu(loadOsu(host));
LoadOszIntoOsu(loadOsu(host));
}
finally
{
@ -48,7 +48,7 @@ namespace osu.Game.Tests.Beatmaps.IO
{
var osu = loadOsu(host);
var imported = loadOszIntoOsu(osu);
var imported = LoadOszIntoOsu(osu);
deleteBeatmapSet(imported, osu);
}
@ -69,8 +69,8 @@ namespace osu.Game.Tests.Beatmaps.IO
{
var osu = loadOsu(host);
var imported = loadOszIntoOsu(osu);
var importedSecondTime = loadOszIntoOsu(osu);
var imported = LoadOszIntoOsu(osu);
var importedSecondTime = LoadOszIntoOsu(osu);
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
Assert.IsTrue(imported.ID == importedSecondTime.ID);
@ -105,7 +105,7 @@ namespace osu.Game.Tests.Beatmaps.IO
manager.ItemAdded += (_, __, ___) => fireCount++;
manager.ItemRemoved += _ => fireCount++;
var imported = loadOszIntoOsu(osu);
var imported = LoadOszIntoOsu(osu);
Assert.AreEqual(0, fireCount -= 1);
@ -160,12 +160,12 @@ namespace osu.Game.Tests.Beatmaps.IO
var osu = loadOsu(host);
var manager = osu.Dependencies.Get<BeatmapManager>();
var imported = loadOszIntoOsu(osu);
var imported = LoadOszIntoOsu(osu);
imported.Hash += "-changed";
manager.Update(imported);
var importedSecondTime = loadOszIntoOsu(osu);
var importedSecondTime = LoadOszIntoOsu(osu);
Assert.IsTrue(imported.ID != importedSecondTime.ID);
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
@ -191,11 +191,11 @@ namespace osu.Game.Tests.Beatmaps.IO
{
var osu = loadOsu(host);
var imported = loadOszIntoOsu(osu);
var imported = LoadOszIntoOsu(osu);
deleteBeatmapSet(imported, osu);
var importedSecondTime = loadOszIntoOsu(osu);
var importedSecondTime = LoadOszIntoOsu(osu);
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
Assert.IsTrue(imported.ID == importedSecondTime.ID);
@ -262,7 +262,7 @@ namespace osu.Game.Tests.Beatmaps.IO
}
}
private string createTemporaryBeatmap()
private static string createTemporaryBeatmap()
{
var temp = Path.GetTempFileName() + ".osz";
File.Copy(TEST_OSZ_PATH, temp, true);
@ -270,7 +270,7 @@ namespace osu.Game.Tests.Beatmaps.IO
return temp;
}
private BeatmapSetInfo loadOszIntoOsu(OsuGameBase osu, string path = null)
public static BeatmapSetInfo LoadOszIntoOsu(OsuGameBase osu, string path = null)
{
var temp = path ?? createTemporaryBeatmap();
@ -305,7 +305,7 @@ namespace osu.Game.Tests.Beatmaps.IO
return osu;
}
private void ensureLoaded(OsuGameBase osu, int timeout = 60000)
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000)
{
IEnumerable<BeatmapSetInfo> resultSets = null;
var store = osu.Dependencies.Get<BeatmapManager>();
@ -343,7 +343,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.IsTrue(beatmap?.HitObjects.Any() == true);
}
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{
Task task = Task.Run(() =>
{

View File

@ -87,10 +87,7 @@ namespace osu.Game.Tests.Visual
usage.Migrate();
Dependencies.Cache(rulesets = new RulesetStore(factory));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null)
{
DefaultBeatmap = defaultBeatmap = Beatmap.Default
});
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null, null, defaultBeatmap = Beatmap.Default));
Beatmap.SetDefault();
}

View File

@ -0,0 +1,57 @@
// 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.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using osu.Game.Tests.Beatmaps.IO;
namespace osu.Game.Tests.Visual
{
public class TestCaseUpdateableBeatmapBackgroundSprite : OsuTestCase
{
private UpdateableBeatmapBackgroundSprite backgroundSprite;
[Resolved]
private BeatmapManager beatmaps { get; set; }
[BackgroundDependencyLoader]
private void load(OsuGameBase osu, APIAccess api, RulesetStore rulesets)
{
Bindable<BeatmapInfo> beatmapBindable = new Bindable<BeatmapInfo>();
var imported = ImportBeatmapTest.LoadOszIntoOsu(osu);
Child = backgroundSprite = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both };
backgroundSprite.Beatmap.BindTo(beatmapBindable);
var req = new GetBeatmapSetRequest(1);
api.Queue(req);
AddStep("null", () => beatmapBindable.Value = null);
AddStep("imported", () => beatmapBindable.Value = imported.Beatmaps.First());
if (api.IsLoggedIn)
{
AddUntilStep(() => req.Result != null, "wait for api response");
AddStep("online", () => beatmapBindable.Value = new BeatmapInfo
{
BeatmapSet = req.Result?.ToBeatmapSet(rulesets)
});
}
else
{
AddStep("online (login first)", () => { });
}
}
}
}

View File

@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps
/// <summary>
/// A default representation of a WorkingBeatmap to use when no beatmap is available.
/// </summary>
public WorkingBeatmap DefaultBeatmap { private get; set; }
public readonly WorkingBeatmap DefaultBeatmap;
public override string[] HandledExtensions => new[] { ".osz" };
@ -77,16 +77,19 @@ namespace osu.Game.Beatmaps
private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>();
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null)
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null,
WorkingBeatmap defaultBeatmap = null)
: base(storage, contextFactory, new BeatmapStore(contextFactory), importHost)
{
beatmaps = (BeatmapStore)ModelStore;
beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b);
beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b);
this.rulesets = rulesets;
this.api = api;
this.audioManager = audioManager;
DefaultBeatmap = defaultBeatmap;
beatmaps = (BeatmapStore)ModelStore;
beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b);
beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b);
}
protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive)

View File

@ -5,10 +5,12 @@ using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Beatmaps.Drawables
{
/// <summary>
/// Display a baetmap background from a local source, but fallback to online source if not available.
/// </summary>
public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable<BeatmapInfo>
{
public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
@ -25,12 +27,12 @@ namespace osu.Game.Beatmaps.Drawables
{
Drawable drawable;
if (model == null)
drawable = new DefaultSprite();
else if (model.BeatmapSet?.OnlineInfo != null)
var localBeatmap = beatmaps.GetWorkingBeatmap(model);
if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null)
drawable = new BeatmapSetCover(model.BeatmapSet);
else
drawable = new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(model));
drawable = new BeatmapBackgroundSprite(localBeatmap);
drawable.RelativeSizeAxes = Axes.Both;
drawable.Anchor = Anchor.Centre;
@ -41,17 +43,5 @@ namespace osu.Game.Beatmaps.Drawables
}
protected override double FadeDuration => 400;
private class DefaultSprite : Sprite
{
[Resolved]
private IBindableBeatmap gameBeatmap { get; set; }
[BackgroundDependencyLoader]
private void load()
{
Texture = gameBeatmap.Default.Background;
}
}
}
}

View File

@ -64,6 +64,9 @@ namespace osu.Game.Graphics.Containers
public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
=> createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText);
public void AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
=> createLink(AddText(text, creationParameters), text, tooltipText: tooltipText, action: action);
public void AddLink(IEnumerable<SpriteText> text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null)
{
foreach (var t in text)
@ -72,12 +75,12 @@ namespace osu.Game.Graphics.Containers
createLink(text, null, url, linkType, linkArgument, tooltipText);
}
private void createLink(IEnumerable<Drawable> drawables, string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null)
private void createLink(IEnumerable<Drawable> drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null)
{
AddInternal(new DrawableLinkCompiler(drawables.OfType<SpriteText>().ToList())
{
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
Action = () =>
Action = action ?? (() =>
{
switch (linkType)
{
@ -116,7 +119,7 @@ namespace osu.Game.Graphics.Containers
default:
throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action.");
}
},
}),
});
}
}

View File

@ -145,7 +145,8 @@ namespace osu.Game.Online.API
if (!handleRequest(userReq))
{
Thread.Sleep(500);
if (State == APIState.Connecting)
State = APIState.Failing;
continue;
}

View File

@ -153,9 +153,12 @@ namespace osu.Game
dependencies.Cache(API);
dependencies.CacheAs<IAPIProvider>(API);
var defaultBeatmap = new DummyWorkingBeatmap(this);
beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio);
dependencies.Cache(RulesetStore = new RulesetStore(contextFactory));
dependencies.Cache(FileStore = new FileStore(contextFactory, Host.Storage));
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, API, Audio, Host));
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap));
dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, BeatmapManager, Host.Storage, contextFactory, Host));
dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore));
dependencies.Cache(SettingsStore = new SettingsStore(contextFactory));
@ -166,10 +169,6 @@ namespace osu.Game
fileImporters.Add(ScoreManager);
fileImporters.Add(SkinManager);
var defaultBeatmap = new DummyWorkingBeatmap(this);
beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio);
BeatmapManager.DefaultBeatmap = defaultBeatmap;
// tracks play so loud our samples can't keep up.
// this adds a global reduction of track volume for the time being.
Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));

View File

@ -17,6 +17,7 @@ using osu.Game.Graphics;
using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
using RectangleF = osu.Framework.Graphics.Primitives.RectangleF;
using Container = osu.Framework.Graphics.Containers.Container;
@ -86,25 +87,29 @@ namespace osu.Game.Overlays.Settings.Sections.General
};
break;
case APIState.Failing:
Children = new Drawable[]
{
new OsuSpriteText
{
Text = "Connection failing :(",
},
};
break;
case APIState.Connecting:
LinkFlowContainer linkFlow;
Children = new Drawable[]
{
new OsuSpriteText
new LoadingAnimation
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = "Connecting...",
State = Visibility.Visible,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
},
linkFlow = new LinkFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
TextAnchor = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Text = state == APIState.Failing ? "Connection is failing, will attempt to reconnect... " : "Attempting to connect... ",
Margin = new MarginPadding { Top = 10, Bottom = 10 },
},
};
linkFlow.AddLink("cancel", api.Logout, string.Empty);
break;
case APIState.Online:
Children = new Drawable[]

View File

@ -18,7 +18,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Framework" Version="2018.1221.0" />
<PackageReference Include="ppy.osu.Framework" Version="2018.1226.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />