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

Merge pull request #10654 from peppy/fix-taiko-editor-crash

Fix taiko drum not correct handling sample / group point changes
This commit is contained in:
Dan Balasescu 2020-11-02 15:26:09 +09:00 committed by GitHub
commit c1a9a9082a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 31 deletions

View File

@ -2,6 +2,10 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints;
@ -18,47 +22,83 @@ namespace osu.Game.Rulesets.Taiko.Audio
private readonly ControlPointInfo controlPoints;
private readonly Dictionary<double, DrumSample> mappings = new Dictionary<double, DrumSample>();
private IBindableList<SampleControlPoint> samplePoints;
public DrumSampleContainer(ControlPointInfo controlPoints)
{
this.controlPoints = controlPoints;
IReadOnlyList<SampleControlPoint> samplePoints = controlPoints.SamplePoints.Count == 0 ? new[] { controlPoints.SamplePointAt(double.MinValue) } : controlPoints.SamplePoints;
for (int i = 0; i < samplePoints.Count; i++)
{
var samplePoint = samplePoints[i];
var centre = samplePoint.GetSampleInfo();
var rim = samplePoint.GetSampleInfo(HitSampleInfo.HIT_CLAP);
var lifetimeStart = i > 0 ? samplePoint.Time : double.MinValue;
var lifetimeEnd = i + 1 < samplePoints.Count ? samplePoints[i + 1].Time : double.MaxValue;
mappings[samplePoint.Time] = new DrumSample
{
Centre = addSound(centre, lifetimeStart, lifetimeEnd),
Rim = addSound(rim, lifetimeStart, lifetimeEnd)
};
}
}
private PausableSkinnableSound addSound(HitSampleInfo hitSampleInfo, double lifetimeStart, double lifetimeEnd)
[BackgroundDependencyLoader]
private void load()
{
var drawable = new PausableSkinnableSound(hitSampleInfo)
samplePoints = controlPoints.SamplePoints.GetBoundCopy();
samplePoints.BindCollectionChanged((_, __) => recreateMappings(), true);
}
private void recreateMappings()
{
mappings.Clear();
ClearInternal();
SampleControlPoint[] points = samplePoints.Count == 0
? new[] { controlPoints.SamplePointAt(double.MinValue) }
: samplePoints.ToArray();
for (int i = 0; i < points.Length; i++)
{
LifetimeStart = lifetimeStart,
LifetimeEnd = lifetimeEnd
};
AddInternal(drawable);
return drawable;
var samplePoint = points[i];
var lifetimeStart = i > 0 ? samplePoint.Time : double.MinValue;
var lifetimeEnd = i + 1 < points.Length ? points[i + 1].Time : double.MaxValue;
AddInternal(mappings[samplePoint.Time] = new DrumSample(samplePoint)
{
LifetimeStart = lifetimeStart,
LifetimeEnd = lifetimeEnd
});
}
}
public DrumSample SampleAt(double time) => mappings[controlPoints.SamplePointAt(time).Time];
public class DrumSample
public class DrumSample : CompositeDrawable
{
public PausableSkinnableSound Centre;
public PausableSkinnableSound Rim;
public override bool RemoveWhenNotAlive => false;
public PausableSkinnableSound Centre { get; private set; }
public PausableSkinnableSound Rim { get; private set; }
private readonly SampleControlPoint samplePoint;
private Bindable<string> sampleBank;
private BindableNumber<int> sampleVolume;
public DrumSample(SampleControlPoint samplePoint)
{
this.samplePoint = samplePoint;
}
[BackgroundDependencyLoader]
private void load()
{
sampleBank = samplePoint.SampleBankBindable.GetBoundCopy();
sampleBank.BindValueChanged(_ => recreate());
sampleVolume = samplePoint.SampleVolumeBindable.GetBoundCopy();
sampleVolume.BindValueChanged(_ => recreate());
recreate();
}
private void recreate()
{
InternalChildren = new Drawable[]
{
Centre = new PausableSkinnableSound(samplePoint.GetSampleInfo()),
Rim = new PausableSkinnableSound(samplePoint.GetSampleInfo(HitSampleInfo.HIT_CLAP))
};
}
}
}
}

View File

@ -41,9 +41,9 @@ namespace osu.Game.Beatmaps.ControlPoints
/// All sound points.
/// </summary>
[JsonProperty]
public IReadOnlyList<SampleControlPoint> SamplePoints => samplePoints;
public IBindableList<SampleControlPoint> SamplePoints => samplePoints;
private readonly SortedList<SampleControlPoint> samplePoints = new SortedList<SampleControlPoint>(Comparer<SampleControlPoint>.Default);
private readonly BindableList<SampleControlPoint> samplePoints = new BindableList<SampleControlPoint>();
/// <summary>
/// All effect points.