mirror of
https://github.com/osukey/osukey.git
synced 2025-08-08 00:53:56 +09:00
Merge branch 'master' into watch-replays-4
This commit is contained in:
@ -30,9 +30,9 @@ namespace osu.Game.Tests
|
|||||||
trackStore = audioManager.GetTrackStore(reader);
|
trackStore = audioManager.GetTrackStore(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose();
|
base.Dispose(isDisposing);
|
||||||
stream?.Dispose();
|
stream?.Dispose();
|
||||||
reader?.Dispose();
|
reader?.Dispose();
|
||||||
trackStore?.Dispose();
|
trackStore?.Dispose();
|
||||||
|
@ -13,6 +13,7 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Framework.Lists;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
@ -159,6 +160,8 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <param name="beatmap">The beatmap difficulty to restore.</param>
|
/// <param name="beatmap">The beatmap difficulty to restore.</param>
|
||||||
public void Restore(BeatmapInfo beatmap) => beatmaps.Restore(beatmap);
|
public void Restore(BeatmapInfo beatmap) => beatmaps.Restore(beatmap);
|
||||||
|
|
||||||
|
private readonly WeakList<WorkingBeatmap> workingCache = new WeakList<WorkingBeatmap>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieve a <see cref="WorkingBeatmap"/> instance for the provided <see cref="BeatmapInfo"/>
|
/// Retrieve a <see cref="WorkingBeatmap"/> instance for the provided <see cref="BeatmapInfo"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -173,12 +176,18 @@ namespace osu.Game.Beatmaps
|
|||||||
if (beatmapInfo?.BeatmapSet == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo)
|
if (beatmapInfo?.BeatmapSet == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo)
|
||||||
return DefaultBeatmap;
|
return DefaultBeatmap;
|
||||||
|
|
||||||
|
var cached = workingCache.FirstOrDefault(w => w.BeatmapInfo?.ID == beatmapInfo.ID);
|
||||||
|
|
||||||
|
if (cached != null)
|
||||||
|
return cached;
|
||||||
|
|
||||||
if (beatmapInfo.Metadata == null)
|
if (beatmapInfo.Metadata == null)
|
||||||
beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata;
|
beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata;
|
||||||
|
|
||||||
WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(Files.Store, new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager);
|
WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(Files.Store, new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager);
|
||||||
|
|
||||||
previous?.TransferTo(working);
|
previous?.TransferTo(working);
|
||||||
|
workingCache.Add(working);
|
||||||
|
|
||||||
return working;
|
return working;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,9 @@ using osu.Framework.IO.File;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Statistics;
|
||||||
using osu.Game.IO.Serialization;
|
using osu.Game.IO.Serialization;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -31,6 +33,8 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
protected AudioManager AudioManager { get; }
|
protected AudioManager AudioManager { get; }
|
||||||
|
|
||||||
|
private static readonly GlobalStatistic<int> total_count = GlobalStatistics.Get<int>(nameof(Beatmaps), $"Total {nameof(WorkingBeatmap)}s");
|
||||||
|
|
||||||
protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager)
|
protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager)
|
||||||
{
|
{
|
||||||
AudioManager = audioManager;
|
AudioManager = audioManager;
|
||||||
@ -38,24 +42,13 @@ namespace osu.Game.Beatmaps
|
|||||||
BeatmapSetInfo = beatmapInfo.BeatmapSet;
|
BeatmapSetInfo = beatmapInfo.BeatmapSet;
|
||||||
Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||||
|
|
||||||
beatmap = new RecyclableLazy<IBeatmap>(() =>
|
|
||||||
{
|
|
||||||
var b = GetBeatmap() ?? new Beatmap();
|
|
||||||
|
|
||||||
// The original beatmap version needs to be preserved as the database doesn't contain it
|
|
||||||
BeatmapInfo.BeatmapVersion = b.BeatmapInfo.BeatmapVersion;
|
|
||||||
|
|
||||||
// Use the database-backed info for more up-to-date values (beatmap id, ranked status, etc)
|
|
||||||
b.BeatmapInfo = BeatmapInfo;
|
|
||||||
|
|
||||||
return b;
|
|
||||||
});
|
|
||||||
|
|
||||||
track = new RecyclableLazy<Track>(() => GetTrack() ?? GetVirtualTrack());
|
track = new RecyclableLazy<Track>(() => GetTrack() ?? GetVirtualTrack());
|
||||||
background = new RecyclableLazy<Texture>(GetBackground, BackgroundStillValid);
|
background = new RecyclableLazy<Texture>(GetBackground, BackgroundStillValid);
|
||||||
waveform = new RecyclableLazy<Waveform>(GetWaveform);
|
waveform = new RecyclableLazy<Waveform>(GetWaveform);
|
||||||
storyboard = new RecyclableLazy<Storyboard>(GetStoryboard);
|
storyboard = new RecyclableLazy<Storyboard>(GetStoryboard);
|
||||||
skin = new RecyclableLazy<Skin>(GetSkin);
|
skin = new RecyclableLazy<Skin>(GetSkin);
|
||||||
|
|
||||||
|
total_count.Value++;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Track GetVirtualTrack()
|
protected virtual Track GetVirtualTrack()
|
||||||
@ -153,10 +146,40 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
public override string ToString() => BeatmapInfo.ToString();
|
public override string ToString() => BeatmapInfo.ToString();
|
||||||
|
|
||||||
public bool BeatmapLoaded => beatmap.IsResultAvailable;
|
public bool BeatmapLoaded => beatmapLoadTask?.IsCompleted ?? false;
|
||||||
public IBeatmap Beatmap => beatmap.Value;
|
|
||||||
|
public Task<IBeatmap> LoadBeatmapAsync() => (beatmapLoadTask ?? (beatmapLoadTask = Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
// Todo: Handle cancellation during beatmap parsing
|
||||||
|
var b = GetBeatmap() ?? new Beatmap();
|
||||||
|
|
||||||
|
// The original beatmap version needs to be preserved as the database doesn't contain it
|
||||||
|
BeatmapInfo.BeatmapVersion = b.BeatmapInfo.BeatmapVersion;
|
||||||
|
|
||||||
|
// Use the database-backed info for more up-to-date values (beatmap id, ranked status, etc)
|
||||||
|
b.BeatmapInfo = BeatmapInfo;
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}, beatmapCancellation.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)));
|
||||||
|
|
||||||
|
public IBeatmap Beatmap
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return LoadBeatmapAsync().Result;
|
||||||
|
}
|
||||||
|
catch (TaskCanceledException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly CancellationTokenSource beatmapCancellation = new CancellationTokenSource();
|
||||||
protected abstract IBeatmap GetBeatmap();
|
protected abstract IBeatmap GetBeatmap();
|
||||||
private readonly RecyclableLazy<IBeatmap> beatmap;
|
private Task<IBeatmap> beatmapLoadTask;
|
||||||
|
|
||||||
public bool BackgroundLoaded => background.IsResultAvailable;
|
public bool BackgroundLoaded => background.IsResultAvailable;
|
||||||
public Texture Background => background.Value;
|
public Texture Background => background.Value;
|
||||||
@ -195,20 +218,46 @@ namespace osu.Game.Beatmaps
|
|||||||
other.track = track;
|
other.track = track;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Dispose()
|
|
||||||
{
|
|
||||||
background.Recycle();
|
|
||||||
waveform.Recycle();
|
|
||||||
storyboard.Recycle();
|
|
||||||
skin.Recycle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Eagerly dispose of the audio track associated with this <see cref="WorkingBeatmap"/> (if any).
|
/// Eagerly dispose of the audio track associated with this <see cref="WorkingBeatmap"/> (if any).
|
||||||
/// Accessing track again will load a fresh instance.
|
/// Accessing track again will load a fresh instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void RecycleTrack() => track.Recycle();
|
public virtual void RecycleTrack() => track.Recycle();
|
||||||
|
|
||||||
|
#region Disposal
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool isDisposed;
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
if (isDisposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
isDisposed = true;
|
||||||
|
|
||||||
|
// recycling logic is not here for the time being, as components which use
|
||||||
|
// retrieved objects from WorkingBeatmap may not hold a reference to the WorkingBeatmap itself.
|
||||||
|
// this should be fine as each retrieved component do have their own finalizers.
|
||||||
|
|
||||||
|
// cancelling the beatmap load is safe for now since the retrieval is a synchronous
|
||||||
|
// operation. if we add an async retrieval method this may need to be reconsidered.
|
||||||
|
beatmapCancellation.Cancel();
|
||||||
|
total_count.Value--;
|
||||||
|
}
|
||||||
|
|
||||||
|
~WorkingBeatmap()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public class RecyclableLazy<T>
|
public class RecyclableLazy<T>
|
||||||
{
|
{
|
||||||
private Lazy<T> lazy;
|
private Lazy<T> lazy;
|
||||||
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.EntityFrameworkCore.Storage;
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Statistics;
|
||||||
|
|
||||||
namespace osu.Game.Database
|
namespace osu.Game.Database
|
||||||
{
|
{
|
||||||
@ -31,11 +32,20 @@ namespace osu.Game.Database
|
|||||||
recycleThreadContexts();
|
recycleThreadContexts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly GlobalStatistic<int> reads = GlobalStatistics.Get<int>("Database", "Get (Read)");
|
||||||
|
private static readonly GlobalStatistic<int> writes = GlobalStatistics.Get<int>("Database", "Get (Write)");
|
||||||
|
private static readonly GlobalStatistic<int> commits = GlobalStatistics.Get<int>("Database", "Commits");
|
||||||
|
private static readonly GlobalStatistic<int> rollbacks = GlobalStatistics.Get<int>("Database", "Rollbacks");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a context for the current thread for read-only usage.
|
/// Get a context for the current thread for read-only usage.
|
||||||
/// If a <see cref="DatabaseWriteUsage"/> is in progress, the existing write-safe context will be returned.
|
/// If a <see cref="DatabaseWriteUsage"/> is in progress, the existing write-safe context will be returned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public OsuDbContext Get() => threadContexts.Value;
|
public OsuDbContext Get()
|
||||||
|
{
|
||||||
|
reads.Value++;
|
||||||
|
return threadContexts.Value;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Request a context for write usage. Can be consumed in a nested fashion (and will return the same underlying context).
|
/// Request a context for write usage. Can be consumed in a nested fashion (and will return the same underlying context).
|
||||||
@ -45,6 +55,7 @@ namespace osu.Game.Database
|
|||||||
/// <returns>A usage containing a usable context.</returns>
|
/// <returns>A usage containing a usable context.</returns>
|
||||||
public DatabaseWriteUsage GetForWrite(bool withTransaction = true)
|
public DatabaseWriteUsage GetForWrite(bool withTransaction = true)
|
||||||
{
|
{
|
||||||
|
writes.Value++;
|
||||||
Monitor.Enter(writeLock);
|
Monitor.Enter(writeLock);
|
||||||
OsuDbContext context;
|
OsuDbContext context;
|
||||||
|
|
||||||
@ -90,9 +101,15 @@ namespace osu.Game.Database
|
|||||||
if (usages == 0)
|
if (usages == 0)
|
||||||
{
|
{
|
||||||
if (currentWriteDidError)
|
if (currentWriteDidError)
|
||||||
|
{
|
||||||
|
rollbacks.Value++;
|
||||||
currentWriteTransaction?.Rollback();
|
currentWriteTransaction?.Rollback();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
commits.Value++;
|
||||||
currentWriteTransaction?.Commit();
|
currentWriteTransaction?.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
if (currentWriteDidWrite || currentWriteDidError)
|
if (currentWriteDidWrite || currentWriteDidError)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
|
using osu.Framework.Statistics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
@ -34,6 +35,8 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
private static readonly Lazy<OsuDbLoggerFactory> logger = new Lazy<OsuDbLoggerFactory>(() => new OsuDbLoggerFactory());
|
private static readonly Lazy<OsuDbLoggerFactory> logger = new Lazy<OsuDbLoggerFactory>(() => new OsuDbLoggerFactory());
|
||||||
|
|
||||||
|
private static readonly GlobalStatistic<int> contexts = GlobalStatistics.Get<int>("Database", "Contexts");
|
||||||
|
|
||||||
static OsuDbContext()
|
static OsuDbContext()
|
||||||
{
|
{
|
||||||
// required to initialise native SQLite libraries on some platforms.
|
// required to initialise native SQLite libraries on some platforms.
|
||||||
@ -76,6 +79,8 @@ namespace osu.Game.Database
|
|||||||
connection.Close();
|
connection.Close();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contexts.Value++;
|
||||||
}
|
}
|
||||||
|
|
||||||
~OsuDbContext()
|
~OsuDbContext()
|
||||||
@ -85,6 +90,20 @@ namespace osu.Game.Database
|
|||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool isDisposed;
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
if (isDisposed) return;
|
||||||
|
|
||||||
|
isDisposed = true;
|
||||||
|
|
||||||
|
base.Dispose();
|
||||||
|
|
||||||
|
contexts.Value--;
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
{
|
{
|
||||||
base.OnConfiguring(optionsBuilder);
|
base.OnConfiguring(optionsBuilder);
|
||||||
|
@ -6,23 +6,28 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Framework.Graphics.Transforms;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Backgrounds
|
namespace osu.Game.Graphics.Backgrounds
|
||||||
{
|
{
|
||||||
public class Background : BufferedContainer
|
/// <summary>
|
||||||
|
/// A background which offers blurring via a <see cref="BufferedContainer"/> on demand.
|
||||||
|
/// </summary>
|
||||||
|
public class Background : CompositeDrawable
|
||||||
{
|
{
|
||||||
public Sprite Sprite;
|
public Sprite Sprite;
|
||||||
|
|
||||||
private readonly string textureName;
|
private readonly string textureName;
|
||||||
|
|
||||||
|
private BufferedContainer bufferedContainer;
|
||||||
|
|
||||||
public Background(string textureName = @"")
|
public Background(string textureName = @"")
|
||||||
{
|
{
|
||||||
CacheDrawnFrameBuffer = true;
|
|
||||||
|
|
||||||
this.textureName = textureName;
|
this.textureName = textureName;
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
Add(Sprite = new Sprite
|
AddInternal(Sprite = new Sprite
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -37,5 +42,28 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
if (!string.IsNullOrEmpty(textureName))
|
if (!string.IsNullOrEmpty(textureName))
|
||||||
Sprite.Texture = textures.Get(textureName);
|
Sprite.Texture = textures.Get(textureName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 BlurSigma => bufferedContainer?.BlurSigma ?? Vector2.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Smoothly adjusts <see cref="IBufferedContainer.BlurSigma"/> over time.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns>
|
||||||
|
public void BlurTo(Vector2 newBlurSigma, double duration = 0, Easing easing = Easing.None)
|
||||||
|
{
|
||||||
|
if (bufferedContainer == null)
|
||||||
|
{
|
||||||
|
RemoveInternal(Sprite);
|
||||||
|
|
||||||
|
AddInternal(bufferedContainer = new BufferedContainer
|
||||||
|
{
|
||||||
|
CacheDrawnFrameBuffer = true,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = Sprite
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferedContainer.BlurTo(newBlurSigma, duration, easing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,6 +297,10 @@ namespace osu.Game
|
|||||||
var nextBeatmap = beatmap.NewValue;
|
var nextBeatmap = beatmap.NewValue;
|
||||||
if (nextBeatmap?.Track != null)
|
if (nextBeatmap?.Track != null)
|
||||||
nextBeatmap.Track.Completed += currentTrackCompleted;
|
nextBeatmap.Track.Completed += currentTrackCompleted;
|
||||||
|
|
||||||
|
beatmap.OldValue?.Dispose();
|
||||||
|
|
||||||
|
nextBeatmap?.LoadBeatmapAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void currentTrackCompleted()
|
private void currentTrackCompleted()
|
||||||
|
@ -66,24 +66,64 @@ namespace osu.Game.Overlays
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Header.Tabs.Current.ValueChanged += _ => Scheduler.AddOnce(updateSearch);
|
Header.Tabs.Current.ValueChanged += _ => queueUpdate();
|
||||||
|
|
||||||
Filter.Tabs.Current.ValueChanged += _ => Scheduler.AddOnce(updateSearch);
|
Filter.Tabs.Current.ValueChanged += _ => queueUpdate();
|
||||||
|
|
||||||
Filter.DisplayStyleControl.DisplayStyle.ValueChanged += style => recreatePanels(style.NewValue);
|
Filter.DisplayStyleControl.DisplayStyle.ValueChanged += style => recreatePanels(style.NewValue);
|
||||||
Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => Scheduler.AddOnce(updateSearch);
|
Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => queueUpdate();
|
||||||
|
|
||||||
|
currentQuery.BindTo(Filter.Search.Current);
|
||||||
currentQuery.ValueChanged += query =>
|
currentQuery.ValueChanged += query =>
|
||||||
{
|
{
|
||||||
queryChangedDebounce?.Cancel();
|
queryChangedDebounce?.Cancel();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(query.NewValue))
|
if (string.IsNullOrEmpty(query.NewValue))
|
||||||
Scheduler.AddOnce(updateSearch);
|
queueUpdate();
|
||||||
else
|
else
|
||||||
queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500);
|
queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
currentQuery.BindTo(Filter.Search.Current);
|
private APIRequest getUsersRequest;
|
||||||
|
|
||||||
|
private readonly Bindable<string> currentQuery = new Bindable<string>();
|
||||||
|
|
||||||
|
private ScheduledDelegate queryChangedDebounce;
|
||||||
|
|
||||||
|
private void queueUpdate() => Scheduler.AddOnce(updateSearch);
|
||||||
|
|
||||||
|
private void updateSearch()
|
||||||
|
{
|
||||||
|
queryChangedDebounce?.Cancel();
|
||||||
|
|
||||||
|
if (!IsLoaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Users = null;
|
||||||
|
clearPanels();
|
||||||
|
loading.Hide();
|
||||||
|
getUsersRequest?.Cancel();
|
||||||
|
|
||||||
|
if (API?.IsLoggedIn != true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (Header.Tabs.Current.Value)
|
||||||
|
{
|
||||||
|
case SocialTab.Friends:
|
||||||
|
var friendRequest = new GetFriendsRequest(); // TODO filter arguments?
|
||||||
|
friendRequest.Success += updateUsers;
|
||||||
|
API.Queue(getUsersRequest = friendRequest);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
var userRequest = new GetUsersRequest(); // TODO filter arguments!
|
||||||
|
userRequest.Success += response => updateUsers(response.Select(r => r.User));
|
||||||
|
API.Queue(getUsersRequest = userRequest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recreatePanels(PanelDisplayStyle displayStyle)
|
private void recreatePanels(PanelDisplayStyle displayStyle)
|
||||||
@ -133,45 +173,6 @@ namespace osu.Game.Overlays
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private APIRequest getUsersRequest;
|
|
||||||
|
|
||||||
private readonly Bindable<string> currentQuery = new Bindable<string>();
|
|
||||||
|
|
||||||
private ScheduledDelegate queryChangedDebounce;
|
|
||||||
|
|
||||||
private void updateSearch()
|
|
||||||
{
|
|
||||||
queryChangedDebounce?.Cancel();
|
|
||||||
|
|
||||||
if (!IsLoaded)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Users = null;
|
|
||||||
clearPanels();
|
|
||||||
loading.Hide();
|
|
||||||
getUsersRequest?.Cancel();
|
|
||||||
|
|
||||||
if (API?.IsLoggedIn != true)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (Header.Tabs.Current.Value)
|
|
||||||
{
|
|
||||||
case SocialTab.Friends:
|
|
||||||
var friendRequest = new GetFriendsRequest(); // TODO filter arguments?
|
|
||||||
friendRequest.Success += updateUsers;
|
|
||||||
API.Queue(getUsersRequest = friendRequest);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
var userRequest = new GetUsersRequest(); // TODO filter arguments!
|
|
||||||
userRequest.Success += response => updateUsers(response.Select(r => r.User));
|
|
||||||
API.Queue(getUsersRequest = userRequest);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
loading.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateUsers(IEnumerable<User> newUsers)
|
private void updateUsers(IEnumerable<User> newUsers)
|
||||||
{
|
{
|
||||||
Users = newUsers;
|
Users = newUsers;
|
||||||
@ -193,7 +194,7 @@ namespace osu.Game.Overlays
|
|||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case APIState.Online:
|
case APIState.Online:
|
||||||
Scheduler.AddOnce(updateSearch);
|
queueUpdate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
private Background background;
|
private Background background;
|
||||||
|
|
||||||
private int currentDisplay;
|
private int currentDisplay;
|
||||||
private const int background_count = 5;
|
private const int background_count = 7;
|
||||||
|
|
||||||
private string backgroundName => $@"Menu/menu-background-{currentDisplay % background_count + 1}";
|
private string backgroundName => $@"Menu/menu-background-{currentDisplay % background_count + 1}";
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
if (!resuming)
|
if (!resuming)
|
||||||
{
|
{
|
||||||
Beatmap.Value = introBeatmap;
|
Beatmap.Value = introBeatmap;
|
||||||
|
introBeatmap = null;
|
||||||
|
|
||||||
if (menuVoice.Value)
|
if (menuVoice.Value)
|
||||||
welcome.Play();
|
welcome.Play();
|
||||||
@ -94,7 +95,10 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu.
|
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu.
|
||||||
if (menuMusic.Value)
|
if (menuMusic.Value)
|
||||||
|
{
|
||||||
track.Start();
|
track.Start();
|
||||||
|
track = null;
|
||||||
|
}
|
||||||
|
|
||||||
LoadComponentAsync(mainMenu = new MainMenu());
|
LoadComponentAsync(mainMenu = new MainMenu());
|
||||||
|
|
||||||
|
@ -96,13 +96,13 @@ namespace osu.Game.Screens.Menu
|
|||||||
var track = beatmap.Value.TrackLoaded ? beatmap.Value.Track : null;
|
var track = beatmap.Value.TrackLoaded ? beatmap.Value.Track : null;
|
||||||
var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null;
|
var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null;
|
||||||
|
|
||||||
float[] temporalAmplitudes = track?.CurrentAmplitudes.FrequencyAmplitudes ?? new float[256];
|
float[] temporalAmplitudes = track?.CurrentAmplitudes.FrequencyAmplitudes;
|
||||||
|
|
||||||
for (int i = 0; i < bars_per_visualiser; i++)
|
for (int i = 0; i < bars_per_visualiser; i++)
|
||||||
{
|
{
|
||||||
if (track?.IsRunning ?? false)
|
if (track?.IsRunning ?? false)
|
||||||
{
|
{
|
||||||
float targetAmplitude = temporalAmplitudes[(i + indexOffset) % bars_per_visualiser] * (effect?.KiaiMode == true ? 1 : 0.5f);
|
float targetAmplitude = (temporalAmplitudes?[(i + indexOffset) % bars_per_visualiser] ?? 0) * (effect?.KiaiMode == true ? 1 : 0.5f);
|
||||||
if (targetAmplitude > frequencyAmplitudes[i])
|
if (targetAmplitude > frequencyAmplitudes[i])
|
||||||
frequencyAmplitudes[i] = targetAmplitude;
|
frequencyAmplitudes[i] = targetAmplitude;
|
||||||
}
|
}
|
||||||
@ -115,7 +115,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
|
|
||||||
indexOffset = (indexOffset + index_change) % bars_per_visualiser;
|
indexOffset = (indexOffset + index_change) % bars_per_visualiser;
|
||||||
Scheduler.AddDelayed(updateAmplitudes, time_between_updates);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateColour()
|
private void updateColour()
|
||||||
@ -131,7 +130,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
updateAmplitudes();
|
|
||||||
|
Scheduler.AddDelayed(updateAmplitudes, time_between_updates, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
@ -137,9 +137,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
track = audio?.Tracks.GetVirtual(length);
|
track = audio?.Tracks.GetVirtual(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose();
|
base.Dispose(isDisposing);
|
||||||
store?.Dispose();
|
store?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.701.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2019.702.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2019.703.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.23.0" />
|
<PackageReference Include="SharpCompress" Version="0.23.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
@ -104,9 +104,9 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.701.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2019.702.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2019.703.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.702.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.703.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Reference in New Issue
Block a user