mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Merge master into netstandard
This commit is contained in:
@ -484,7 +484,8 @@ namespace osu.Game.Beatmaps
|
||||
using (var stream = new StreamReader(reader.GetStream(mapName)))
|
||||
metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
|
||||
|
||||
beatmapSet = new BeatmapSetInfo
|
||||
// check if a set already exists with the same online id.
|
||||
beatmapSet = beatmaps.BeatmapSets.FirstOrDefault(b => b.OnlineBeatmapSetID == metadata.OnlineBeatmapSetID) ?? new BeatmapSetInfo
|
||||
{
|
||||
OnlineBeatmapSetID = metadata.OnlineBeatmapSetID,
|
||||
Beatmaps = new List<BeatmapInfo>(),
|
||||
@ -511,16 +512,21 @@ namespace osu.Game.Beatmaps
|
||||
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
||||
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
||||
|
||||
// TODO: Diff beatmap metadata with set metadata and leave it here if necessary
|
||||
beatmap.BeatmapInfo.Metadata = null;
|
||||
var existing = beatmaps.Beatmaps.FirstOrDefault(b => b.Hash == beatmap.BeatmapInfo.Hash || b.OnlineBeatmapID == beatmap.BeatmapInfo.OnlineBeatmapID);
|
||||
|
||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||
if (existing == null)
|
||||
{
|
||||
// TODO: Diff beatmap metadata with set metadata and leave it here if necessary
|
||||
beatmap.BeatmapInfo.Metadata = null;
|
||||
|
||||
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance()?.CreateDifficultyCalculator(beatmap).Calculate() ?? 0;
|
||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||
|
||||
beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo);
|
||||
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance()?.CreateDifficultyCalculator(beatmap).Calculate() ?? 0;
|
||||
|
||||
beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Framework.Timing;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
@ -10,45 +14,46 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
protected double TimeRate = 1;
|
||||
|
||||
protected abstract double CalculateInternal(Dictionary<string, string> categoryDifficulty);
|
||||
|
||||
private void loadTiming()
|
||||
{
|
||||
// TODO: Handle mods
|
||||
const int audio_rate = 100;
|
||||
TimeRate = audio_rate / 100.0;
|
||||
}
|
||||
|
||||
public double Calculate(Dictionary<string, string> categoryDifficulty = null)
|
||||
{
|
||||
loadTiming();
|
||||
double difficulty = CalculateInternal(categoryDifficulty);
|
||||
return difficulty;
|
||||
}
|
||||
public abstract double Calculate(Dictionary<string, string> categoryDifficulty = null);
|
||||
}
|
||||
|
||||
public abstract class DifficultyCalculator<T> : DifficultyCalculator where T : HitObject
|
||||
{
|
||||
protected readonly Beatmap Beatmap;
|
||||
protected readonly Beatmap<T> Beatmap;
|
||||
protected readonly Mod[] Mods;
|
||||
|
||||
protected List<T> Objects;
|
||||
|
||||
protected DifficultyCalculator(Beatmap beatmap)
|
||||
protected DifficultyCalculator(Beatmap beatmap, Mod[] mods = null)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
Beatmap = CreateBeatmapConverter(beatmap).Convert(beatmap);
|
||||
Mods = mods ?? new Mod[0];
|
||||
|
||||
Objects = CreateBeatmapConverter().Convert(beatmap).HitObjects;
|
||||
|
||||
foreach (var h in Objects)
|
||||
h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
|
||||
ApplyMods(Mods);
|
||||
|
||||
PreprocessHitObjects();
|
||||
}
|
||||
|
||||
protected virtual void ApplyMods(Mod[] mods)
|
||||
{
|
||||
var clock = new StopwatchClock();
|
||||
mods.OfType<IApplicableToClock>().ForEach(m => m.ApplyToClock(clock));
|
||||
TimeRate = clock.Rate;
|
||||
|
||||
foreach (var mod in Mods.OfType<IApplicableToDifficulty>())
|
||||
mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToHitObject<T>>())
|
||||
foreach (var obj in Beatmap.HitObjects)
|
||||
mod.ApplyToHitObject(obj);
|
||||
|
||||
foreach (var h in Beatmap.HitObjects)
|
||||
h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
}
|
||||
|
||||
protected virtual void PreprocessHitObjects()
|
||||
{
|
||||
}
|
||||
|
||||
protected abstract BeatmapConverter<T> CreateBeatmapConverter();
|
||||
protected abstract BeatmapConverter<T> CreateBeatmapConverter(Beatmap beatmap);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ using osu.Framework.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
internal class BeatmapBackgroundSprite : Sprite
|
||||
public class BeatmapBackgroundSprite : Sprite
|
||||
{
|
||||
private readonly WorkingBeatmap working;
|
||||
|
||||
|
@ -11,7 +11,7 @@ using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
internal class DummyWorkingBeatmap : WorkingBeatmap
|
||||
public class DummyWorkingBeatmap : WorkingBeatmap
|
||||
{
|
||||
private readonly OsuGameBase game;
|
||||
|
||||
@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => null;
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => null;
|
||||
|
||||
public override string Description => "dummy";
|
||||
|
||||
|
@ -28,16 +28,11 @@ namespace osu.Game.Beatmaps
|
||||
Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||
|
||||
Mods.ValueChanged += mods => applyRateAdjustments();
|
||||
}
|
||||
|
||||
private void applyRateAdjustments()
|
||||
{
|
||||
var t = track;
|
||||
if (t == null) return;
|
||||
|
||||
t.ResetSpeedAdjustments();
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToClock>())
|
||||
mod.ApplyToClock(t);
|
||||
beatmap = new Lazy<Beatmap>(populateBeatmap);
|
||||
background = new Lazy<Texture>(populateBackground);
|
||||
track = new Lazy<Track>(populateTrack);
|
||||
waveform = new Lazy<Waveform>(populateWaveform);
|
||||
}
|
||||
|
||||
protected abstract Beatmap GetBeatmap();
|
||||
@ -45,98 +40,72 @@ namespace osu.Game.Beatmaps
|
||||
protected abstract Track GetTrack();
|
||||
protected virtual Waveform GetWaveform() => new Waveform();
|
||||
|
||||
private Beatmap beatmap;
|
||||
private readonly object beatmapLock = new object();
|
||||
public Beatmap Beatmap
|
||||
public bool BeatmapLoaded => beatmap.IsValueCreated;
|
||||
public Beatmap Beatmap => beatmap.Value;
|
||||
private readonly Lazy<Beatmap> beatmap;
|
||||
|
||||
private Beatmap populateBeatmap()
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (beatmapLock)
|
||||
{
|
||||
if (beatmap != null) return beatmap;
|
||||
var b = GetBeatmap() ?? new Beatmap();
|
||||
|
||||
beatmap = GetBeatmap() ?? new Beatmap();
|
||||
// use the database-backed info.
|
||||
b.BeatmapInfo = BeatmapInfo;
|
||||
|
||||
// use the database-backed info.
|
||||
beatmap.BeatmapInfo = BeatmapInfo;
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
private readonly object backgroundLock = new object();
|
||||
private Texture background;
|
||||
public Texture Background
|
||||
public bool BackgroundLoaded => background.IsValueCreated;
|
||||
public Texture Background => background.Value;
|
||||
private Lazy<Texture> background;
|
||||
|
||||
private Texture populateBackground() => GetBackground();
|
||||
|
||||
public bool TrackLoaded => track.IsValueCreated;
|
||||
public Track Track => track.Value;
|
||||
private Lazy<Track> track;
|
||||
|
||||
private Track populateTrack()
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (backgroundLock)
|
||||
{
|
||||
return background ?? (background = GetBackground());
|
||||
}
|
||||
}
|
||||
// we want to ensure that we always have a track, even if it's a fake one.
|
||||
var t = GetTrack() ?? new TrackVirtual();
|
||||
applyRateAdjustments(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
private Track track;
|
||||
private readonly object trackLock = new object();
|
||||
public Track Track
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (trackLock)
|
||||
{
|
||||
if (track != null) return track;
|
||||
public bool WaveformLoaded => waveform.IsValueCreated;
|
||||
public Waveform Waveform => waveform.Value;
|
||||
private readonly Lazy<Waveform> waveform;
|
||||
|
||||
// we want to ensure that we always have a track, even if it's a fake one.
|
||||
track = GetTrack() ?? new TrackVirtual();
|
||||
|
||||
applyRateAdjustments();
|
||||
return track;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Waveform waveform;
|
||||
private readonly object waveformLock = new object();
|
||||
public Waveform Waveform
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (waveformLock)
|
||||
return waveform ?? (waveform = GetWaveform());
|
||||
}
|
||||
}
|
||||
|
||||
public bool TrackLoaded => track != null;
|
||||
private Waveform populateWaveform() => GetWaveform();
|
||||
|
||||
public void TransferTo(WorkingBeatmap other)
|
||||
{
|
||||
lock (trackLock)
|
||||
{
|
||||
if (track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo))
|
||||
other.track = track;
|
||||
}
|
||||
if (track.IsValueCreated && Track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo))
|
||||
other.track = track;
|
||||
|
||||
if (background != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo))
|
||||
if (background.IsValueCreated && Background != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo))
|
||||
other.background = background;
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
background?.Dispose();
|
||||
background = null;
|
||||
|
||||
waveform?.Dispose();
|
||||
if (BackgroundLoaded) Background?.Dispose();
|
||||
if (WaveformLoaded) Waveform?.Dispose();
|
||||
}
|
||||
|
||||
public void DisposeTrack()
|
||||
{
|
||||
lock (trackLock)
|
||||
{
|
||||
track?.Dispose();
|
||||
track = null;
|
||||
}
|
||||
if (TrackLoaded) Track?.Dispose();
|
||||
}
|
||||
|
||||
private void applyRateAdjustments(Track t = null)
|
||||
{
|
||||
if (t == null && track.IsValueCreated) t = Track;
|
||||
if (t == null) return;
|
||||
|
||||
t.ResetSpeedAdjustments();
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToClock>())
|
||||
mod.ApplyToClock(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user