mirror of https://github.com/ppy/osu
Add basic base class to begin to standardise function across caching components
This commit is contained in:
parent
14bb079feb
commit
0103b12575
|
@ -11,11 +11,11 @@
|
|||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
|
@ -27,14 +27,11 @@ namespace osu.Game.Beatmaps
|
|||
/// A component which performs and acts as a central cache for difficulty calculations of beatmap/ruleset/mod combinations.
|
||||
/// Currently not persisted between game sessions.
|
||||
/// </summary>
|
||||
public class BeatmapDifficultyCache : Component
|
||||
public class BeatmapDifficultyCache : MemoryCachingComponent<BeatmapDifficultyCache.DifficultyCacheLookup, StarDifficulty>
|
||||
{
|
||||
// Too many simultaneous updates can lead to stutters. One thread seems to work fine for song select display purposes.
|
||||
private readonly ThreadedTaskScheduler updateScheduler = new ThreadedTaskScheduler(1, nameof(BeatmapDifficultyCache));
|
||||
|
||||
// A permanent cache to prevent re-computations.
|
||||
private readonly ConcurrentDictionary<DifficultyCacheLookup, StarDifficulty> difficultyCache = new ConcurrentDictionary<DifficultyCacheLookup, StarDifficulty>();
|
||||
|
||||
// All bindables that should be updated along with the current ruleset + mods.
|
||||
private readonly LockedWeakList<BindableStarDifficulty> trackedBindables = new LockedWeakList<BindableStarDifficulty>();
|
||||
|
||||
|
@ -243,7 +240,7 @@ private StarDifficulty computeDifficulty(in DifficultyCacheLookup key, BeatmapIn
|
|||
var calculator = ruleset.CreateDifficultyCalculator(beatmapManager.GetWorkingBeatmap(beatmapInfo));
|
||||
var attributes = calculator.Calculate(key.Mods);
|
||||
|
||||
return difficultyCache[key] = new StarDifficulty(attributes);
|
||||
return Cache[key] = new StarDifficulty(attributes);
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException e)
|
||||
{
|
||||
|
@ -254,7 +251,7 @@ private StarDifficulty computeDifficulty(in DifficultyCacheLookup key, BeatmapIn
|
|||
if (rulesetInfo.Equals(beatmapInfo.Ruleset))
|
||||
{
|
||||
Logger.Error(e, $"Failed to convert {beatmapInfo.OnlineBeatmapID} to the beatmap's default ruleset ({beatmapInfo.Ruleset}).");
|
||||
return difficultyCache[key] = new StarDifficulty();
|
||||
return Cache[key] = new StarDifficulty();
|
||||
}
|
||||
|
||||
// Check the cache first because this is now a different ruleset than the one previously guarded against.
|
||||
|
@ -265,7 +262,7 @@ private StarDifficulty computeDifficulty(in DifficultyCacheLookup key, BeatmapIn
|
|||
}
|
||||
catch
|
||||
{
|
||||
return difficultyCache[key] = new StarDifficulty();
|
||||
return Cache[key] = new StarDifficulty();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,7 +291,7 @@ private bool tryGetExisting(BeatmapInfo beatmapInfo, RulesetInfo rulesetInfo, IE
|
|||
}
|
||||
|
||||
key = new DifficultyCacheLookup(beatmapInfo.ID, rulesetInfo.ID.Value, mods);
|
||||
return difficultyCache.TryGetValue(key, out existingDifficulty);
|
||||
return Cache.TryGetValue(key, out existingDifficulty);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using osu.Framework.Graphics;
|
||||
|
||||
namespace osu.Game.Database
|
||||
{
|
||||
/// <summary>
|
||||
/// A component which performs lookups (or calculations) and caches the results.
|
||||
/// Currently not persisted between game sessions.
|
||||
/// </summary>
|
||||
public abstract class MemoryCachingComponent<TLookup, TValue> : Component
|
||||
{
|
||||
protected readonly ConcurrentDictionary<TLookup, TValue> Cache = new ConcurrentDictionary<TLookup, TValue>();
|
||||
}
|
||||
}
|
|
@ -2,13 +2,12 @@
|
|||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Scoring
|
||||
{
|
||||
|
@ -16,12 +15,8 @@ namespace osu.Game.Scoring
|
|||
/// A component which performs and acts as a central cache for performance calculations of locally databased scores.
|
||||
/// Currently not persisted between game sessions.
|
||||
/// </summary>
|
||||
public class ScorePerformanceCache : Component
|
||||
public class ScorePerformanceCache : MemoryCachingComponent<ScorePerformanceCache.PerformanceCacheLookup, double>
|
||||
{
|
||||
// this cache will grow indefinitely per session and should be considered temporary.
|
||||
// this whole component should likely be replaced with database persistence.
|
||||
private readonly ConcurrentDictionary<PerformanceCacheLookup, double> performanceCache = new ConcurrentDictionary<PerformanceCacheLookup, double>();
|
||||
|
||||
[Resolved]
|
||||
private BeatmapDifficultyCache difficultyCache { get; set; }
|
||||
|
||||
|
@ -34,7 +29,7 @@ public class ScorePerformanceCache : Component
|
|||
{
|
||||
var lookupKey = new PerformanceCacheLookup(score);
|
||||
|
||||
if (performanceCache.TryGetValue(lookupKey, out double performance))
|
||||
if (Cache.TryGetValue(lookupKey, out double performance))
|
||||
return Task.FromResult((double?)performance);
|
||||
|
||||
return computePerformanceAsync(score, lookupKey, token);
|
||||
|
@ -54,7 +49,7 @@ public class ScorePerformanceCache : Component
|
|||
var total = calculator?.Calculate();
|
||||
|
||||
if (total.HasValue)
|
||||
performanceCache[lookupKey] = total.Value;
|
||||
Cache[lookupKey] = total.Value;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ private void load(ScorePerformanceCache performanceCache)
|
|||
else
|
||||
{
|
||||
performanceCache.CalculatePerformanceAsync(score, cancellationTokenSource.Token)
|
||||
.ContinueWith(t => Schedule(() => setPerformanceValue(t.Result)), cancellationTokenSource.Token);
|
||||
.ContinueWith(t => Schedule(() => setPerformanceValue(t.Result)), cancellationTokenSource.Token);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue