1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 03:27:24 +08:00

Use interface to access API

Allows for better testability.
This commit is contained in:
Dean Herbert 2019-03-13 12:56:47 +09:00
parent 13f84e8d50
commit f0114d776d
33 changed files with 127 additions and 61 deletions

View File

@ -28,7 +28,7 @@ namespace osu.Game.Tests.Visual
} }
[Resolved] [Resolved]
private APIAccess api { get; set; } private IAPIProvider api { get; set; }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -22,7 +22,7 @@ namespace osu.Game.Tests.Visual
private BeatmapManager beatmaps { get; set; } private BeatmapManager beatmaps { get; set; }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuGameBase osu, APIAccess api, RulesetStore rulesets) private void load(OsuGameBase osu, IAPIProvider api, RulesetStore rulesets)
{ {
Bindable<BeatmapInfo> beatmapBindable = new Bindable<BeatmapInfo>(); Bindable<BeatmapInfo> beatmapBindable = new Bindable<BeatmapInfo>();

View File

@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual
public class TestCaseUserProfile : OsuTestCase public class TestCaseUserProfile : OsuTestCase
{ {
private readonly TestUserProfileOverlay profile; private readonly TestUserProfileOverlay profile;
private APIAccess api; private IAPIProvider api;
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api) private void load(IAPIProvider api)
{ {
this.api = api; this.api = api;
} }

View File

@ -64,7 +64,7 @@ namespace osu.Game.Beatmaps
private readonly BeatmapStore beatmaps; private readonly BeatmapStore beatmaps;
private readonly APIAccess api; private readonly IAPIProvider api;
private readonly AudioManager audioManager; private readonly AudioManager audioManager;
@ -72,7 +72,7 @@ namespace osu.Game.Beatmaps
private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>(); private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>();
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, GameHost host = null, public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null,
WorkingBeatmap defaultBeatmap = null) WorkingBeatmap defaultBeatmap = null)
: base(storage, contextFactory, new BeatmapStore(contextFactory), host) : base(storage, contextFactory, new BeatmapStore(contextFactory), host)
{ {

View File

@ -22,7 +22,7 @@ namespace osu.Game.Online.API
private readonly OsuConfigManager config; private readonly OsuConfigManager config;
private readonly OAuth authentication; private readonly OAuth authentication;
public string Endpoint = @"https://osu.ppy.sh"; public string Endpoint => @"https://osu.ppy.sh";
private const string client_id = @"5"; private const string client_id = @"5";
private const string client_secret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"; private const string client_secret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk";

View File

@ -61,9 +61,12 @@ namespace osu.Game.Online.API
private Action pendingFailure; private Action pendingFailure;
public void Perform(APIAccess api) public void Perform(IAPIProvider api)
{ {
API = api; if (!(api is APIAccess apiAccess))
throw new NotSupportedException($"A {nameof(APIAccess)} is required to perform requests.");
API = apiAccess;
if (checkAndScheduleFailure()) if (checkAndScheduleFailure())
return; return;
@ -71,7 +74,7 @@ namespace osu.Game.Online.API
WebRequest = CreateWebRequest(); WebRequest = CreateWebRequest();
WebRequest.Failed += Fail; WebRequest.Failed += Fail;
WebRequest.AllowRetryOnTimeout = false; WebRequest.AllowRetryOnTimeout = false;
WebRequest.AddHeader("Authorization", $"Bearer {api.AccessToken}"); WebRequest.AddHeader("Authorization", $"Bearer {API.AccessToken}");
if (checkAndScheduleFailure()) if (checkAndScheduleFailure())
return; return;
@ -85,7 +88,7 @@ namespace osu.Game.Online.API
if (checkAndScheduleFailure()) if (checkAndScheduleFailure())
return; return;
api.Schedule(delegate { Success?.Invoke(); }); API.Schedule(delegate { Success?.Invoke(); });
} }
public void Cancel() => Fail(new OperationCanceledException(@"Request cancelled")); public void Cancel() => Fail(new OperationCanceledException(@"Request cancelled"));

View File

@ -11,14 +11,16 @@ namespace osu.Game.Online.API
public Bindable<User> LocalUser { get; } = new Bindable<User>(new User public Bindable<User> LocalUser { get; } = new Bindable<User>(new User
{ {
Username = @"Dummy", Username = @"Dummy",
Id = 1, Id = 1001,
}); });
public bool IsLoggedIn => true; public bool IsLoggedIn => true;
public void Update() public string ProvidedUsername => LocalUser.Value.Username;
{
} public string Endpoint => "https://test.com";
public APIState State => LocalUser.Value.Id == 1 ? APIState.Offline : APIState.Online;
public virtual void Queue(APIRequest request) public virtual void Queue(APIRequest request)
{ {
@ -26,6 +28,28 @@ namespace osu.Game.Online.API
public void Register(IOnlineComponent component) public void Register(IOnlineComponent component)
{ {
// todo: add support
} }
public void Unregister(IOnlineComponent component)
{
// todo: add support
}
public void Login(string username, string password)
{
LocalUser.Value = new User
{
Username = @"Dummy",
Id = 1,
};
}
public void Logout()
{
LocalUser.Value = new GuestUser();
}
public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password) => null;
} }
} }

View File

@ -18,6 +18,19 @@ namespace osu.Game.Online.API
/// </summary> /// </summary>
bool IsLoggedIn { get; } bool IsLoggedIn { get; }
/// <summary>
/// The last username provided by the end-user.
/// May not be authenticated.
/// </summary>
string ProvidedUsername { get; }
/// <summary>
/// The URL endpoint for this API. Does not include a trailing slash.
/// </summary>
string Endpoint { get; }
APIState State { get; }
/// <summary> /// <summary>
/// Queue a new request. /// Queue a new request.
/// </summary> /// </summary>
@ -29,5 +42,32 @@ namespace osu.Game.Online.API
/// </summary> /// </summary>
/// <param name="component">The component to register.</param> /// <param name="component">The component to register.</param>
void Register(IOnlineComponent component); void Register(IOnlineComponent component);
/// <summary>
/// Unregisters a component to receive state changes.
/// </summary>
/// <param name="component">The component to unregister.</param>
void Unregister(IOnlineComponent component);
/// <summary>
/// Attempt to login using the provided credentials. This is a non-blocking operation.
/// </summary>
/// <param name="username">The user's username.</param>
/// <param name="password">The user's password.</param>
void Login(string username, string password);
/// <summary>
/// Log out the current user.
/// </summary>
void Logout();
/// <summary>
/// Create a new user account. This is a blocking operation.
/// </summary>
/// <param name="email">The email to create the account with.</param>
/// <param name="username">The username to create the account with.</param>
/// <param name="password">The password to create the account with.</param>
/// <returns>Any errors encoutnered during account creation.</returns>
RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password);
} }
} }

View File

@ -5,6 +5,6 @@ namespace osu.Game.Online.API
{ {
public interface IOnlineComponent public interface IOnlineComponent
{ {
void APIStateChanged(APIAccess api, APIState state); void APIStateChanged(IAPIProvider api, APIState state);
} }
} }

View File

@ -174,12 +174,12 @@ namespace osu.Game.Online.Leaderboards
}; };
} }
private APIAccess api; private IAPIProvider api;
private ScheduledDelegate pendingUpdateScores; private ScheduledDelegate pendingUpdateScores;
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(APIAccess api) private void load(IAPIProvider api)
{ {
this.api = api; this.api = api;
api?.Register(this); api?.Register(this);
@ -195,7 +195,7 @@ namespace osu.Game.Online.Leaderboards
private APIRequest getScoresRequest; private APIRequest getScoresRequest;
public void APIStateChanged(APIAccess api, APIState state) public void APIStateChanged(IAPIProvider api, APIState state)
{ {
if (state == APIState.Online) if (state == APIState.Online)
UpdateScores(); UpdateScores();

View File

@ -152,7 +152,6 @@ namespace osu.Game
API = new APIAccess(LocalConfig); API = new APIAccess(LocalConfig);
dependencies.Cache(API);
dependencies.CacheAs<IAPIProvider>(API); dependencies.CacheAs<IAPIProvider>(API);
var defaultBeatmap = new DummyWorkingBeatmap(this); var defaultBeatmap = new DummyWorkingBeatmap(this);

View File

@ -33,7 +33,7 @@ namespace osu.Game.Overlays.AccountCreation
private OsuTextBox emailTextBox; private OsuTextBox emailTextBox;
private OsuPasswordTextBox passwordTextBox; private OsuPasswordTextBox passwordTextBox;
private APIAccess api; private IAPIProvider api;
private ShakeContainer registerShake; private ShakeContainer registerShake;
private IEnumerable<Drawable> characterCheckText; private IEnumerable<Drawable> characterCheckText;
@ -42,7 +42,7 @@ namespace osu.Game.Overlays.AccountCreation
private GameHost host; private GameHost host;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours, APIAccess api, GameHost host) private void load(OsuColour colours, IAPIProvider api, GameHost host)
{ {
this.api = api; this.api = api;
this.host = host; this.host = host;

View File

@ -22,7 +22,7 @@ namespace osu.Game.Overlays.AccountCreation
{ {
private OsuTextFlowContainer multiAccountExplanationText; private OsuTextFlowContainer multiAccountExplanationText;
private LinkFlowContainer furtherAssistance; private LinkFlowContainer furtherAssistance;
private APIAccess api; private IAPIProvider api;
private const string help_centre_url = "/help/wiki/Help_Centre#login"; private const string help_centre_url = "/help/wiki/Help_Centre#login";
@ -39,7 +39,7 @@ namespace osu.Game.Overlays.AccountCreation
} }
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(OsuColour colours, APIAccess api, OsuGame game, TextureStore textures) private void load(OsuColour colours, IAPIProvider api, OsuGame game, TextureStore textures)
{ {
this.api = api; this.api = api;

View File

@ -30,7 +30,7 @@ namespace osu.Game.Overlays
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours, APIAccess api) private void load(OsuColour colours, IAPIProvider api)
{ {
api.Register(this); api.Register(this);
@ -96,7 +96,7 @@ namespace osu.Game.Overlays
this.FadeOut(100); this.FadeOut(100);
} }
public void APIStateChanged(APIAccess api, APIState state) public void APIStateChanged(IAPIProvider api, APIState state)
{ {
switch (state) switch (state)
{ {

View File

@ -39,7 +39,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api, BeatmapManager beatmaps) private void load(IAPIProvider api, BeatmapManager beatmaps)
{ {
FillFlowContainer textSprites; FillFlowContainer textSprites;

View File

@ -45,7 +45,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
} }
private GetScoresRequest getScoresRequest; private GetScoresRequest getScoresRequest;
private APIAccess api; private IAPIProvider api;
public BeatmapInfo Beatmap public BeatmapInfo Beatmap
{ {
@ -129,7 +129,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api) private void load(IAPIProvider api)
{ {
this.api = api; this.api = api;
updateDisplay(); updateDisplay();

View File

@ -31,7 +31,7 @@ namespace osu.Game.Overlays
private readonly Header header; private readonly Header header;
private APIAccess api; private IAPIProvider api;
private RulesetStore rulesets; private RulesetStore rulesets;
private readonly ScrollContainer scroll; private readonly ScrollContainer scroll;
@ -101,7 +101,7 @@ namespace osu.Game.Overlays
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api, RulesetStore rulesets) private void load(IAPIProvider api, RulesetStore rulesets)
{ {
this.api = api; this.api = api;
this.rulesets = rulesets; this.rulesets = rulesets;

View File

@ -28,7 +28,7 @@ namespace osu.Game.Overlays
{ {
private const float panel_padding = 10f; private const float panel_padding = 10f;
private APIAccess api; private IAPIProvider api;
private RulesetStore rulesets; private RulesetStore rulesets;
private readonly FillFlowContainer resultCountsContainer; private readonly FillFlowContainer resultCountsContainer;
@ -164,7 +164,7 @@ namespace osu.Game.Overlays
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours, APIAccess api, RulesetStore rulesets, PreviewTrackManager previewTrackManager) private void load(OsuColour colours, IAPIProvider api, RulesetStore rulesets, PreviewTrackManager previewTrackManager)
{ {
this.api = api; this.api = api;
this.rulesets = rulesets; this.rulesets = rulesets;

View File

@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile.Sections
protected readonly Bindable<User> User = new Bindable<User>(); protected readonly Bindable<User> User = new Bindable<User>();
protected APIAccess Api; protected IAPIProvider Api;
protected APIRequest RetrievalRequest; protected APIRequest RetrievalRequest;
protected RulesetStore Rulesets; protected RulesetStore Rulesets;
@ -84,7 +84,7 @@ namespace osu.Game.Overlays.Profile.Sections
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api, RulesetStore rulesets) private void load(IAPIProvider api, RulesetStore rulesets)
{ {
Api = api; Api = api;
Rulesets = rulesets; Rulesets = rulesets;

View File

@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
{ {
public class DrawableRecentActivity : DrawableProfileRow public class DrawableRecentActivity : DrawableProfileRow
{ {
private APIAccess api; private IAPIProvider api;
private readonly APIRecentActivity activity; private readonly APIRecentActivity activity;
@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api) private void load(IAPIProvider api)
{ {
this.api = api; this.api = api;

View File

@ -58,14 +58,14 @@ namespace osu.Game.Overlays.Settings.Sections.General
} }
[BackgroundDependencyLoader(permitNulls: true)] [BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuColour colours, APIAccess api) private void load(OsuColour colours, IAPIProvider api)
{ {
this.colours = colours; this.colours = colours;
api?.Register(this); api?.Register(this);
} }
public void APIStateChanged(APIAccess api, APIState state) public void APIStateChanged(IAPIProvider api, APIState state)
{ {
form = null; form = null;
@ -194,7 +194,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
{ {
private TextBox username; private TextBox username;
private TextBox password; private TextBox password;
private APIAccess api; private IAPIProvider api;
public Action RequestHide; public Action RequestHide;
@ -205,7 +205,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
} }
[BackgroundDependencyLoader(permitNulls: true)] [BackgroundDependencyLoader(permitNulls: true)]
private void load(APIAccess api, OsuConfigManager config, AccountCreationOverlay accountCreation) private void load(IAPIProvider api, OsuConfigManager config, AccountCreationOverlay accountCreation)
{ {
this.api = api; this.api = api;
Direction = FillDirection.Vertical; Direction = FillDirection.Vertical;

View File

@ -22,7 +22,7 @@ namespace osu.Game.Overlays
{ {
public class SocialOverlay : SearchableListOverlay<SocialTab, SocialSortCriteria, SortDirection>, IOnlineComponent public class SocialOverlay : SearchableListOverlay<SocialTab, SocialSortCriteria, SortDirection>, IOnlineComponent
{ {
private APIAccess api; private IAPIProvider api;
private readonly LoadingAnimation loading; private readonly LoadingAnimation loading;
private FillFlowContainer<SocialPanel> panels; private FillFlowContainer<SocialPanel> panels;
@ -89,7 +89,7 @@ namespace osu.Game.Overlays
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api) private void load(IAPIProvider api)
{ {
this.api = api; this.api = api;
api.Register(this); api.Register(this);
@ -193,7 +193,7 @@ namespace osu.Game.Overlays
} }
} }
public void APIStateChanged(APIAccess api, APIState state) public void APIStateChanged(IAPIProvider api, APIState state)
{ {
switch (state) switch (state)
{ {

View File

@ -43,12 +43,12 @@ namespace osu.Game.Overlays.Toolbar
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api) private void load(IAPIProvider api)
{ {
api.Register(this); api.Register(this);
} }
public void APIStateChanged(APIAccess api, APIState state) public void APIStateChanged(IAPIProvider api, APIState state)
{ {
switch (state) switch (state)
{ {

View File

@ -26,7 +26,7 @@ namespace osu.Game.Overlays
private ProfileSection lastSection; private ProfileSection lastSection;
private ProfileSection[] sections; private ProfileSection[] sections;
private GetUserRequest userReq; private GetUserRequest userReq;
private APIAccess api; private IAPIProvider api;
protected ProfileHeader Header; protected ProfileHeader Header;
private SectionsContainer<ProfileSection> sectionsContainer; private SectionsContainer<ProfileSection> sectionsContainer;
private ProfileTabControl tabs; private ProfileTabControl tabs;
@ -56,7 +56,7 @@ namespace osu.Game.Overlays
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api) private void load(IAPIProvider api)
{ {
this.api = api; this.api = api;
} }

View File

@ -97,7 +97,7 @@ namespace osu.Game.Screens.Menu
private OsuGame game { get; set; } private OsuGame game { get; set; }
[Resolved] [Resolved]
private APIAccess api { get; set; } private IAPIProvider api { get; set; }
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
private NotificationOverlay notifications { get; set; } private NotificationOverlay notifications { get; set; }

View File

@ -1,4 +1,4 @@
// 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;
@ -44,7 +44,7 @@ namespace osu.Game.Screens.Menu
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours, APIAccess api) private void load(OsuColour colours, IAPIProvider api)
{ {
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {

View File

@ -246,7 +246,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components
} }
[Resolved] [Resolved]
private APIAccess api { get; set; } private IAPIProvider api { get; set; }
private GetRoomScoresRequest request; private GetRoomScoresRequest request;

View File

@ -54,7 +54,7 @@ namespace osu.Game.Screens.Multi
private OsuGameBase game { get; set; } private OsuGameBase game { get; set; }
[Resolved] [Resolved]
private APIAccess api { get; set; } private IAPIProvider api { get; set; }
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
private OsuLogo logo { get; set; } private OsuLogo logo { get; set; }
@ -163,7 +163,7 @@ namespace osu.Game.Screens.Multi
this.Push(new PlayerLoader(player)); this.Push(new PlayerLoader(player));
} }
public void APIStateChanged(APIAccess api, APIState state) public void APIStateChanged(IAPIProvider api, APIState state)
{ {
if (state != APIState.Online) if (state != APIState.Online)
forcefullyExit(); forcefullyExit();

View File

@ -32,7 +32,7 @@ namespace osu.Game.Screens.Multi.Play
private readonly PlaylistItem playlistItem; private readonly PlaylistItem playlistItem;
[Resolved] [Resolved]
private APIAccess api { get; set; } private IAPIProvider api { get; set; }
[Resolved] [Resolved]
private IBindable<RulesetInfo> ruleset { get; set; } private IBindable<RulesetInfo> ruleset { get; set; }

View File

@ -30,7 +30,7 @@ namespace osu.Game.Screens.Multi
private Bindable<FilterCriteria> currentFilter { get; set; } private Bindable<FilterCriteria> currentFilter { get; set; }
[Resolved] [Resolved]
private APIAccess api { get; set; } private IAPIProvider api { get; set; }
[Resolved] [Resolved]
private RulesetStore rulesets { get; set; } private RulesetStore rulesets { get; set; }

View File

@ -60,7 +60,7 @@ namespace osu.Game.Screens.Play
private RulesetInfo ruleset; private RulesetInfo ruleset;
private APIAccess api; private IAPIProvider api;
private SampleChannel sampleRestart; private SampleChannel sampleRestart;
@ -85,7 +85,7 @@ namespace osu.Game.Screens.Play
private GameplayClockContainer gameplayClockContainer; private GameplayClockContainer gameplayClockContainer;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audio, APIAccess api, OsuConfigManager config) private void load(AudioManager audio, IAPIProvider api, OsuConfigManager config)
{ {
this.api = api; this.api = api;

View File

@ -36,7 +36,7 @@ namespace osu.Game.Screens.Select
private readonly FailRetryGraph failRetryGraph; private readonly FailRetryGraph failRetryGraph;
private readonly DimmedLoadingAnimation loading; private readonly DimmedLoadingAnimation loading;
private APIAccess api; private IAPIProvider api;
private ScheduledDelegate pendingBeatmapSwitch; private ScheduledDelegate pendingBeatmapSwitch;
@ -160,7 +160,7 @@ namespace osu.Game.Screens.Select
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(APIAccess api) private void load(IAPIProvider api)
{ {
this.api = api; this.api = api;
} }

View File

@ -43,7 +43,7 @@ namespace osu.Game.Screens.Select.Leaderboards
private IBindable<RulesetInfo> ruleset { get; set; } private IBindable<RulesetInfo> ruleset { get; set; }
[Resolved] [Resolved]
private APIAccess api { get; set; } private IAPIProvider api { get; set; }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()