1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-16 22:17:19 +08:00

Merge branch 'dho-remove-onparentreceived' into fix-hidden-mod-crash

This commit is contained in:
smoogipoo 2020-12-03 20:10:16 +09:00
commit 09af4bbd57
9 changed files with 46 additions and 60 deletions

@ -6,7 +6,6 @@ using System.Diagnostics;
using JetBrains.Annotations; using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Rulesets.Osu.Objects.Drawables namespace osu.Game.Rulesets.Osu.Objects.Drawables
@ -14,14 +13,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public class DrawableSliderHead : DrawableHitCircle public class DrawableSliderHead : DrawableHitCircle
{ {
[CanBeNull] [CanBeNull]
public Slider Slider => drawableSlider?.HitObject; public Slider Slider => DrawableSlider?.HitObject;
protected DrawableSlider DrawableSlider => (DrawableSlider)ParentHitObject;
private readonly IBindable<int> pathVersion = new Bindable<int>(); private readonly IBindable<int> pathVersion = new Bindable<int>();
protected override OsuSkinComponents CirclePieceComponent => OsuSkinComponents.SliderHeadHitCircle; protected override OsuSkinComponents CirclePieceComponent => OsuSkinComponents.SliderHeadHitCircle;
private DrawableSlider drawableSlider;
public DrawableSliderHead() public DrawableSliderHead()
{ {
} }
@ -42,19 +41,17 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
base.OnFree(); base.OnFree();
pathVersion.UnbindFrom(drawableSlider.PathVersion); pathVersion.UnbindFrom(DrawableSlider.PathVersion);
} }
protected override void OnParentReceived(DrawableHitObject parent) protected override void OnApply()
{ {
base.OnParentReceived(parent); base.OnApply();
drawableSlider = (DrawableSlider)parent; pathVersion.BindTo(DrawableSlider.PathVersion);
pathVersion.BindTo(drawableSlider.PathVersion); OnShake = DrawableSlider.Shake;
CheckHittable = (d, t) => DrawableSlider.CheckHittable?.Invoke(d, t) ?? true;
OnShake = drawableSlider.Shake;
CheckHittable = (d, t) => drawableSlider.CheckHittable?.Invoke(d, t) ?? true;
} }
protected override void Update() protected override void Update()

@ -20,7 +20,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public new SliderRepeat HitObject => (SliderRepeat)base.HitObject; public new SliderRepeat HitObject => (SliderRepeat)base.HitObject;
[CanBeNull] [CanBeNull]
public Slider Slider => drawableSlider?.HitObject; public Slider Slider => DrawableSlider?.HitObject;
protected DrawableSlider DrawableSlider => (DrawableSlider)ParentHitObject;
private double animDuration; private double animDuration;
@ -30,8 +32,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public override bool DisplayResult => false; public override bool DisplayResult => false;
private DrawableSlider drawableSlider;
public DrawableSliderRepeat() public DrawableSliderRepeat()
: base(null) : base(null)
{ {
@ -64,19 +64,17 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue)); ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
} }
protected override void OnParentReceived(DrawableHitObject parent) protected override void OnApply()
{ {
base.OnParentReceived(parent); base.OnApply();
drawableSlider = (DrawableSlider)parent; Position = HitObject.Position - DrawableSlider.Position;
Position = HitObject.Position - drawableSlider.Position;
} }
protected override void CheckForResult(bool userTriggered, double timeOffset) protected override void CheckForResult(bool userTriggered, double timeOffset)
{ {
if (HitObject.StartTime <= Time.Current) if (HitObject.StartTime <= Time.Current)
ApplyResult(r => r.Type = drawableSlider.Tracking.Value ? r.Judgement.MaxResult : r.Judgement.MinResult); ApplyResult(r => r.Type = DrawableSlider.Tracking.Value ? r.Judgement.MaxResult : r.Judgement.MinResult);
} }
protected override void UpdateInitialTransforms() protected override void UpdateInitialTransforms()
@ -118,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (IsHit) return; if (IsHit) return;
bool isRepeatAtEnd = HitObject.RepeatIndex % 2 == 0; bool isRepeatAtEnd = HitObject.RepeatIndex % 2 == 0;
List<Vector2> curve = ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve; List<Vector2> curve = ((PlaySliderBody)DrawableSlider.Body.Drawable).CurrentCurve;
Position = isRepeatAtEnd ? end : start; Position = isRepeatAtEnd ? end : start;

@ -17,7 +17,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public new SliderTailCircle HitObject => (SliderTailCircle)base.HitObject; public new SliderTailCircle HitObject => (SliderTailCircle)base.HitObject;
[CanBeNull] [CanBeNull]
public Slider Slider => drawableSlider?.HitObject; public Slider Slider => DrawableSlider?.HitObject;
protected DrawableSlider DrawableSlider => (DrawableSlider)ParentHitObject;
/// <summary> /// <summary>
/// The judgement text is provided by the <see cref="DrawableSlider"/>. /// The judgement text is provided by the <see cref="DrawableSlider"/>.
@ -26,7 +28,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public bool Tracking { get; set; } public bool Tracking { get; set; }
private DrawableSlider drawableSlider;
private SkinnableDrawable circlePiece; private SkinnableDrawable circlePiece;
private Container scaleContainer; private Container scaleContainer;
@ -64,13 +65,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue)); ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
} }
protected override void OnParentReceived(DrawableHitObject parent)
{
base.OnParentReceived(parent);
drawableSlider = (DrawableSlider)parent;
}
protected override void UpdateInitialTransforms() protected override void UpdateInitialTransforms()
{ {
base.UpdateInitialTransforms(); base.UpdateInitialTransforms();

@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public override bool DisplayResult => false; public override bool DisplayResult => false;
protected DrawableSlider DrawableSlider => (DrawableSlider)ParentHitObject;
private SkinnableDrawable scaleContainer; private SkinnableDrawable scaleContainer;
public DrawableSliderTick() public DrawableSliderTick()
@ -62,11 +64,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue)); ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
} }
protected override void OnParentReceived(DrawableHitObject parent) protected override void OnApply()
{ {
base.OnParentReceived(parent); base.OnApply();
Position = HitObject.Position - ((DrawableSlider)parent).HitObject.Position; Position = HitObject.Position - DrawableSlider.HitObject.Position;
} }
protected override void CheckForResult(bool userTriggered, double timeOffset) protected override void CheckForResult(bool userTriggered, double timeOffset)

@ -1,14 +1,14 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Objects.Drawables namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
public class DrawableSpinnerTick : DrawableOsuHitObject public class DrawableSpinnerTick : DrawableOsuHitObject
{ {
public override bool DisplayResult => false; public override bool DisplayResult => false;
protected DrawableSpinner DrawableSpinner => (DrawableSpinner)ParentHitObject;
public DrawableSpinnerTick() public DrawableSpinnerTick()
: base(null) : base(null)
{ {
@ -19,15 +19,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
} }
private DrawableSpinner drawableSpinner; protected override double MaximumJudgementOffset => DrawableSpinner.HitObject.Duration;
protected override void OnParentReceived(DrawableHitObject parent)
{
base.OnParentReceived(parent);
drawableSpinner = (DrawableSpinner)parent;
}
protected override double MaximumJudgementOffset => drawableSpinner.HitObject.Duration;
/// <summary> /// <summary>
/// Apply a judgement result. /// Apply a judgement result.

@ -43,6 +43,12 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </summary> /// </summary>
public HitObject HitObject { get; private set; } public HitObject HitObject { get; private set; }
/// <summary>
/// The parenting <see cref="DrawableHitObject"/>, if any.
/// </summary>
[CanBeNull]
protected internal DrawableHitObject ParentHitObject { get; internal set; }
/// <summary> /// <summary>
/// The colour used for various elements of this DrawableHitObject. /// The colour used for various elements of this DrawableHitObject.
/// </summary> /// </summary>
@ -230,12 +236,12 @@ namespace osu.Game.Rulesets.Objects.Drawables
foreach (var h in HitObject.NestedHitObjects) foreach (var h in HitObject.NestedHitObjects)
{ {
var pooledDrawableNested = pooledObjectProvider?.GetPooledDrawableRepresentation(h); var pooledDrawableNested = pooledObjectProvider?.GetPooledDrawableRepresentation(h, this);
var drawableNested = pooledDrawableNested var drawableNested = pooledDrawableNested
?? CreateNestedHitObject(h) ?? CreateNestedHitObject(h)
?? throw new InvalidOperationException($"{nameof(CreateNestedHitObject)} returned null for {h.GetType().ReadableName()}."); ?? throw new InvalidOperationException($"{nameof(CreateNestedHitObject)} returned null for {h.GetType().ReadableName()}.");
// Invoke the event only if this nested object is just created by `CreateNestedHitObject`. // Only invoke the event for non-pooled DHOs, otherwise the event will be fired by the playfield.
if (pooledDrawableNested == null) if (pooledDrawableNested == null)
OnNestedDrawableCreated?.Invoke(drawableNested); OnNestedDrawableCreated?.Invoke(drawableNested);
@ -243,10 +249,12 @@ namespace osu.Game.Rulesets.Objects.Drawables
drawableNested.OnRevertResult += onRevertResult; drawableNested.OnRevertResult += onRevertResult;
drawableNested.ApplyCustomUpdateState += onApplyCustomUpdateState; drawableNested.ApplyCustomUpdateState += onApplyCustomUpdateState;
// This is only necessary for non-pooled DHOs. For pooled DHOs, this is handled inside GetPooledDrawableRepresentation().
// Must be done before the nested DHO is added to occur before the nested Apply()!
drawableNested.ParentHitObject = this;
nestedHitObjects.Value.Add(drawableNested); nestedHitObjects.Value.Add(drawableNested);
AddNestedHitObject(drawableNested); AddNestedHitObject(drawableNested);
drawableNested.OnParentReceived(this);
} }
StartTimeBindable.BindTo(HitObject.StartTimeBindable); StartTimeBindable.BindTo(HitObject.StartTimeBindable);
@ -315,6 +323,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
OnFree(); OnFree();
HitObject = null; HitObject = null;
ParentHitObject = null;
Result = null; Result = null;
lifetimeEntry = null; lifetimeEntry = null;
@ -348,14 +357,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
{ {
} }
/// <summary>
/// Invoked when this <see cref="DrawableHitObject"/> receives a new parenting <see cref="DrawableHitObject"/>.
/// </summary>
/// <param name="parent">The parenting <see cref="DrawableHitObject"/>.</param>
protected virtual void OnParentReceived(DrawableHitObject parent)
{
}
/// <summary> /// <summary>
/// Invoked by the base <see cref="DrawableHitObject"/> to populate samples, once on initial load and potentially again on any change to the samples collection. /// Invoked by the base <see cref="DrawableHitObject"/> to populate samples, once on initial load and potentially again on any change to the samples collection.
/// </summary> /// </summary>

@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.UI
{ {
Debug.Assert(!drawableMap.ContainsKey(entry)); Debug.Assert(!drawableMap.ContainsKey(entry));
var drawable = pooledObjectProvider?.GetPooledDrawableRepresentation(entry.HitObject); var drawable = pooledObjectProvider?.GetPooledDrawableRepresentation(entry.HitObject, null);
if (drawable == null) if (drawable == null)
throw new InvalidOperationException($"A drawable representation could not be retrieved for hitobject type: {entry.HitObject.GetType().ReadableName()}."); throw new InvalidOperationException($"A drawable representation could not be retrieved for hitobject type: {entry.HitObject.GetType().ReadableName()}.");

@ -13,8 +13,9 @@ namespace osu.Game.Rulesets.UI
/// Attempts to retrieve the poolable <see cref="DrawableHitObject"/> representation of a <see cref="HitObject"/>. /// Attempts to retrieve the poolable <see cref="DrawableHitObject"/> representation of a <see cref="HitObject"/>.
/// </summary> /// </summary>
/// <param name="hitObject">The <see cref="HitObject"/> to retrieve the <see cref="DrawableHitObject"/> representation of.</param> /// <param name="hitObject">The <see cref="HitObject"/> to retrieve the <see cref="DrawableHitObject"/> representation of.</param>
/// <param name="parent">The parenting <see cref="DrawableHitObject"/>, if any.</param>
/// <returns>The <see cref="DrawableHitObject"/> representing <see cref="HitObject"/>, or <c>null</c> if no poolable representation exists.</returns> /// <returns>The <see cref="DrawableHitObject"/> representing <see cref="HitObject"/>, or <c>null</c> if no poolable representation exists.</returns>
[CanBeNull] [CanBeNull]
DrawableHitObject GetPooledDrawableRepresentation([NotNull] HitObject hitObject); DrawableHitObject GetPooledDrawableRepresentation([NotNull] HitObject hitObject, [CanBeNull] DrawableHitObject parent);
} }
} }

@ -323,7 +323,7 @@ namespace osu.Game.Rulesets.UI
AddInternal(pool); AddInternal(pool);
} }
DrawableHitObject IPooledHitObjectProvider.GetPooledDrawableRepresentation(HitObject hitObject) DrawableHitObject IPooledHitObjectProvider.GetPooledDrawableRepresentation(HitObject hitObject, DrawableHitObject parent)
{ {
var lookupType = hitObject.GetType(); var lookupType = hitObject.GetType();
@ -359,6 +359,7 @@ namespace osu.Game.Rulesets.UI
if (!lifetimeEntryMap.TryGetValue(hitObject, out var entry)) if (!lifetimeEntryMap.TryGetValue(hitObject, out var entry))
lifetimeEntryMap[hitObject] = entry = CreateLifetimeEntry(hitObject); lifetimeEntryMap[hitObject] = entry = CreateLifetimeEntry(hitObject);
dho.ParentHitObject = parent;
dho.Apply(hitObject, entry); dho.Apply(hitObject, entry);
}); });
} }