// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; using JetBrains.Annotations; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Audio; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osuTK; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public abstract class DrawableTaikoStrongableHitObject : DrawableTaikoHitObject where TObject : TaikoStrongableHitObject where TStrongNestedObject : StrongNestedHitObject { private readonly Bindable isStrong = new BindableBool(); private readonly Container strongHitContainer; protected DrawableTaikoStrongableHitObject([CanBeNull] TObject hitObject) : base(hitObject) { AddInternal(strongHitContainer = new Container()); } protected override void OnApply() { isStrong.BindTo(HitObject.IsStrongBindable); isStrong.BindValueChanged(_ => { // will overwrite samples, should only be called on subsequent changes // after the initial application. updateSamplesFromStrong(); RecreatePieces(); }); base.OnApply(); } protected override void OnFree() { base.OnFree(); isStrong.UnbindFrom(HitObject.IsStrongBindable); // ensure the next application does not accidentally overwrite samples. isStrong.UnbindEvents(); } private HitSampleInfo[] getStrongSamples() => HitObject.Samples.Where(s => s.Name == HitSampleInfo.HIT_FINISH).ToArray(); protected override void LoadSamples() { base.LoadSamples(); isStrong.Value = getStrongSamples().Any(); } private void updateSamplesFromStrong() { var strongSamples = getStrongSamples(); if (isStrong.Value != strongSamples.Any()) { if (isStrong.Value) HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_FINISH)); else { foreach (var sample in strongSamples) HitObject.Samples.Remove(sample); } } } protected override void RecreatePieces() { base.RecreatePieces(); if (HitObject.IsStrong) Size = BaseSize = new Vector2(TaikoStrongableHitObject.DEFAULT_STRONG_SIZE); } protected override void AddNestedHitObject(DrawableHitObject hitObject) { base.AddNestedHitObject(hitObject); switch (hitObject) { case DrawableStrongNestedHit strong: strongHitContainer.Add(strong); break; } } protected override void ClearNestedHitObjects() { base.ClearNestedHitObjects(); strongHitContainer.Clear(false); } protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject) { switch (hitObject) { case TStrongNestedObject strong: return CreateStrongNestedHit(strong); } return base.CreateNestedHitObject(hitObject); } /// /// Creates the handler for this 's . /// This is only invoked if is true for . /// /// The strong hitobject. /// The strong hitobject handler. protected abstract DrawableStrongNestedHit CreateStrongNestedHit(TStrongNestedObject hitObject); } }