1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-14 05:24:07 +08:00

Compare commits

...

101 Commits

83 changed files with 618 additions and 523 deletions
+3 -1
View File
@@ -24,7 +24,9 @@ Clone the repository including submodules
Build and run
- Using Visual Studio 2017, Rider or Visual Studio Code (configurations are included)
- From command line using `dotnet run --project osu.Desktop`
- From command line using `dotnet run --project osu.Desktop`. When building for non-development purposes, add `-c Release` to gain higher performance.
Note: If you run from command line under linux, you will need to prefix the output folder to your `LD_LIBRARY_PATH`. See `.vscode/launch.json` for an example
If you run into issues building you may need to restore nuget packages (commonly via `dotnet restore`). Visual Studio Code users must run `Restore` task from debug tab before attempt to build.
+2 -3
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -32,7 +31,7 @@ namespace osu.Desktop.Overlays
public override bool HandleMouseInput => false;
[BackgroundDependencyLoader]
private async Task load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config, GameHost host)
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config, GameHost host)
{
notificationOverlay = notification;
this.config = config;
@@ -87,7 +86,7 @@ namespace osu.Desktop.Overlays
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Texture = await textures.GetAsync(@"Menu/dev-build-footer"),
Texture = textures.Get(@"Menu/dev-build-footer"),
},
}
}
+8 -11
View File
@@ -3,7 +3,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -408,9 +407,7 @@ namespace osu.Game.Rulesets.Catch.UI
/// </summary>
public void Explode()
{
var fruit = caughtFruit.ToArray();
foreach (var f in fruit)
foreach (var f in caughtFruit.ToArray())
Explode(f);
}
@@ -423,15 +420,15 @@ namespace osu.Game.Rulesets.Catch.UI
fruit.Anchor = Anchor.TopLeft;
fruit.Position = caughtFruit.ToSpaceOfOtherDrawable(fruit.DrawPosition, ExplodingFruitTarget);
caughtFruit.Remove(fruit);
if (!caughtFruit.Remove(fruit))
// we may have already been removed by a previous operation (due to the weird OnLoadComplete scheduling).
// this avoids a crash on potentially attempting to Add a fruit to ExplodingFruitTarget twice.
return;
ExplodingFruitTarget.Add(fruit);
}
fruit.MoveToY(fruit.Y - 50, 250, Easing.OutSine)
.Then()
.MoveToY(fruit.Y + 50, 500, Easing.InSine);
fruit.MoveToY(fruit.Y - 50, 250, Easing.OutSine).Then().MoveToY(fruit.Y + 50, 500, Easing.InSine);
fruit.MoveToX(fruit.X + originalX * 6, 1000);
fruit.FadeOut(750);
@@ -449,9 +446,9 @@ namespace osu.Game.Rulesets.Catch.UI
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
Texture = await textures.GetAsync(@"Play/Catch/fruit-catcher-idle");
Texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
}
}
}
@@ -111,6 +111,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
bodyPiece.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2;
}
protected void BeginHold()
{
holdStartTime = Time.Current;
bodyPiece.Hitting = true;
}
protected void EndHold()
{
holdStartTime = null;
bodyPiece.Hitting = false;
}
public bool OnPressed(ManiaAction action)
{
// Make sure the action happened within the body of the hold note
@@ -123,8 +135,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
// The user has pressed during the body of the hold note, after the head note and its hit windows have passed
// and within the limited range of the above if-statement. This state will be managed by the head note if the
// user has pressed during the hit windows of the head note.
holdStartTime = Time.Current;
BeginHold();
return true;
}
@@ -137,7 +148,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (action != Action.Value)
return false;
holdStartTime = null;
EndHold();
// If the key has been released too early, the user should not receive full score for the release
if (!Tail.IsHit)
@@ -170,7 +181,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
// The head note also handles early hits before the body, but we want accurate early hits to count as the body being held
// The body doesn't handle these early early hits, so we have to explicitly set the holding state here
holdNote.holdStartTime = Time.Current;
holdNote.BeginHold();
return true;
}
@@ -32,6 +32,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
background = new Box { RelativeSizeAxes = Axes.Both },
foreground = new BufferedContainer
{
Blending = BlendingMode.Additive,
RelativeSizeAxes = Axes.Both,
CacheDrawnFrameBuffer = true,
Children = new Drawable[]
@@ -73,6 +74,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
}
private Color4 accentColour;
public Color4 AccentColour
{
get { return accentColour; }
@@ -86,6 +88,16 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
}
}
public bool Hitting
{
get { return hitting; }
set
{
hitting = value;
updateAccentColour();
}
}
private Cached subtractionCache = new Cached();
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
@@ -118,13 +130,26 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
}
}
private bool hitting;
private void updateAccentColour()
{
if (!IsLoaded)
return;
foreground.Colour = AccentColour.Opacity(0.9f);
background.Colour = AccentColour.Opacity(0.6f);
foreground.Colour = AccentColour.Opacity(0.5f);
background.Colour = AccentColour.Opacity(0.7f);
const float animation_length = 50;
foreground.ClearTransforms(false, nameof(foreground.Colour));
if (hitting)
{
// wait for the next sync point
double synchronisedOffset = animation_length * 2 - Time.Current % (animation_length * 2);
using (foreground.BeginDelayedSequence(synchronisedOffset))
foreground.FadeColour(AccentColour.Lighten(0.2f), animation_length).Then().FadeColour(foreground.Colour, animation_length).Loop();
}
subtractionCache.Invalidate();
}
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableOsuHitObject : DrawableHitObject<OsuHitObject>
{
public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Time.Current >= HitObject.StartTime - HitObject.TimePreempt;
public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Clock?.CurrentTime >= HitObject.StartTime - HitObject.TimePreempt;
private readonly ShakeContainer shakeContainer;
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -13,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
public class DefaultCirclePiece : Container
{
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
@@ -22,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Texture = await textures.GetAsync(@"Play/osu/disc"),
Texture = textures.Get(@"Play/osu/disc"),
},
new TrianglesPiece
{
@@ -7,14 +7,15 @@ using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Lines;
using osu.Framework.Graphics.Textures;
using OpenTK;
using OpenTK.Graphics.ES30;
using OpenTK.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Game.Rulesets.Objects.Types;
using OpenTK;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
@@ -43,6 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
public double? SnakedEnd { get; private set; }
private Color4 accentColour = Color4.White;
/// <summary>
/// Used to colour the path.
/// </summary>
@@ -61,6 +63,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
}
private Color4 borderColour = Color4.White;
/// <summary>
/// Used to colour the path border.
/// </summary>
@@ -85,6 +88,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
private Vector2 topLeftOffset;
private readonly Slider slider;
public SliderBody(Slider s)
{
slider = s;
@@ -139,8 +143,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
var texture = new Texture(textureWidth, 1);
//initialise background
var raw = new RawTexture(textureWidth, 1);
var bytes = raw.Data;
var raw = new Image<Rgba32>(textureWidth, 1);
const float aa_portion = 0.02f;
const float border_portion = 0.128f;
@@ -155,19 +158,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
if (progress <= border_portion)
{
bytes[i * 4] = (byte)(BorderColour.R * 255);
bytes[i * 4 + 1] = (byte)(BorderColour.G * 255);
bytes[i * 4 + 2] = (byte)(BorderColour.B * 255);
bytes[i * 4 + 3] = (byte)(Math.Min(progress / aa_portion, 1) * (BorderColour.A * 255));
raw[i, 0] = new Rgba32(BorderColour.R, BorderColour.G, BorderColour.B, Math.Min(progress / aa_portion, 1) * BorderColour.A);
}
else
{
progress -= border_portion;
bytes[i * 4] = (byte)(AccentColour.R * 255);
bytes[i * 4 + 1] = (byte)(AccentColour.G * 255);
bytes[i * 4 + 2] = (byte)(AccentColour.B * 255);
bytes[i * 4 + 3] = (byte)((opacity_at_edge - (opacity_at_edge - opacity_at_centre) * progress / gradient_portion) * (AccentColour.A * 255));
raw[i, 0] = new Rgba32(AccentColour.R, AccentColour.G, AccentColour.B,
(opacity_at_edge - (opacity_at_edge - opacity_at_centre) * progress / gradient_portion) * AccentColour.A);
}
}
@@ -4,7 +4,6 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.OpenGL.Buffers;
@@ -80,10 +79,10 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true;
[BackgroundDependencyLoader]
private async Task load(ShaderManager shaders, TextureStore textures)
private void load(ShaderManager shaders, TextureStore textures)
{
shader = shaders?.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE);
texture = await textures.GetAsync(@"Cursor/cursortrail");
texture = textures.Get(@"Cursor/cursortrail");
Scale = new Vector2(1 / texture.ScaleAdjust);
}
@@ -217,7 +216,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
Texture.DrawQuad(
new Quad(pos.X - Size.X / 2, pos.Y - Size.Y / 2, Size.X, Size.Y),
DrawInfo.Colour,
DrawColourInfo.Colour,
null,
v => Shared.VertexBuffer.Vertices[end++] = new TexturedTrailVertex
{
+5 -6
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -131,12 +130,12 @@ namespace osu.Game.Rulesets.Taiko.UI
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures, OsuColour colours)
private void load(TextureStore textures, OsuColour colours)
{
rim.Texture = await textures.GetAsync(@"Play/Taiko/taiko-drum-outer");
rimHit.Texture = await textures.GetAsync(@"Play/Taiko/taiko-drum-outer-hit");
centre.Texture = await textures.GetAsync(@"Play/Taiko/taiko-drum-inner");
centreHit.Texture = await textures.GetAsync(@"Play/Taiko/taiko-drum-inner-hit");
rim.Texture = textures.Get(@"Play/Taiko/taiko-drum-outer");
rimHit.Texture = textures.Get(@"Play/Taiko/taiko-drum-outer-hit");
centre.Texture = textures.Get(@"Play/Taiko/taiko-drum-inner");
centreHit.Texture = textures.Get(@"Play/Taiko/taiko-drum-inner-hit");
rimHit.Colour = colours.Blue;
centreHit.Colour = colours.Pink;
+15 -32
View File
@@ -11,6 +11,7 @@ using Microsoft.EntityFrameworkCore;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics.Textures;
using osu.Framework.Logging;
using osu.Framework.Platform;
@@ -62,6 +63,8 @@ namespace osu.Game.Beatmaps
public override string[] HandledExtensions => new[] { ".osz" };
protected override string ImportFromStablePath => "Songs";
private readonly RulesetStore rulesets;
private readonly BeatmapStore beatmaps;
@@ -72,11 +75,6 @@ namespace osu.Game.Beatmaps
private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>();
/// <summary>
/// Set a storage with access to an osu-stable install for import purposes.
/// </summary>
public Func<Storage> GetStableStorage { private get; set; }
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null)
: base(storage, contextFactory, new BeatmapStore(contextFactory), importHost)
{
@@ -103,6 +101,11 @@ namespace osu.Game.Beatmaps
b.BeatmapSet = beatmapSet;
}
validateOnlineIds(beatmapSet.Beatmaps);
foreach (BeatmapInfo b in beatmapSet.Beatmaps)
fetchAndPopulateOnlineIDs(b, beatmapSet.Beatmaps);
// check if a set already exists with the same online id, delete if it does.
if (beatmapSet.OnlineBeatmapSetID != null)
{
@@ -114,11 +117,6 @@ namespace osu.Game.Beatmaps
Logger.Log($"Found existing beatmap set with same OnlineBeatmapSetID ({beatmapSet.OnlineBeatmapSetID}). It has been purged.", LoggingTarget.Database);
}
}
validateOnlineIds(beatmapSet.Beatmaps);
foreach (BeatmapInfo b in beatmapSet.Beatmaps)
fetchAndPopulateOnlineIDs(b, beatmapSet.Beatmaps);
}
private void validateOnlineIds(List<BeatmapInfo> beatmaps)
@@ -195,7 +193,7 @@ namespace osu.Game.Beatmaps
downloadNotification.CompletionClickAction = () =>
{
PresentBeatmap?.Invoke(importedBeatmap);
PresentCompletedImport(importedBeatmap.Yield());
return true;
};
downloadNotification.State = ProgressNotificationState.Completed;
@@ -231,6 +229,12 @@ namespace osu.Game.Beatmaps
BeatmapDownloadBegan?.Invoke(request);
}
protected override void PresentCompletedImport(IEnumerable<BeatmapSetInfo> imported)
{
base.PresentCompletedImport(imported);
PresentBeatmap?.Invoke(imported.LastOrDefault());
}
/// <summary>
/// Get an existing download request if it exists.
/// </summary>
@@ -311,27 +315,6 @@ namespace osu.Game.Beatmaps
/// <returns>Results from the provided query.</returns>
public IQueryable<BeatmapInfo> QueryBeatmaps(Expression<Func<BeatmapInfo, bool>> query) => beatmaps.Beatmaps.AsNoTracking().Where(query);
/// <summary>
/// Denotes whether an osu-stable installation is present to perform automated imports from.
/// </summary>
public bool StableInstallationAvailable => GetStableStorage?.Invoke() != null;
/// <summary>
/// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future.
/// </summary>
public Task ImportFromStable()
{
var stable = GetStableStorage?.Invoke();
if (stable == null)
{
Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error);
return Task.CompletedTask;
}
return Task.Factory.StartNew(() => Import(stable.GetDirectories("Songs").Select(f => stable.GetFullPath(f)).ToArray()), TaskCreationOptions.LongRunning);
}
/// <summary>
/// Create a SHA-2 hash from the provided archive based on contained beatmap (.osu) file content.
/// </summary>
@@ -10,7 +10,6 @@ using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores;
using osu.Framework.Logging;
using osu.Game.Beatmaps.Formats;
using osu.Game.Graphics.Textures;
using osu.Game.Skinning;
using osu.Game.Storyboards;
@@ -45,6 +44,10 @@ namespace osu.Game.Beatmaps
private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase)).FileInfo.StoragePath;
private LargeTextureStore textureStore;
protected override bool BackgroundStillValid(Texture b) => false; // bypass lazy logic. we want to return a new background each time for refcounting purposes.
protected override Texture GetBackground()
{
if (Metadata?.BackgroundFile == null)
@@ -52,7 +55,7 @@ namespace osu.Game.Beatmaps
try
{
return new LargeTextureStore(new RawTextureLoaderStore(store)).Get(getPathForFile(Metadata.BackgroundFile));
return (textureStore ?? (textureStore = new LargeTextureStore(new TextureLoaderStore(store)))).Get(getPathForFile(Metadata.BackgroundFile));
}
catch
{
@@ -73,6 +76,14 @@ namespace osu.Game.Beatmaps
}
}
public override void TransferTo(WorkingBeatmap other)
{
base.TransferTo(other);
if (other is BeatmapManagerWorkingBeatmap owb && textureStore != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo))
owb.textureStore = textureStore;
}
protected override Waveform GetWaveform()
{
try
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
@@ -24,7 +23,7 @@ namespace osu.Game.Beatmaps.Drawables
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
string resource = null;
@@ -42,7 +41,7 @@ namespace osu.Game.Beatmaps.Drawables
}
if (resource != null)
Texture = await textures.GetAsync(resource);
Texture = textures.Get(resource);
}
}
+67 -101
View File
@@ -8,10 +8,10 @@ using osu.Game.Rulesets.Mods;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using osu.Game.Storyboards;
using osu.Framework.IO.File;
using System.IO;
using System.Threading;
using osu.Game.IO.Serialization;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
@@ -38,12 +38,26 @@ namespace osu.Game.Beatmaps
Mods.ValueChanged += mods => applyRateAdjustments();
beatmap = new AsyncLazy<IBeatmap>(populateBeatmap);
background = new AsyncLazy<Texture>(populateBackground, b => b == null || !b.IsDisposed);
track = new AsyncLazy<Track>(populateTrack);
waveform = new AsyncLazy<Waveform>(populateWaveform);
storyboard = new AsyncLazy<Storyboard>(populateStoryboard);
skin = new AsyncLazy<Skin>(populateSkin);
beatmap = new RecyclableLazy<IBeatmap>(() =>
{
var b = GetBeatmap() ?? new Beatmap();
// use the database-backed info.
b.BeatmapInfo = BeatmapInfo;
return b;
});
track = new RecyclableLazy<Track>(() =>
{
// we want to ensure that we always have a track, even if it's a fake one.
var t = GetTrack() ?? new VirtualBeatmapTrack(Beatmap);
applyRateAdjustments(t);
return t;
});
background = new RecyclableLazy<Texture>(GetBackground, BackgroundStillValid);
waveform = new RecyclableLazy<Waveform>(GetWaveform);
storyboard = new RecyclableLazy<Storyboard>(GetStoryboard);
skin = new RecyclableLazy<Skin>(GetSkin);
}
/// <summary>
@@ -58,28 +72,6 @@ namespace osu.Game.Beatmaps
return path;
}
protected abstract IBeatmap GetBeatmap();
protected abstract Texture GetBackground();
protected abstract Track GetTrack();
protected virtual Skin GetSkin() => new DefaultSkin();
protected virtual Waveform GetWaveform() => new Waveform();
protected virtual Storyboard GetStoryboard() => new Storyboard { BeatmapInfo = BeatmapInfo };
public bool BeatmapLoaded => beatmap.IsResultAvailable;
public IBeatmap Beatmap => beatmap.Value.Result;
public Task<IBeatmap> GetBeatmapAsync() => beatmap.Value;
private readonly AsyncLazy<IBeatmap> beatmap;
private IBeatmap populateBeatmap()
{
var b = GetBeatmap() ?? new Beatmap();
// use the database-backed info.
b.BeatmapInfo = BeatmapInfo;
return b;
}
/// <summary>
/// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>.
/// <para>
@@ -136,62 +128,53 @@ namespace osu.Game.Beatmaps
public override string ToString() => BeatmapInfo.ToString();
public bool BackgroundLoaded => background.IsResultAvailable;
public Texture Background => background.Value.Result;
public Task<Texture> GetBackgroundAsync() => background.Value;
private AsyncLazy<Texture> background;
public bool BeatmapLoaded => beatmap.IsResultAvailable;
public IBeatmap Beatmap => beatmap.Value;
protected abstract IBeatmap GetBeatmap();
private readonly RecyclableLazy<IBeatmap> beatmap;
private Texture populateBackground() => GetBackground();
public bool BackgroundLoaded => background.IsResultAvailable;
public Texture Background => background.Value;
protected virtual bool BackgroundStillValid(Texture b) => b == null || !b.IsDisposed;
protected abstract Texture GetBackground();
private readonly RecyclableLazy<Texture> background;
public bool TrackLoaded => track.IsResultAvailable;
public Track Track => track.Value.Result;
public Task<Track> GetTrackAsync() => track.Value;
private AsyncLazy<Track> track;
private Track populateTrack()
{
// we want to ensure that we always have a track, even if it's a fake one.
var t = GetTrack() ?? new VirtualBeatmapTrack(Beatmap);
applyRateAdjustments(t);
return t;
}
public Track Track => track.Value;
protected abstract Track GetTrack();
private RecyclableLazy<Track> track;
public bool WaveformLoaded => waveform.IsResultAvailable;
public Waveform Waveform => waveform.Value.Result;
public Task<Waveform> GetWaveformAsync() => waveform.Value;
private readonly AsyncLazy<Waveform> waveform;
private Waveform populateWaveform() => GetWaveform();
public Waveform Waveform => waveform.Value;
protected virtual Waveform GetWaveform() => new Waveform();
private readonly RecyclableLazy<Waveform> waveform;
public bool StoryboardLoaded => storyboard.IsResultAvailable;
public Storyboard Storyboard => storyboard.Value.Result;
public Task<Storyboard> GetStoryboardAsync() => storyboard.Value;
private readonly AsyncLazy<Storyboard> storyboard;
private Storyboard populateStoryboard() => GetStoryboard();
public Storyboard Storyboard => storyboard.Value;
protected virtual Storyboard GetStoryboard() => new Storyboard { BeatmapInfo = BeatmapInfo };
private readonly RecyclableLazy<Storyboard> storyboard;
public bool SkinLoaded => skin.IsResultAvailable;
public Skin Skin => skin.Value.Result;
public Task<Skin> GetSkinAsync() => skin.Value;
private readonly AsyncLazy<Skin> skin;
public Skin Skin => skin.Value;
protected virtual Skin GetSkin() => new DefaultSkin();
private readonly RecyclableLazy<Skin> skin;
private Skin populateSkin() => GetSkin();
public void TransferTo(WorkingBeatmap other)
/// <summary>
/// Transfer pieces of a beatmap to a new one, where possible, to save on loading.
/// </summary>
/// <param name="other">The new beatmap which is being switched to.</param>
public virtual void TransferTo(WorkingBeatmap other)
{
if (track.IsResultAvailable && Track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo))
other.track = track;
if (background.IsResultAvailable && Background != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo))
other.background = background;
}
public virtual void Dispose()
{
if (BackgroundLoaded) Background?.Dispose();
if (WaveformLoaded) Waveform?.Dispose();
if (StoryboardLoaded) Storyboard?.Dispose();
if (SkinLoaded) Skin?.Dispose();
background.Recycle();
waveform.Recycle();
storyboard.Recycle();
skin.Recycle();
}
/// <summary>
@@ -210,15 +193,15 @@ namespace osu.Game.Beatmaps
mod.ApplyToClock(t);
}
public class AsyncLazy<T>
public class RecyclableLazy<T>
{
private Lazy<Task<T>> lazy;
private Lazy<T> lazy;
private readonly Func<T> valueFactory;
private readonly Func<T, bool> stillValidFunction;
private readonly object initLock = new object();
private readonly object fetchLock = new object();
public AsyncLazy(Func<T> valueFactory, Func<T, bool> stillValidFunction = null)
public RecyclableLazy(Func<T> valueFactory, Func<T, bool> stillValidFunction = null)
{
this.valueFactory = valueFactory;
this.stillValidFunction = stillValidFunction;
@@ -230,45 +213,28 @@ namespace osu.Game.Beatmaps
{
if (!IsResultAvailable) return;
(lazy.Value.Result as IDisposable)?.Dispose();
(lazy.Value as IDisposable)?.Dispose();
recreate();
}
public bool IsResultAvailable
public bool IsResultAvailable => stillValid;
public T Value
{
get
{
recreateIfInvalid();
return lazy.Value.IsCompleted;
lock (fetchLock)
{
if (!stillValid)
recreate();
return lazy.Value;
}
}
}
public Task<T> Value
{
get
{
recreateIfInvalid();
return lazy.Value;
}
}
private bool stillValid => lazy.IsValueCreated && (stillValidFunction?.Invoke(lazy.Value) ?? true);
private void recreateIfInvalid()
{
lock (initLock)
{
if (!lazy.IsValueCreated || !lazy.Value.IsCompleted)
// we have not yet been initialised or haven't run the task.
return;
if (stillValidFunction?.Invoke(lazy.Value.Result) ?? true)
// we are still in a valid state.
return;
recreate();
}
}
private void recreate() => lazy = new Lazy<Task<T>>(() => Task.Run(valueFactory));
private void recreate() => lazy = new Lazy<T>(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication);
}
}
}
+57 -5
View File
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using osu.Framework.IO.File;
@@ -129,7 +130,6 @@ namespace osu.Game.Database
List<TModel> imported = new List<TModel>();
int current = 0;
int errors = 0;
foreach (string path in paths)
{
if (notification.State == ProgressNotificationState.Cancelled)
@@ -162,12 +162,29 @@ namespace osu.Game.Database
{
e = e.InnerException ?? e;
Logger.Error(e, $@"Could not import ({Path.GetFileName(path)})");
errors++;
}
}
notification.Text = errors > 0 ? $"Import complete with {errors} errors" : "Import successful!";
notification.State = ProgressNotificationState.Completed;
if (imported.Count == 0)
{
notification.Text = "Import failed!";
notification.State = ProgressNotificationState.Cancelled;
}
else
{
notification.CompletionText = $"Imported {current} {typeof(TModel).Name.Replace("Info", "").ToLower()}s!";
notification.CompletionClickAction += () =>
{
if (imported.Count > 0)
PresentCompletedImport(imported);
return true;
};
notification.State = ProgressNotificationState.Completed;
}
}
protected virtual void PresentCompletedImport(IEnumerable<TModel> imported)
{
}
/// <summary>
@@ -283,7 +300,7 @@ namespace osu.Game.Database
var notification = new ProgressNotification
{
Progress = 0,
CompletionText = "Deleted all beatmaps!",
CompletionText = $"Deleted all {typeof(TModel).Name.Replace("Info", "").ToLower()}s!",
State = ProgressNotificationState.Active,
};
@@ -385,6 +402,41 @@ namespace osu.Game.Database
return fileInfos;
}
#region osu-stable import
/// <summary>
/// Set a storage with access to an osu-stable install for import purposes.
/// </summary>
public Func<Storage> GetStableStorage { private get; set; }
/// <summary>
/// Denotes whether an osu-stable installation is present to perform automated imports from.
/// </summary>
public bool StableInstallationAvailable => GetStableStorage?.Invoke() != null;
/// <summary>
/// The relative path from osu-stable's data directory to import items from.
/// </summary>
protected virtual string ImportFromStablePath => null;
/// <summary>
/// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future.
/// </summary>
public Task ImportFromStableAsync()
{
var stable = GetStableStorage?.Invoke();
if (stable == null)
{
Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error);
return Task.CompletedTask;
}
return Task.Factory.StartNew(() => Import(stable.GetDirectories(ImportFromStablePath).Select(f => stable.GetFullPath(f)).ToArray()), TaskCreationOptions.LongRunning);
}
#endregion
/// <summary>
/// Create a barebones model from the provided archive.
/// Actual expensive population should be done in <see cref="Populate"/>; this should just prepare for duplicate checking.
+3 -4
View File
@@ -1,13 +1,12 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using OpenTK.Graphics;
using osu.Game.Graphics.Textures;
namespace osu.Game.Graphics.Backgrounds
{
@@ -35,10 +34,10 @@ namespace osu.Game.Graphics.Backgrounds
}
[BackgroundDependencyLoader]
private async Task load(LargeTextureStore textures)
private void load(LargeTextureStore textures)
{
if (!string.IsNullOrEmpty(textureName))
Sprite.Texture = await textures.GetAsync(textureName);
Sprite.Texture = textures.Get(textureName);
}
}
}
+2 -2
View File
@@ -116,7 +116,7 @@ namespace osu.Game.Graphics.Backgrounds
float adjustedAlpha = HideAlphaDiscrepancies ?
// Cubically scale alpha to make it drop off more sharply.
(float)Math.Pow(DrawInfo.Colour.AverageColour.Linear.A, 3) :
(float)Math.Pow(DrawColourInfo.Colour.AverageColour.Linear.A, 3) :
1;
float elapsedSeconds = (float)Time.Elapsed / 1000;
@@ -235,7 +235,7 @@ namespace osu.Game.Graphics.Backgrounds
Vector2Extensions.Transform(particle.Position * Size + new Vector2(-offset.X, offset.Y), DrawInfo.Matrix)
);
ColourInfo colourInfo = DrawInfo.Colour;
ColourInfo colourInfo = DrawColourInfo.Colour;
colourInfo.ApplyChild(particle.Colour);
Texture.DrawTriangle(
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -38,15 +37,15 @@ namespace osu.Game.Graphics.Containers
}
[BackgroundDependencyLoader(true)]
private async Task load(OsuGame osuGame, AudioManager audio, PreviewTrackManager previewTrackManager)
private void load(OsuGame osuGame, AudioManager audio, PreviewTrackManager previewTrackManager)
{
this.previewTrackManager = previewTrackManager;
if (osuGame != null)
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
samplePopIn = await audio.Sample.GetAsync(@"UI/overlay-pop-in");
samplePopOut = await audio.Sample.GetAsync(@"UI/overlay-pop-out");
samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in");
samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out");
StateChanged += onStateChanged;
}
+3 -4
View File
@@ -10,7 +10,6 @@ using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Game.Configuration;
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input.EventArgs;
@@ -133,7 +132,7 @@ namespace osu.Game.Graphics.Cursor
}
[BackgroundDependencyLoader]
private async Task load(OsuConfigManager config, TextureStore textures, OsuColour colour)
private void load(OsuConfigManager config, TextureStore textures, OsuColour colour)
{
Children = new Drawable[]
{
@@ -144,14 +143,14 @@ namespace osu.Game.Graphics.Cursor
{
new Sprite
{
Texture = await textures.GetAsync(@"Cursor/menu-cursor"),
Texture = textures.Get(@"Cursor/menu-cursor"),
},
AdditiveLayer = new Sprite
{
Blending = BlendingMode.Additive,
Colour = colour.Pink,
Alpha = 0,
Texture = await textures.GetAsync(@"Cursor/menu-cursor-additive"),
Texture = textures.Get(@"Cursor/menu-cursor-additive"),
},
}
}
-2
View File
@@ -4,7 +4,6 @@
using System;
using Humanizer;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Game.Graphics.Sprites;
@@ -16,7 +15,6 @@ namespace osu.Game.Graphics
public DrawableDate(DateTimeOffset date)
{
AutoSizeAxes = Axes.Both;
Font = "Exo2.0-RegularItalic";
Date = date.ToLocalTime();
+2 -2
View File
@@ -42,7 +42,7 @@ namespace osu.Game.Graphics
private SampleChannel shutter;
[BackgroundDependencyLoader]
private async Task load(GameHost host, OsuConfigManager config, Storage storage, NotificationOverlay notificationOverlay, AudioManager audio)
private void load(GameHost host, OsuConfigManager config, Storage storage, NotificationOverlay notificationOverlay, AudioManager audio)
{
this.host = host;
this.storage = storage.GetStorageForDirectory(@"screenshots");
@@ -51,7 +51,7 @@ namespace osu.Game.Graphics
screenshotFormat = config.GetBindable<ScreenshotFormat>(OsuSetting.ScreenshotFormat);
captureMenuCursor = config.GetBindable<bool>(OsuSetting.ScreenshotCaptureMenuCursor);
shutter = await audio.Sample.GetAsync("UI/shutter");
shutter = audio.Sample.Get("UI/shutter");
}
public bool OnPressed(GlobalAction action)
+7 -8
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -25,7 +24,7 @@ namespace osu.Game.Graphics
private FontStore store;
[BackgroundDependencyLoader]
private async Task load(FontStore store)
private void load(FontStore store)
{
this.store = store;
@@ -56,23 +55,23 @@ namespace osu.Game.Graphics
},
};
await updateTexture();
updateTexture();
}
protected override void LoadComplete()
{
base.LoadComplete();
updateTexture().Wait();
updateTexture();
}
private FontAwesome loadedIcon;
private async Task updateTexture()
private void updateTexture()
{
var loadableIcon = icon;
if (loadableIcon == loadedIcon) return;
var texture = await store.GetAsync(((char)loadableIcon).ToString());
var texture = store.Get(((char)loadableIcon).ToString());
spriteMain.Texture = texture;
spriteShadow.Texture = texture;
@@ -96,7 +95,7 @@ namespace osu.Game.Graphics
{
//adjust shadow alpha based on highest component intensity to avoid muddy display of darker text.
//squared result for quadratic fall-off seems to give the best result.
var avgColour = (Color4)DrawInfo.Colour.AverageColour;
var avgColour = (Color4)DrawColourInfo.Colour.AverageColour;
spriteShadow.Alpha = (float)Math.Pow(Math.Max(Math.Max(avgColour.R, avgColour.G), avgColour.B), 2);
@@ -131,7 +130,7 @@ namespace osu.Game.Graphics
icon = value;
if (LoadState == LoadState.Loaded)
updateTexture().Wait();
updateTexture();
}
}
}
@@ -3,9 +3,6 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Transforms;
namespace osu.Game.Graphics.Sprites
@@ -19,27 +16,6 @@ namespace osu.Game.Graphics.Sprites
Shadow = true;
TextSize = FONT_SIZE;
}
protected override Drawable CreateFallbackCharacterDrawable()
{
var tex = GetTextureForCharacter('?').Result;
if (tex != null)
{
float adjust = (RNG.NextSingle() - 0.5f) * 2;
return new Sprite
{
Texture = tex,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Scale = new Vector2(1 + adjust * 0.2f),
Rotation = adjust * 15,
Colour = Color4.White,
};
}
return base.CreateFallbackCharacterDrawable();
}
}
public static class OsuSpriteTextTransformExtensions
@@ -1,18 +0,0 @@
// 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.Graphics.Textures;
using osu.Framework.IO.Stores;
namespace osu.Game.Graphics.Textures
{
/// <summary>
/// A texture store that bypasses atlasing.
/// </summary>
public class LargeTextureStore : TextureStore
{
public LargeTextureStore(IResourceStore<RawTexture> store = null) : base(store, false)
{
}
}
}
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -29,9 +28,9 @@ namespace osu.Game.Graphics.UserInterface
}
[BackgroundDependencyLoader]
private async Task load(AudioManager audio)
private void load(AudioManager audio)
{
sampleClick = await audio.Sample.GetAsync($@"UI/generic-select{SampleSet.GetDescription()}");
sampleClick = audio.Sample.Get($@"UI/generic-select{SampleSet.GetDescription()}");
}
}
}
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -36,9 +35,9 @@ namespace osu.Game.Graphics.UserInterface
}
[BackgroundDependencyLoader]
private async Task load(AudioManager audio)
private void load(AudioManager audio)
{
sampleHover = await audio.Sample.GetAsync($@"UI/generic-hover{SampleSet.GetDescription()}");
sampleHover = audio.Sample.Get($@"UI/generic-hover{SampleSet.GetDescription()}");
}
}
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -111,10 +110,10 @@ namespace osu.Game.Graphics.UserInterface
}
[BackgroundDependencyLoader]
private async Task load(AudioManager audio)
private void load(AudioManager audio)
{
sampleChecked = await audio.Sample.GetAsync(@"UI/check-on");
sampleUnchecked = await audio.Sample.GetAsync(@"UI/check-off");
sampleChecked = audio.Sample.Get(@"UI/check-on");
sampleUnchecked = audio.Sample.Get(@"UI/check-off");
}
}
}
+3 -4
View File
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -70,10 +69,10 @@ namespace osu.Game.Graphics.UserInterface
}
[BackgroundDependencyLoader]
private async Task load(AudioManager audio)
private void load(AudioManager audio)
{
sampleHover = await audio.Sample.GetAsync(@"UI/generic-hover");
sampleClick = await audio.Sample.GetAsync(@"UI/generic-select");
sampleHover = audio.Sample.Get(@"UI/generic-hover");
sampleClick = audio.Sample.Get(@"UI/generic-select");
BackgroundColour = Color4.Transparent;
BackgroundColourHover = OsuColour.FromHex(@"172023");
@@ -3,7 +3,6 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
@@ -120,9 +119,9 @@ namespace osu.Game.Graphics.UserInterface
}
[BackgroundDependencyLoader]
private async Task load(AudioManager audio, OsuColour colours)
private void load(AudioManager audio, OsuColour colours)
{
sample = await audio.Sample.GetAsync(@"UI/sliderbar-notch");
sample = audio.Sample.Get(@"UI/sliderbar-notch");
AccentColour = colours.Pink;
}
+37 -26
View File
@@ -2,12 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Logging;
@@ -26,7 +24,7 @@ namespace osu.Game.Online.API
private const string client_id = @"5";
private const string client_secret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk";
private ConcurrentQueue<APIRequest> queue = new ConcurrentQueue<APIRequest>();
private readonly Queue<APIRequest> queue = new Queue<APIRequest>();
/// <summary>
/// The username/email provided by the user when initiating a login.
@@ -55,7 +53,13 @@ namespace osu.Game.Online.API
authentication.TokenString = config.Get<string>(OsuSetting.Token);
authentication.Token.ValueChanged += onTokenChanged;
Task.Factory.StartNew(run, cancellationToken.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
var thread = new Thread(run)
{
Name = "APIAccess",
IsBackground = true
};
thread.Start();
}
private void onTokenChanged(OAuthToken token) => config.Set(OsuSetting.Token, config.Get<bool>(OsuSetting.SavePassword) ? authentication.TokenString : string.Empty);
@@ -75,10 +79,7 @@ namespace osu.Game.Online.API
public void Unregister(IOnlineComponent component)
{
Scheduler.Add(delegate
{
components.Remove(component);
});
Scheduler.Add(delegate { components.Remove(component); });
}
public string AccessToken => authentication.RequestAccessToken();
@@ -103,6 +104,7 @@ namespace osu.Game.Online.API
log.Add(@"Queueing a ping request");
Queue(new ListChannelsRequest { Timeout = 5000 });
}
break;
case APIState.Offline:
case APIState.Connecting:
@@ -161,18 +163,21 @@ namespace osu.Game.Online.API
continue;
}
//process the request queue.
APIRequest req;
while (queue.TryPeek(out req))
while (true)
{
if (handleRequest(req))
APIRequest req;
lock (queue)
{
//we have succeeded, so let's unqueue.
queue.TryDequeue(out req);
if (queue.Count == 0) break;
req = queue.Dequeue();
}
// TODO: handle failures better
handleRequest(req);
}
Thread.Sleep(1);
Thread.Sleep(50);
}
}
@@ -205,7 +210,8 @@ namespace osu.Game.Online.API
}
catch (WebException we)
{
HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode ?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout);
HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode
?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout);
// special cases for un-typed but useful message responses.
switch (we.Message)
@@ -247,6 +253,7 @@ namespace osu.Game.Online.API
}
private APIState state;
public APIState State
{
get { return state; }
@@ -271,7 +278,10 @@ namespace osu.Game.Online.API
public bool IsLoggedIn => LocalUser.Value.Id > 1;
public void Queue(APIRequest request) => queue.Enqueue(request);
public void Queue(APIRequest request)
{
lock (queue) queue.Enqueue(request);
}
public event StateChangeDelegate OnStateChange;
@@ -279,16 +289,17 @@ namespace osu.Game.Online.API
private void flushQueue(bool failOldRequests = true)
{
var oldQueue = queue;
//flush the queue.
queue = new ConcurrentQueue<APIRequest>();
if (failOldRequests)
lock (queue)
{
APIRequest req;
while (oldQueue.TryDequeue(out req))
req.Fail(new WebException(@"Disconnected from server"));
var oldQueueRequests = queue.ToArray();
queue.Clear();
if (failOldRequests)
{
foreach (var req in oldQueueRequests)
req.Fail(new WebException(@"Disconnected from server"));
}
}
}
+18 -16
View File
@@ -75,10 +75,10 @@ namespace osu.Game
{
get
{
Screen s = screenStack;
while (s != null && !(s is Intro))
s = s.ChildScreen;
return s as Intro;
Screen screen = screenStack;
while (screen != null && !(screen is Intro))
screen = screen.ChildScreen;
return screen as Intro;
}
}
@@ -126,8 +126,8 @@ namespace osu.Game
/// <param name="toolbar">Whether the toolbar should also be hidden.</param>
public void CloseAllOverlays(bool toolbar = true)
{
foreach (var o in overlays)
o.State = Visibility.Hidden;
foreach (var overlay in overlays)
overlay.State = Visibility.Hidden;
if (toolbar) Toolbar.State = Visibility.Hidden;
}
@@ -244,7 +244,7 @@ namespace osu.Game
/// <param name="beatmapId">The beatmap to show.</param>
public void ShowBeatmap(int beatmapId) => beatmapSetOverlay.FetchAndShowBeatmap(beatmapId);
protected void LoadScore(Score s)
protected void LoadScore(Score score)
{
scoreLoad?.Cancel();
@@ -252,18 +252,18 @@ namespace osu.Game
if (menu == null)
{
scoreLoad = Schedule(() => LoadScore(s));
scoreLoad = Schedule(() => LoadScore(score));
return;
}
if (!menu.IsCurrentScreen)
{
menu.MakeCurrent();
this.Delay(500).Schedule(() => LoadScore(s), out scoreLoad);
this.Delay(500).Schedule(() => LoadScore(score), out scoreLoad);
return;
}
if (s.Beatmap == null)
if (score.Beatmap == null)
{
notifications.Post(new SimpleNotification
{
@@ -273,12 +273,12 @@ namespace osu.Game
return;
}
ruleset.Value = s.Ruleset;
ruleset.Value = score.Ruleset;
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(s.Beatmap);
Beatmap.Value.Mods.Value = s.Mods;
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(score.Beatmap);
Beatmap.Value.Mods.Value = score.Mods;
menu.Push(new PlayerLoader(new ReplayPlayer(s.Replay)));
menu.Push(new PlayerLoader(new ReplayPlayer(score.Replay)));
}
protected override void Dispose(bool isDisposing)
@@ -299,11 +299,13 @@ namespace osu.Game
// This prevents the cursor from showing until we have a screen with CursorVisible = true
MenuCursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;
// hook up notifications to components.
// todo: all archive managers should be able to be looped here.
SkinManager.PostNotification = n => notifications?.Post(n);
BeatmapManager.PostNotification = n => notifications?.Post(n);
SkinManager.GetStableStorage = GetStorageForStableInstall;
BeatmapManager.PostNotification = n => notifications?.Post(n);
BeatmapManager.GetStableStorage = GetStorageForStableInstall;
BeatmapManager.PresentBeatmap = PresentBeatmap;
AddRange(new Drawable[]
+29 -29
View File
@@ -24,7 +24,6 @@ using osu.Framework.Input;
using osu.Framework.Logging;
using osu.Game.Audio;
using osu.Game.Database;
using osu.Game.Graphics.Textures;
using osu.Game.Input;
using osu.Game.Input.Bindings;
using osu.Game.IO;
@@ -109,11 +108,39 @@ namespace osu.Game
dependencies.Cache(contextFactory = new DatabaseContextFactory(Host.Storage));
dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures"))));
var largeStore = new LargeTextureStore(new TextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures")));
largeStore.AddStore(new TextureLoaderStore(new OnlineStore()));
dependencies.Cache(largeStore);
dependencies.CacheAs(this);
dependencies.Cache(LocalConfig);
//this completely overrides the framework default. will need to change once we make a proper FontStore.
dependencies.Cache(Fonts = new FontStore(new GlyphStore(Resources, @"Fonts/FontAwesome")));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/osuFont"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Medium"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-MediumItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Noto-Basic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Noto-Hangul"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Noto-CJK-Basic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Noto-CJK-Compatibility"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Regular"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-RegularItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-SemiBold"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-SemiBoldItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Bold"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-BoldItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Light"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-LightItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Black"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-BlackItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light"));
runMigrations();
dependencies.Cache(SkinManager = new SkinManager(Host.Storage, contextFactory, Host, Audio));
@@ -137,33 +164,6 @@ namespace osu.Game
fileImporters.Add(ScoreStore);
fileImporters.Add(SkinManager);
//this completely overrides the framework default. will need to change once we make a proper FontStore.
dependencies.Cache(Fonts = new FontStore { ScaleAdjust = 100 });
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/FontAwesome"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/osuFont"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Medium"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-MediumItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Noto-Basic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Noto-Hangul"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Noto-CJK-Basic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Noto-CJK-Compatibility"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Regular"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-RegularItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-SemiBold"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-SemiBoldItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Bold"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-BoldItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Light"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-LightItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Black"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-BlackItalic"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light"));
var defaultBeatmap = new DummyWorkingBeatmap(this);
beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio);
BeatmapManager.DefaultBeatmap = defaultBeatmap;
@@ -62,7 +62,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
loading = true;
getScoresRequest = new GetScoresRequest(beatmap, beatmap.Ruleset);
getScoresRequest.Success += r => Scores = r.Scores;
getScoresRequest.Success += r => Schedule(() => Scores = r.Scores);
api.Queue(getScoresRequest);
}
}
@@ -134,5 +134,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
this.api = api;
updateDisplay();
}
protected override void Dispose(bool isDisposing)
{
getScoresRequest?.Cancel();
}
}
}
+1 -3
View File
@@ -104,8 +104,6 @@ namespace osu.Game.Overlays.Direct
beatmaps.ItemAdded += setAdded;
}
public override bool DisposeOnDeathRemoval => true;
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
@@ -187,7 +185,7 @@ namespace osu.Game.Overlays.Direct
base.LoadComplete();
this.FadeInFromZero(200, Easing.Out);
PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint);
PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered || !FadePlayButton ? 1 : 0, 120, Easing.InOutQuint);
PreviewPlaying.ValueChanged += newValue => PreviewBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint);
}
+3 -4
View File
@@ -20,7 +20,6 @@ using OpenTK.Input;
using osu.Framework.Graphics.Shapes;
using System;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Input.States;
using osu.Framework.MathUtils;
@@ -144,10 +143,10 @@ namespace osu.Game.Overlays
}
[BackgroundDependencyLoader]
private async Task load(OsuColour colours, TextureStore textures, AudioManager audio)
private void load(OsuColour colours, TextureStore textures, AudioManager audio)
{
getSample = await audio.Sample.GetAsync(@"MedalSplash/medal-get");
innerSpin.Texture = outerSpin.Texture = await textures.GetAsync(@"MedalSplash/disc-spin");
getSample = audio.Sample.Get(@"MedalSplash/medal-get");
innerSpin.Texture = outerSpin.Texture = textures.Get(@"MedalSplash/disc-spin");
disc.EdgeEffect = leftStrip.EdgeEffect = rightStrip.EdgeEffect = new EdgeEffectParameters
{
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework;
using OpenTK;
using osu.Framework.Allocation;
@@ -119,10 +118,10 @@ namespace osu.Game.Overlays.MedalSplash
}
[BackgroundDependencyLoader]
private async Task load(OsuColour colours, TextureStore textures)
private void load(OsuColour colours, TextureStore textures, LargeTextureStore largeTextures)
{
medalSprite.Texture = await textures.GetAsync(medal.ImageUrl);
medalGlow.Texture = await textures.GetAsync(@"MedalSplash/medal-glow");
medalSprite.Texture = largeTextures.Get(medal.ImageUrl);
medalGlow.Texture = textures.Get(@"MedalSplash/medal-glow");
description.Colour = colours.BlueLight;
}
+3 -4
View File
@@ -15,7 +15,6 @@ using osu.Game.Rulesets.Mods;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics.Shapes;
@@ -50,7 +49,7 @@ namespace osu.Game.Overlays.Mods
protected readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
[BackgroundDependencyLoader(true)]
private async Task load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IEnumerable<Mod>> selectedMods)
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IEnumerable<Mod>> selectedMods)
{
LowMultiplierColour = colours.Red;
HighMultiplierColour = colours.Green;
@@ -59,8 +58,8 @@ namespace osu.Game.Overlays.Mods
Ruleset.BindTo(ruleset);
if (selectedMods != null) SelectedMods.BindTo(selectedMods);
sampleOn = await audio.Sample.GetAsync(@"UI/check-on");
sampleOff = await audio.Sample.GetAsync(@"UI/check-off");
sampleOn = audio.Sample.Get(@"UI/check-on");
sampleOff = audio.Sample.Get(@"UI/check-off");
}
protected override void LoadComplete()
+2 -2
View File
@@ -454,9 +454,9 @@ namespace osu.Game.Overlays
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
sprite.Texture = beatmap?.Background ?? await textures.GetAsync(@"Backgrounds/bg4");
sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4");
}
}
@@ -169,7 +169,7 @@ namespace osu.Game.Overlays.Notifications
public Action<Notification> CompletionTarget { get; set; }
/// <summary>
/// An action to complete when the completion notification is clicked.
/// An action to complete when the completion notification is clicked. Return true to close.
/// </summary>
public Func<bool> CompletionClickAction;
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -43,9 +42,9 @@ namespace osu.Game.Overlays.Profile.Components
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
badge.Texture = await textures.GetAsync($"Grades/{grade}");
badge.Texture = textures.Get($"Grades/{grade}");
}
}
}
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -177,13 +176,13 @@ namespace osu.Game.Overlays.Profile.Header
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(LargeTextureStore textures)
{
Child = new Sprite
{
FillMode = FillMode.Fit,
RelativeSizeAxes = Axes.Both,
Texture = await textures.GetAsync(badge.ImageUrl),
Texture = textures.Get(badge.ImageUrl),
};
}
+2 -3
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
@@ -312,9 +311,9 @@ namespace osu.Game.Overlays.Profile
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
levelBadge.Texture = await textures.GetAsync(@"Profile/levelbadge");
levelBadge.Texture = textures.Get(@"Profile/levelbadge");
}
private User user;
@@ -14,8 +14,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps
public class PaginatedBeatmapContainer : PaginatedContainer
{
private const float panel_padding = 10f;
private readonly BeatmapSetType type;
private GetUserBeatmapsRequest request;
public PaginatedBeatmapContainer(BeatmapSetType type, Bindable<User> user, string header, string missing = "None... yet.")
: base(user, header, missing)
@@ -31,9 +31,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps
{
base.ShowMore();
var req = new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++ * ItemsPerPage);
req.Success += sets =>
request = new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++ * ItemsPerPage);
request.Success += sets => Schedule(() =>
{
ShowMoreButton.FadeTo(sets.Count == ItemsPerPage ? 1 : 0);
ShowMoreLoading.Hide();
@@ -52,9 +51,15 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps
var panel = new DirectGridPanel(s.ToBeatmapSet(Rulesets));
ItemsContainer.Add(panel);
}
};
});
Api.Queue(req);
Api.Queue(request);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
request?.Cancel();
}
}
}
@@ -12,6 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
{
public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer
{
private GetUserMostPlayedBeatmapsRequest request;
public PaginatedMostPlayedBeatmapContainer(Bindable<User> user)
:base(user, "Most Played Beatmaps", "No records. :(")
{
@@ -24,9 +26,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
{
base.ShowMore();
var req = new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++ * ItemsPerPage);
req.Success += beatmaps =>
request = new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++ * ItemsPerPage);
request.Success += beatmaps => Schedule(() =>
{
ShowMoreButton.FadeTo(beatmaps.Count == ItemsPerPage ? 1 : 0);
ShowMoreLoading.Hide();
@@ -43,9 +44,16 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
{
ItemsContainer.Add(new DrawableMostPlayedRow(beatmap.GetBeatmapInfo(Rulesets), beatmap.PlayCount));
}
};
});
Api.Queue(req);
Api.Queue(request);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
request?.Cancel();
}
}
}
@@ -28,6 +28,7 @@ namespace osu.Game.Overlays.Profile.Sections
protected readonly Bindable<User> User = new Bindable<User>();
protected APIAccess Api;
protected APIRequest RetrievalRequest;
protected RulesetStore Rulesets;
public PaginatedContainer(Bindable<User> user, string header, string missing)
@@ -16,6 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
{
private readonly bool includeWeight;
private readonly ScoreType type;
private GetUserScoresRequest request;
public PaginatedScoreContainer(ScoreType type, Bindable<User> user, string header, string missing, bool includeWeight = false)
: base(user, header, missing)
@@ -32,9 +33,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
{
base.ShowMore();
var req = new GetUserScoresRequest(User.Value.Id, type, VisiblePages++ * ItemsPerPage);
req.Success += scores =>
request = new GetUserScoresRequest(User.Value.Id, type, VisiblePages++ * ItemsPerPage);
request.Success += scores => Schedule(() =>
{
foreach (var s in scores)
s.ApplyRuleset(Rulesets.GetRuleset(s.OnlineRulesetID));
@@ -66,9 +66,15 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
ItemsContainer.Add(drawableScore);
}
};
});
Api.Queue(req);
Api.Queue(request);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
request?.Cancel();
}
}
}
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
@@ -31,9 +30,9 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(LargeTextureStore textures)
{
sprite.Texture = await textures.GetAsync(url);
sprite.Texture = textures.Get(url);
}
}
}
@@ -12,6 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
{
public class PaginatedRecentActivityContainer : PaginatedContainer
{
private GetUserRecentActivitiesRequest request;
public PaginatedRecentActivityContainer(Bindable<User> user, string header, string missing)
: base(user, header, missing)
{
@@ -22,9 +24,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
{
base.ShowMore();
var req = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++ * ItemsPerPage);
req.Success += activities =>
request = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++ * ItemsPerPage);
request.Success += activities => Schedule(() =>
{
ShowMoreButton.FadeTo(activities.Count == ItemsPerPage ? 1 : 0);
ShowMoreLoading.Hide();
@@ -41,9 +42,15 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
{
ItemsContainer.Add(new DrawableRecentActivity(activity));
}
};
});
Api.Queue(req);
Api.Queue(request);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
request?.Cancel();
}
}
}
@@ -1,8 +1,12 @@
// 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.Collections.Generic;
using System.Drawing;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -15,21 +19,36 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
private FillFlowContainer letterboxSettings;
private Bindable<bool> letterboxing;
private Bindable<Size> sizeFullscreen;
private OsuGameBase game;
private SettingsDropdown<Size> resolutionDropdown;
private SettingsEnumDropdown<WindowMode> windowModeDropdown;
private const int transition_duration = 400;
[BackgroundDependencyLoader]
private void load(FrameworkConfigManager config)
private void load(FrameworkConfigManager config, OsuGameBase game)
{
this.game = game;
letterboxing = config.GetBindable<bool>(FrameworkSetting.Letterboxing);
sizeFullscreen = config.GetBindable<Size>(FrameworkSetting.SizeFullscreen);
Children = new Drawable[]
{
new SettingsEnumDropdown<WindowMode>
windowModeDropdown = new SettingsEnumDropdown<WindowMode>
{
LabelText = "Screen mode",
Bindable = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode),
},
resolutionDropdown = new SettingsDropdown<Size>
{
LabelText = "Resolution",
ShowsDefaultIndicator = false,
Items = getResolutions(),
Bindable = sizeFullscreen
},
new SettingsCheckbox
{
LabelText = "Letterboxing",
@@ -62,15 +81,39 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
},
};
letterboxing.ValueChanged += isVisible =>
windowModeDropdown.Bindable.BindValueChanged(windowMode =>
{
if (windowMode == WindowMode.Fullscreen)
{
resolutionDropdown.Show();
sizeFullscreen.TriggerChange();
}
else
resolutionDropdown.Hide();
}, true);
letterboxing.BindValueChanged(isVisible =>
{
letterboxSettings.ClearTransforms();
letterboxSettings.AutoSizeAxes = isVisible ? Axes.Y : Axes.None;
if (!isVisible)
letterboxSettings.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
};
letterboxing.TriggerChange();
}, true);
}
private IEnumerable<KeyValuePair<string, Size>> getResolutions()
{
var resolutions = new KeyValuePair<string, Size>("Default", new Size(9999, 9999)).Yield();
if (game.Window != null)
resolutions = resolutions.Concat(game.Window.AvailableResolutions
.Where(r => r.Width >= 800 && r.Height >= 600)
.OrderByDescending(r => r.Width)
.ThenByDescending(r => r.Height)
.Select(res => new KeyValuePair<string, Size>($"{res.Width}x{res.Height}", new Size(res.Width, res.Height)))
.Distinct()).ToList();
return resolutions;
}
}
}
@@ -7,6 +7,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
using osu.Game.Skinning;
namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
@@ -20,7 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
protected override string Header => "General";
[BackgroundDependencyLoader]
private void load(BeatmapManager beatmaps, DialogOverlay dialogOverlay)
private void load(BeatmapManager beatmaps, SkinManager skins, DialogOverlay dialogOverlay)
{
Children = new Drawable[]
{
@@ -30,7 +31,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Action = () =>
{
importButton.Enabled.Value = false;
beatmaps.ImportFromStable().ContinueWith(t => Schedule(() => importButton.Enabled.Value = true));
beatmaps.ImportFromStableAsync().ContinueWith(t => Schedule(() => importButton.Enabled.Value = true));
}
},
deleteButton = new DangerousSettingsButton
@@ -45,6 +46,27 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
}));
}
},
importButton = new SettingsButton
{
Text = "Import skins from stable",
Action = () =>
{
importButton.Enabled.Value = false;
skins.ImportFromStableAsync().ContinueWith(t => Schedule(() => importButton.Enabled.Value = true));
}
},
deleteButton = new DangerousSettingsButton
{
Text = "Delete ALL skins",
Action = () =>
{
dialogOverlay?.Push(new DeleteAllBeatmapsDialog(() =>
{
deleteButton.Enabled.Value = false;
Task.Run(() => skins.Delete(skins.GetAllUserSkins())).ContinueWith(t => Schedule(() => deleteButton.Enabled.Value = true));
}));
}
},
restoreButton = new SettingsButton
{
Text = "Restore all hidden difficulties",
@@ -51,10 +51,10 @@ namespace osu.Game.Overlays.Settings.Sections
},
};
skins.ItemAdded += onItemsChanged;
skins.ItemRemoved += onItemsChanged;
skins.ItemAdded += itemAdded;
skins.ItemRemoved += itemRemoved;
reloadSkins();
skinDropdown.Items = skins.GetAllUsableSkins().Select(s => new KeyValuePair<string, int>(s.ToString(), s.ID));
var skinBindable = config.GetBindable<int>(OsuSetting.Skin);
@@ -65,9 +65,8 @@ namespace osu.Game.Overlays.Settings.Sections
skinDropdown.Bindable = skinBindable;
}
private void reloadSkins() => skinDropdown.Items = skins.GetAllUsableSkins().Select(s => new KeyValuePair<string, int>(s.ToString(), s.ID));
private void onItemsChanged(SkinInfo _) => Schedule(reloadSkins);
private void itemRemoved(SkinInfo s) => skinDropdown.Items = skinDropdown.Items.Where(i => i.Value != s.ID);
private void itemAdded(SkinInfo s) => skinDropdown.Items = skinDropdown.Items.Append(new KeyValuePair<string, int>(s.ToString(), s.ID));
protected override void Dispose(bool isDisposing)
{
@@ -75,8 +74,8 @@ namespace osu.Game.Overlays.Settings.Sections
if (skins != null)
{
skins.ItemAdded -= onItemsChanged;
skins.ItemRemoved -= onItemsChanged;
skins.ItemAdded -= itemAdded;
skins.ItemRemoved -= itemRemoved;
}
}
@@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Settings
},
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new[]
Children = new Drawable[]
{
new OsuSpriteText
{
+3 -3
View File
@@ -83,14 +83,14 @@ namespace osu.Game.Overlays.Toolbar
[BackgroundDependencyLoader(true)]
private void load(OsuGame osuGame)
{
if (osuGame != null)
overlayActivationMode.BindTo(osuGame.OverlayActivationMode);
StateChanged += visibility =>
{
if (overlayActivationMode == OverlayActivation.Disabled)
State = Visibility.Hidden;
};
if (osuGame != null)
overlayActivationMode.BindTo(osuGame.OverlayActivationMode);
}
public class ToolbarBackground : Container
+7 -8
View File
@@ -73,16 +73,15 @@ namespace osu.Game.Overlays
FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out);
}
public void ShowUser(long userId)
{
if (userId == Header.User.Id)
return;
ShowUser(new User { Id = userId });
}
public void ShowUser(long userId) => ShowUser(new User { Id = userId });
public void ShowUser(User user, bool fetchOnline = true)
{
Show();
if (user.Id == Header?.User.Id)
return;
userReq?.Cancel();
Clear();
lastSection = null;
@@ -97,6 +96,7 @@ namespace osu.Game.Overlays
new BeatmapsSection(),
new KudosuSection()
};
tabs = new ProfileTabControl
{
RelativeSizeAxes = Axes.X,
@@ -161,7 +161,6 @@ namespace osu.Game.Overlays
userLoadComplete(user);
}
Show();
sectionsContainer.ScrollToTop();
}
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Textures;
@@ -76,9 +75,9 @@ namespace osu.Game.Screens.Backgrounds
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
Sprite.Texture = beatmap?.Background ?? await textures.GetAsync(@"Backgrounds/bg1");
Sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg1");
}
}
}
+3 -4
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@@ -180,11 +179,11 @@ namespace osu.Game.Screens.Menu
}
[BackgroundDependencyLoader]
private async Task load(AudioManager audio)
private void load(AudioManager audio)
{
sampleHover = await audio.Sample.GetAsync(@"Menu/button-hover");
sampleHover = audio.Sample.Get(@"Menu/button-hover");
if (!string.IsNullOrEmpty(sampleName))
sampleClick = await audio.Sample.GetAsync($@"Menu/{sampleName}");
sampleClick = audio.Sample.Get($@"Menu/{sampleName}");
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
+2 -3
View File
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@@ -103,10 +102,10 @@ namespace osu.Game.Screens.Menu
private OsuGame game;
[BackgroundDependencyLoader(true)]
private async Task load(AudioManager audio, OsuGame game)
private void load(AudioManager audio, OsuGame game)
{
this.game = game;
sampleBack = await audio.Sample.GetAsync(@"Menu/button-back-select");
sampleBack = audio.Sample.Get(@"Menu/button-back-select");
}
public bool OnPressed(GlobalAction action)
+3 -4
View File
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -48,7 +47,7 @@ namespace osu.Game.Screens.Menu
private WorkingBeatmap introBeatmap;
[BackgroundDependencyLoader]
private async Task load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, BindableBeatmap beatmap)
private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, BindableBeatmap beatmap)
{
this.beatmap.BindTo(beatmap);
@@ -81,8 +80,8 @@ namespace osu.Game.Screens.Menu
introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
track = introBeatmap.Track;
welcome = await audio.Sample.GetAsync(@"welcome");
seeya = await audio.Sample.GetAsync(@"seeya");
welcome = audio.Sample.Get(@"welcome");
seeya = audio.Sample.Get(@"seeya");
}
private const double delay_step_one = 2300;
+1 -1
View File
@@ -176,7 +176,7 @@ namespace osu.Game.Screens.Menu
Vector2 inflation = DrawInfo.MatrixInverse.ExtractScale().Xy;
ColourInfo colourInfo = DrawInfo.Colour;
ColourInfo colourInfo = DrawColourInfo.Colour;
colourInfo.ApplyChild(Colour);
if (AudioData != null)
+5 -6
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -254,13 +253,13 @@ namespace osu.Game.Screens.Menu
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures, AudioManager audio)
private void load(TextureStore textures, AudioManager audio)
{
sampleClick = await audio.Sample.GetAsync(@"Menu/osu-logo-select");
sampleBeat = await audio.Sample.GetAsync(@"Menu/osu-logo-heartbeat");
sampleClick = audio.Sample.Get(@"Menu/osu-logo-select");
sampleBeat = audio.Sample.Get(@"Menu/osu-logo-heartbeat");
logo.Texture = await textures.GetAsync(@"Menu/logo");
ripple.Texture = await textures.GetAsync(@"Menu/logo");
logo.Texture = textures.Get(@"Menu/logo");
ripple.Texture = textures.Get(@"Menu/logo");
}
private int lastBeatIndex;
+2 -3
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Internal;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@@ -81,7 +80,7 @@ namespace osu.Game.Screens
private SampleChannel sampleExit;
[BackgroundDependencyLoader(true)]
private async Task load(BindableBeatmap beatmap, OsuGame osu, AudioManager audio, Bindable<RulesetInfo> ruleset)
private void load(BindableBeatmap beatmap, OsuGame osu, AudioManager audio, Bindable<RulesetInfo> ruleset)
{
Beatmap.BindTo(beatmap);
Ruleset.BindTo(ruleset);
@@ -99,7 +98,7 @@ namespace osu.Game.Screens
};
}
sampleExit = await audio.Sample.GetAsync(@"UI/screen-back");
sampleExit = audio.Sample.Get(@"UI/screen-back");
}
public virtual bool OnPressed(GlobalAction action)
+3 -4
View File
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -62,19 +61,19 @@ namespace osu.Game.Screens.Play
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
Children = new Drawable[]
{
buttonSprite = new Sprite
{
Texture = await textures.GetAsync(@"KeyCounter/key-up"),
Texture = textures.Get(@"KeyCounter/key-up"),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
glowSprite = new Sprite
{
Texture = await textures.GetAsync(@"KeyCounter/key-glow"),
Texture = textures.Get(@"KeyCounter/key-glow"),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0
+2 -2
View File
@@ -84,7 +84,7 @@ namespace osu.Game.Screens.Play
public bool LoadedBeatmapSuccessfully => RulesetContainer?.Objects.Any() == true;
[BackgroundDependencyLoader]
private async Task load(AudioManager audio, APIAccess api, OsuConfigManager config)
private void load(AudioManager audio, APIAccess api, OsuConfigManager config)
{
this.api = api;
@@ -92,7 +92,7 @@ namespace osu.Game.Screens.Play
if (working is DummyWorkingBeatmap)
return;
sampleRestart = await audio.Sample.GetAsync(@"Gameplay/restart");
sampleRestart = audio.Sample.Get(@"Gameplay/restart");
mouseWheelDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableWheel);
userAudioOffset = config.GetBindable<double>(OsuSetting.AudioOffset);
+2 -3
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@@ -225,12 +224,12 @@ namespace osu.Game.Screens.Play
}
[BackgroundDependencyLoader]
private async Task load(OsuColour colours, AudioManager audio)
private void load(OsuColour colours, AudioManager audio)
{
colourNormal = colours.Yellow;
colourHover = colours.YellowDark;
sampleConfirm = await audio.Sample.GetAsync(@"SongSelect/confirm-selection");
sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection");
Children = new Drawable[]
{
+13 -6
View File
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
@@ -30,6 +29,7 @@ namespace osu.Game.Screens.Ranking
{
public class ResultsPageScore : ResultsPage
{
private Container scoreContainer;
private ScoreCounter scoreCounter;
public ResultsPageScore(Score score, WorkingBeatmap beatmap) : base(score, beatmap) { }
@@ -77,7 +77,7 @@ namespace osu.Game.Screens.Ranking
Size = new Vector2(150, 60),
Margin = new MarginPadding(20),
},
new Container
scoreContainer = new Container
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
@@ -93,8 +93,8 @@ namespace osu.Game.Screens.Ranking
},
scoreCounter = new SlowScoreCounter(6)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = colours.PinkDarker,
Y = 10,
TextSize = 56,
@@ -186,6 +186,13 @@ namespace osu.Game.Screens.Ranking
});
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
scoreCounter.Scale = new Vector2(Math.Min(1f, (scoreContainer.DrawWidth - 20) / scoreCounter.DrawWidth));
}
private class DrawableScoreStatistic : Container
{
private readonly KeyValuePair<HitResult, object> statistic;
@@ -369,10 +376,10 @@ namespace osu.Game.Screens.Ranking
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(LargeTextureStore textures)
{
if (!string.IsNullOrEmpty(user.CoverUrl))
cover.Texture = await textures.GetAsync(user.CoverUrl);
cover.Texture = textures.Get(user.CoverUrl);
}
}
@@ -486,6 +486,15 @@ namespace osu.Game.Screens.Select
updateItem(p, halfHeight);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
// aggressively dispose "off-screen" items to reduce GC pressure.
foreach (var i in Items)
i.Dispose();
}
private CarouselBeatmapSet createCarouselSet(BeatmapSetInfo beatmapSet)
{
if (beatmapSet.Beatmaps.All(b => b.Hidden))
@@ -50,12 +50,12 @@ namespace osu.Game.Screens.Select.Carousel
Children = new Drawable[]
{
new DelayedLoadWrapper(
new DelayedLoadUnloadWrapper(() =>
new PanelBackground(manager.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()))
{
RelativeSizeAxes = Axes.Both,
OnLoadComplete = d => d.FadeInFromZero(1000, Easing.OutQuint),
}, 300
}, 300, 5000
),
new FillFlowContainer
{
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -46,7 +45,7 @@ namespace osu.Game.Screens.Select.Carousel
private SampleChannel sampleHover;
[BackgroundDependencyLoader]
private async Task load(AudioManager audio, OsuColour colours)
private void load(AudioManager audio, OsuColour colours)
{
InternalChild = borderContainer = new Container
{
@@ -69,7 +68,7 @@ namespace osu.Game.Screens.Select.Carousel
}
};
sampleHover = await audio.Sample.GetAsync($@"SongSelect/song-ping-variation-{RNG.Next(1, 5)}");
sampleHover = audio.Sample.Get($@"SongSelect/song-ping-variation-{RNG.Next(1, 5)}");
hoverLayer.Colour = colours.Blue.Opacity(0.1f);
}
@@ -12,7 +12,7 @@ namespace osu.Game.Screens.Select
public ImportFromStablePopup(Action importFromStable)
{
HeaderText = @"You have no beatmaps!";
BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps?";
BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps (and skins)?";
Icon = FontAwesome.fa_plane;
@@ -1,7 +1,6 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -36,20 +35,23 @@ namespace osu.Game.Screens.Select.Leaderboards
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
this.textures = textures;
await updateTexture();
updateTexture();
}
private async Task updateTexture() => rankSprite.Texture = await textures.GetAsync($@"Grades/{Rank.GetDescription()}");
private void updateTexture()
{
rankSprite.Texture = textures.Get($@"Grades/{Rank.GetDescription()}");
}
public void UpdateRank(ScoreRank newRank)
{
Rank = newRank;
if (LoadState >= LoadState.Ready)
updateTexture().Wait();
updateTexture();
}
}
}
+7 -4
View File
@@ -3,7 +3,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@@ -20,6 +19,7 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Play;
using osu.Game.Screens.Ranking;
using osu.Game.Skinning;
namespace osu.Game.Screens.Select
{
@@ -55,11 +55,11 @@ namespace osu.Game.Screens.Select
private readonly Bindable<IEnumerable<Mod>> selectedMods = new Bindable<IEnumerable<Mod>>(new Mod[] { });
[BackgroundDependencyLoader(true)]
private async Task load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, Bindable<IEnumerable<Mod>> selectedMods)
private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, SkinManager skins, DialogOverlay dialogOverlay, Bindable<IEnumerable<Mod>> selectedMods)
{
if (selectedMods != null) this.selectedMods.BindTo(selectedMods);
sampleConfirm = await audio.Sample.GetAsync(@"SongSelect/confirm-selection");
sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection");
Footer.AddButton(@"mods", colours.Yellow, modSelect, Key.F1, float.MaxValue);
@@ -78,7 +78,10 @@ namespace osu.Game.Screens.Select
// if we have no beatmaps but osu-stable is found, let's prompt the user to import.
if (!beatmaps.GetAllUsableBeatmapSets().Any() && beatmaps.StableInstallationAvailable)
dialogOverlay.Push(new ImportFromStablePopup(() =>
Task.Factory.StartNew(beatmaps.ImportFromStable, TaskCreationOptions.LongRunning)));
{
beatmaps.ImportFromStableAsync();
skins.ImportFromStableAsync();
}));
});
}
}
+3 -4
View File
@@ -3,7 +3,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Input;
using osu.Framework.Allocation;
@@ -199,7 +198,7 @@ namespace osu.Game.Screens.Select
}
[BackgroundDependencyLoader(true)]
private async Task load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours)
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours)
{
if (Footer != null)
{
@@ -219,8 +218,8 @@ namespace osu.Game.Screens.Select
dialogOverlay = dialog;
sampleChangeDifficulty = await audio.Sample.GetAsync(@"SongSelect/select-difficulty");
sampleChangeBeatmap = await audio.Sample.GetAsync(@"SongSelect/select-expand");
sampleChangeDifficulty = audio.Sample.Get(@"SongSelect/select-difficulty");
sampleChangeBeatmap = audio.Sample.Get(@"SongSelect/select-expand");
Carousel.LoadBeatmapSetsFromManager(this.beatmaps);
}
@@ -9,7 +9,6 @@ using osu.Framework.Graphics.Textures;
using osu.Framework.MathUtils;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace osu.Game.Screens.Tournament.Components
{
@@ -76,9 +75,9 @@ namespace osu.Game.Screens.Tournament.Components
private int expiredCount;
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
texture = await textures.GetAsync("Drawings/visualiser-line");
texture = textures.Get("Drawings/visualiser-line");
}
protected override void UpdateAfterChildren()
+3 -3
View File
@@ -53,13 +53,13 @@ namespace osu.Game.Screens.Tournament
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
[BackgroundDependencyLoader]
private async Task load(TextureStore textures, Storage storage)
private void load(TextureStore textures, Storage storage)
{
this.storage = storage;
TextureStore flagStore = new TextureStore();
// Local flag store
flagStore.AddStore(new RawTextureLoaderStore(new NamespacedResourceStore<byte[]>(new StorageBackedResourceStore(storage), "Drawings")));
flagStore.AddStore(new TextureLoaderStore(new NamespacedResourceStore<byte[]>(new StorageBackedResourceStore(storage), "Drawings")));
// Default texture store
flagStore.AddStore(textures);
@@ -87,7 +87,7 @@ namespace osu.Game.Screens.Tournament
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fill,
Texture = await textures.GetAsync(@"Backgrounds/Drawings/background.png")
Texture = textures.Get(@"Backgrounds/Drawings/background.png")
},
new FillFlowContainer
{
+2 -3
View File
@@ -4,7 +4,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -179,9 +178,9 @@ namespace osu.Game.Screens.Tournament
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
flagSprite.Texture = await textures.GetAsync($@"Flags/{Team.FlagName}");
flagSprite.Texture = textures.Get($@"Flags/{Team.FlagName}");
}
}
}
@@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
@@ -373,9 +372,9 @@ namespace osu.Game.Screens.Tournament
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(TextureStore textures)
{
flagSprite.Texture = await textures.GetAsync($@"Flags/{Team.FlagName}");
flagSprite.Texture = textures.Get($@"Flags/{Team.FlagName}");
}
}
}
+1 -1
View File
@@ -37,7 +37,7 @@ namespace osu.Game.Skinning
Configuration = new SkinConfiguration();
Samples = audioManager.GetSampleManager(storage);
Textures = new TextureStore(new RawTextureLoaderStore(storage));
Textures = new TextureStore(new TextureLoaderStore(storage));
}
public override Drawable GetDrawableComponent(string componentName)
+17 -12
View File
@@ -26,17 +26,25 @@ namespace osu.Game.Skinning
public override string[] HandledExtensions => new[] { ".osk" };
protected override string ImportFromStablePath => "Skins";
/// <summary>
/// Returns a list of all usable <see cref="SkinInfo"/>s.
/// Returns a list of all usable <see cref="SkinInfo"/>s. Includes the special default skin plus all skins from <see cref="GetAllUserSkins"/>.
/// </summary>
/// <returns>A list of available <see cref="SkinInfo"/>.</returns>
public List<SkinInfo> GetAllUsableSkins()
{
var userSkins = ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList();
var userSkins = GetAllUserSkins();
userSkins.Insert(0, SkinInfo.Default);
return userSkins;
}
/// <summary>
/// Returns a list of all usable <see cref="SkinInfo"/>s that have been loaded by the user.
/// </summary>
/// <returns>A list of available <see cref="SkinInfo"/>.</returns>
public List<SkinInfo> GetAllUserSkins() => ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList();
protected override SkinInfo CreateModel(ArchiveReader archive) => new SkinInfo
{
Name = archive.Name
@@ -85,6 +93,13 @@ namespace osu.Game.Skinning
{
this.audio = audio;
ItemRemoved += removedInfo =>
{
// check the removed skin is not the current user choice. if it is, switch back to default.
if (removedInfo.ID == CurrentSkinInfo.Value.ID)
CurrentSkinInfo.Value = SkinInfo.Default;
};
CurrentSkinInfo.ValueChanged += info => CurrentSkin.Value = GetSkin(info);
CurrentSkin.ValueChanged += skin =>
{
@@ -93,16 +108,6 @@ namespace osu.Game.Skinning
SourceChanged?.Invoke();
};
// migrate older imports which didn't have access to skin.ini
using (ContextFactory.GetForWrite())
{
foreach (var skinInfo in ModelStore.ConsumableItems.Where(s => s.Name.EndsWith(".osk")))
{
populate(skinInfo);
Update(skinInfo);
}
}
}
/// <summary>
@@ -57,7 +57,7 @@ namespace osu.Game.Storyboards.Drawables
[BackgroundDependencyLoader]
private void load(FileStore fileStore)
{
dependencies.Cache(new TextureStore(new RawTextureLoaderStore(fileStore.Store), false) { ScaleAdjust = 1, });
dependencies.Cache(new TextureStore(new TextureLoaderStore(fileStore.Store), false, scaleAdjust: 1));
foreach (var layer in Storyboard.Layers)
Add(layer.CreateDrawable());
+3 -4
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -25,14 +24,14 @@ namespace osu.Game.Users
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(LargeTextureStore textures)
{
if (textures == null)
throw new ArgumentNullException(nameof(textures));
Texture texture = null;
if (user != null && user.Id > 1) texture = await textures.GetAsync($@"https://a.ppy.sh/{user.Id}");
if (texture == null) texture = await textures.GetAsync(@"Online/avatar-guest");
if (user != null && user.Id > 1) texture = textures.Get($@"https://a.ppy.sh/{user.Id}");
if (texture == null) texture = textures.Get(@"Online/avatar-guest");
Add(new Sprite
{
+4 -5
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -45,7 +44,7 @@ namespace osu.Game.Users
country = value;
if (LoadState >= LoadState.Ready)
sprite.Texture = getFlagTexture().Result;
sprite.Texture = getFlagTexture();
}
}
@@ -65,15 +64,15 @@ namespace osu.Game.Users
}
[BackgroundDependencyLoader]
private async Task load(TextureStore ts)
private void load(TextureStore ts)
{
if (ts == null)
throw new ArgumentNullException(nameof(ts));
textures = ts;
sprite.Texture = await getFlagTexture();
sprite.Texture = getFlagTexture();
}
private async Task<Texture> getFlagTexture() => await textures.GetAsync($@"Flags/{country?.FlagName ?? @"__"}");
private Texture getFlagTexture() => textures.Get($@"Flags/{country?.FlagName ?? @"__"}");
}
}
+2 -3
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
@@ -19,13 +18,13 @@ namespace osu.Game.Users
}
[BackgroundDependencyLoader]
private async Task load(TextureStore textures)
private void load(LargeTextureStore textures)
{
if (textures == null)
throw new ArgumentNullException(nameof(textures));
if (!string.IsNullOrEmpty(user.CoverUrl))
Texture = await textures.GetAsync(user.CoverUrl);
Texture = textures.Get(user.CoverUrl);
}
}
}
+1 -1
View File
@@ -18,7 +18,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.2" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="ppy.osu.Framework" Version="2018.830.0" />
<PackageReference Include="ppy.osu.Framework" Version="2018.910.1" />
<PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.10.1" />
<PackageReference Include="SharpRaven" Version="2.4.0" />