From bfa6ae1b66eb38c9c77f4f163c3cb0c3b82a98d9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Nov 2020 14:24:17 +0900 Subject: [PATCH 1/2] Fix taiko drum not correct handling sample / group point changes Closes https://github.com/ppy/osu/issues/10642 --- .../Audio/DrumSampleContainer.cs | 79 ++++++++++++++----- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleContainer.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleContainer.cs index fcf7c529f5..fd6eca3850 100644 --- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleContainer.cs +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleContainer.cs @@ -2,6 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +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,9 +21,24 @@ namespace osu.Game.Rulesets.Taiko.Audio private readonly ControlPointInfo controlPoints; private readonly Dictionary mappings = new Dictionary(); + private IBindableList groups; + public DrumSampleContainer(ControlPointInfo controlPoints) { this.controlPoints = controlPoints; + } + + [BackgroundDependencyLoader] + private void load() + { + groups = controlPoints.Groups.GetBoundCopy(); + groups.BindCollectionChanged((_, __) => recreateMappings(), true); + } + + private void recreateMappings() + { + mappings.Clear(); + ClearInternal(); IReadOnlyList samplePoints = controlPoints.SamplePoints.Count == 0 ? new[] { controlPoints.SamplePointAt(double.MinValue) } : controlPoints.SamplePoints; @@ -28,37 +46,56 @@ namespace osu.Game.Rulesets.Taiko.Audio { 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 + AddInternal(mappings[samplePoint.Time] = new DrumSample(samplePoint) { - Centre = addSound(centre, lifetimeStart, lifetimeEnd), - Rim = addSound(rim, lifetimeStart, lifetimeEnd) - }; + LifetimeStart = lifetimeStart, + LifetimeEnd = lifetimeEnd + }); } } - private PausableSkinnableSound addSound(HitSampleInfo hitSampleInfo, double lifetimeStart, double lifetimeEnd) - { - var drawable = new PausableSkinnableSound(hitSampleInfo) - { - LifetimeStart = lifetimeStart, - LifetimeEnd = lifetimeEnd - }; - AddInternal(drawable); - return drawable; - } - 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 sampleBank; + private BindableNumber 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)) + }; + } } } } From 3adf451e8277a8862e2221cda8000acc37938b8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Nov 2020 14:39:01 +0900 Subject: [PATCH 2/2] Handle changes via SamplePoints list for simplicity --- .../Audio/DrumSampleContainer.cs | 17 ++++++++++------- .../Beatmaps/ControlPoints/ControlPointInfo.cs | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleContainer.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleContainer.cs index fd6eca3850..4a3dc58604 100644 --- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleContainer.cs +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleContainer.cs @@ -2,6 +2,7 @@ // 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; @@ -21,7 +22,7 @@ namespace osu.Game.Rulesets.Taiko.Audio private readonly ControlPointInfo controlPoints; private readonly Dictionary mappings = new Dictionary(); - private IBindableList groups; + private IBindableList samplePoints; public DrumSampleContainer(ControlPointInfo controlPoints) { @@ -31,8 +32,8 @@ namespace osu.Game.Rulesets.Taiko.Audio [BackgroundDependencyLoader] private void load() { - groups = controlPoints.Groups.GetBoundCopy(); - groups.BindCollectionChanged((_, __) => recreateMappings(), true); + samplePoints = controlPoints.SamplePoints.GetBoundCopy(); + samplePoints.BindCollectionChanged((_, __) => recreateMappings(), true); } private void recreateMappings() @@ -40,14 +41,16 @@ namespace osu.Game.Rulesets.Taiko.Audio mappings.Clear(); ClearInternal(); - IReadOnlyList samplePoints = controlPoints.SamplePoints.Count == 0 ? new[] { controlPoints.SamplePointAt(double.MinValue) } : controlPoints.SamplePoints; + SampleControlPoint[] points = samplePoints.Count == 0 + ? new[] { controlPoints.SamplePointAt(double.MinValue) } + : samplePoints.ToArray(); - for (int i = 0; i < samplePoints.Count; i++) + for (int i = 0; i < points.Length; i++) { - var samplePoint = samplePoints[i]; + var samplePoint = points[i]; var lifetimeStart = i > 0 ? samplePoint.Time : double.MinValue; - var lifetimeEnd = i + 1 < samplePoints.Count ? samplePoints[i + 1].Time : double.MaxValue; + var lifetimeEnd = i + 1 < points.Length ? points[i + 1].Time : double.MaxValue; AddInternal(mappings[samplePoint.Time] = new DrumSample(samplePoint) { diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs index 22314f28c7..b843aad950 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs @@ -41,9 +41,9 @@ namespace osu.Game.Beatmaps.ControlPoints /// All sound points. /// [JsonProperty] - public IReadOnlyList SamplePoints => samplePoints; + public IBindableList SamplePoints => samplePoints; - private readonly SortedList samplePoints = new SortedList(Comparer.Default); + private readonly BindableList samplePoints = new BindableList(); /// /// All effect points.