mirror of https://github.com/ppy/osu
Add nested osu! hitobject pooling
This commit is contained in:
parent
1ea526b5ef
commit
3f78d81386
|
@ -83,7 +83,7 @@ protected override void OnFree(HitObject hitObject)
|
|||
private OsuInputManager osuActionInputManager;
|
||||
internal OsuInputManager OsuActionInputManager => osuActionInputManager ??= GetContainingInputManager() as OsuInputManager;
|
||||
|
||||
protected virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength);
|
||||
public virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength);
|
||||
|
||||
protected override void UpdateInitialTransforms()
|
||||
{
|
||||
|
|
|
@ -164,10 +164,10 @@ protected override void ClearNestedHitObjects()
|
|||
{
|
||||
base.ClearNestedHitObjects();
|
||||
|
||||
headContainer.Clear();
|
||||
tailContainer.Clear();
|
||||
repeatContainer.Clear();
|
||||
tickContainer.Clear();
|
||||
headContainer.Clear(false);
|
||||
tailContainer.Clear(false);
|
||||
repeatContainer.Clear(false);
|
||||
tickContainer.Clear(false);
|
||||
}
|
||||
|
||||
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||
|
@ -178,17 +178,13 @@ protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
|||
return new DrawableSliderTail(tail);
|
||||
|
||||
case SliderHeadCircle head:
|
||||
return new DrawableSliderHead(HitObject, head)
|
||||
{
|
||||
OnShake = Shake,
|
||||
CheckHittable = (d, t) => CheckHittable?.Invoke(d, t) ?? true
|
||||
};
|
||||
return new DrawableSliderHead(head);
|
||||
|
||||
case SliderTick tick:
|
||||
return new DrawableSliderTick(tick) { Position = tick.Position - HitObject.Position };
|
||||
return new DrawableSliderTick(tick);
|
||||
|
||||
case SliderRepeat repeat:
|
||||
return new DrawableSliderRepeat(repeat, this) { Position = repeat.Position - HitObject.Position };
|
||||
return new DrawableSliderRepeat(repeat);
|
||||
}
|
||||
|
||||
return base.CreateNestedHitObject(hitObject);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
@ -14,21 +16,43 @@ public class DrawableSliderHead : DrawableHitCircle
|
|||
|
||||
protected override OsuSkinComponents CirclePieceComponent => OsuSkinComponents.SliderHeadHitCircle;
|
||||
|
||||
private readonly Slider slider;
|
||||
private DrawableSlider drawableSlider;
|
||||
|
||||
public DrawableSliderHead(Slider slider, SliderHeadCircle h)
|
||||
private Slider slider => drawableSlider?.HitObject;
|
||||
|
||||
public DrawableSliderHead()
|
||||
{
|
||||
}
|
||||
|
||||
public DrawableSliderHead(SliderHeadCircle h)
|
||||
: base(h)
|
||||
{
|
||||
this.slider = slider;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
pathVersion.BindTo(slider.Path.Version);
|
||||
|
||||
PositionBindable.BindValueChanged(_ => updatePosition());
|
||||
pathVersion.BindValueChanged(_ => updatePosition(), true);
|
||||
pathVersion.BindValueChanged(_ => updatePosition());
|
||||
}
|
||||
|
||||
protected override void OnFree(HitObject hitObject)
|
||||
{
|
||||
base.OnFree(hitObject);
|
||||
|
||||
pathVersion.UnbindFrom(drawableSlider.PathVersion);
|
||||
}
|
||||
|
||||
protected override void OnParentReceived(DrawableHitObject parent)
|
||||
{
|
||||
base.OnParentReceived(parent);
|
||||
|
||||
drawableSlider = (DrawableSlider)parent;
|
||||
|
||||
pathVersion.BindTo(drawableSlider.PathVersion);
|
||||
|
||||
OnShake = drawableSlider.Shake;
|
||||
CheckHittable = (d, t) => drawableSlider.CheckHittable?.Invoke(d, t) ?? true;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
|
@ -44,8 +68,12 @@ protected override void Update()
|
|||
|
||||
public Action<double> OnShake;
|
||||
|
||||
protected override void Shake(double maximumLength) => OnShake?.Invoke(maximumLength);
|
||||
public override void Shake(double maximumLength) => OnShake?.Invoke(maximumLength);
|
||||
|
||||
private void updatePosition() => Position = HitObject.Position - slider.Position;
|
||||
private void updatePosition()
|
||||
{
|
||||
if (slider != null)
|
||||
Position = HitObject.Position - slider.Position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||
{
|
||||
public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking
|
||||
{
|
||||
private readonly SliderRepeat sliderRepeat;
|
||||
private readonly DrawableSlider drawableSlider;
|
||||
public new SliderRepeat HitObject => (SliderRepeat)base.HitObject;
|
||||
|
||||
private double animDuration;
|
||||
|
||||
|
@ -27,11 +26,16 @@ public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking
|
|||
|
||||
public override bool DisplayResult => false;
|
||||
|
||||
public DrawableSliderRepeat(SliderRepeat sliderRepeat, DrawableSlider drawableSlider)
|
||||
private DrawableSlider drawableSlider;
|
||||
|
||||
public DrawableSliderRepeat()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public DrawableSliderRepeat(SliderRepeat sliderRepeat)
|
||||
: base(sliderRepeat)
|
||||
{
|
||||
this.sliderRepeat = sliderRepeat;
|
||||
this.drawableSlider = drawableSlider;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
@ -53,18 +57,27 @@ private void load()
|
|||
}
|
||||
};
|
||||
|
||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true);
|
||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
|
||||
}
|
||||
|
||||
protected override void OnParentReceived(DrawableHitObject parent)
|
||||
{
|
||||
base.OnParentReceived(parent);
|
||||
|
||||
drawableSlider = (DrawableSlider)parent;
|
||||
|
||||
Position = HitObject.Position - drawableSlider.Position;
|
||||
}
|
||||
|
||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||
{
|
||||
if (sliderRepeat.StartTime <= Time.Current)
|
||||
if (HitObject.StartTime <= Time.Current)
|
||||
ApplyResult(r => r.Type = drawableSlider.Tracking.Value ? r.Judgement.MaxResult : r.Judgement.MinResult);
|
||||
}
|
||||
|
||||
protected override void UpdateInitialTransforms()
|
||||
{
|
||||
animDuration = Math.Min(300, sliderRepeat.SpanDuration);
|
||||
animDuration = Math.Min(300, HitObject.SpanDuration);
|
||||
|
||||
this.Animate(
|
||||
d => d.FadeIn(animDuration),
|
||||
|
@ -100,7 +113,7 @@ public void UpdateSnakingPosition(Vector2 start, Vector2 end)
|
|||
// When the repeat is hit, the arrow should fade out on spot rather than following the slider
|
||||
if (IsHit) return;
|
||||
|
||||
bool isRepeatAtEnd = sliderRepeat.RepeatIndex % 2 == 0;
|
||||
bool isRepeatAtEnd = HitObject.RepeatIndex % 2 == 0;
|
||||
List<Vector2> curve = ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve;
|
||||
|
||||
Position = isRepeatAtEnd ? end : start;
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||
{
|
||||
public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking, ITrackSnaking
|
||||
{
|
||||
private readonly SliderTailCircle tailCircle;
|
||||
public new SliderTailCircle HitObject => (SliderTailCircle)base.HitObject;
|
||||
|
||||
/// <summary>
|
||||
/// The judgement text is provided by the <see cref="DrawableSlider"/>.
|
||||
|
@ -25,10 +25,14 @@ public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking, ITrack
|
|||
private SkinnableDrawable circlePiece;
|
||||
private Container scaleContainer;
|
||||
|
||||
public DrawableSliderTail()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public DrawableSliderTail(SliderTailCircle tailCircle)
|
||||
: base(tailCircle)
|
||||
{
|
||||
this.tailCircle = tailCircle;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
@ -52,7 +56,7 @@ private void load()
|
|||
},
|
||||
};
|
||||
|
||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true);
|
||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
|
||||
}
|
||||
|
||||
protected override void UpdateInitialTransforms()
|
||||
|
@ -92,6 +96,6 @@ protected override void CheckForResult(bool userTriggered, double timeOffset)
|
|||
}
|
||||
|
||||
public void UpdateSnakingPosition(Vector2 start, Vector2 end) =>
|
||||
Position = tailCircle.RepeatIndex % 2 == 0 ? end : start;
|
||||
Position = HitObject.RepeatIndex % 2 == 0 ? end : start;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,11 @@ public class DrawableSliderTick : DrawableOsuHitObject, IRequireTracking
|
|||
|
||||
private SkinnableDrawable scaleContainer;
|
||||
|
||||
public DrawableSliderTick()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public DrawableSliderTick(SliderTick sliderTick)
|
||||
: base(sliderTick)
|
||||
{
|
||||
|
@ -54,7 +59,14 @@ private void load()
|
|||
Origin = Anchor.Centre,
|
||||
};
|
||||
|
||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true);
|
||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
|
||||
}
|
||||
|
||||
protected override void OnParentReceived(DrawableHitObject parent)
|
||||
{
|
||||
base.OnParentReceived(parent);
|
||||
|
||||
Position = HitObject.Position - ((DrawableSlider)parent).HitObject.Position;
|
||||
}
|
||||
|
||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||
|
|
|
@ -160,7 +160,7 @@ protected override void UpdateHitStateTransforms(ArmedState state)
|
|||
protected override void ClearNestedHitObjects()
|
||||
{
|
||||
base.ClearNestedHitObjects();
|
||||
ticks.Clear();
|
||||
ticks.Clear(false);
|
||||
}
|
||||
|
||||
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||
|
|
|
@ -5,6 +5,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||
{
|
||||
public class DrawableSpinnerBonusTick : DrawableSpinnerTick
|
||||
{
|
||||
public DrawableSpinnerBonusTick()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public DrawableSpinnerBonusTick(SpinnerBonusTick spinnerTick)
|
||||
: base(spinnerTick)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,11 @@ public class DrawableSpinnerTick : DrawableOsuHitObject
|
|||
{
|
||||
public override bool DisplayResult => false;
|
||||
|
||||
public DrawableSpinnerTick()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public DrawableSpinnerTick(SpinnerTick spinnerTick)
|
||||
: base(spinnerTick)
|
||||
{
|
||||
|
|
|
@ -38,8 +38,16 @@ public DrawableOsuRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod>
|
|||
private void load()
|
||||
{
|
||||
registerPool<HitCircle, DrawableHitCircle>(10, 100);
|
||||
|
||||
registerPool<Slider, DrawableSlider>(10, 100);
|
||||
registerPool<SliderHeadCircle, DrawableSliderHead>(10, 100);
|
||||
registerPool<SliderTailCircle, DrawableSliderTail>(10, 100);
|
||||
registerPool<SliderTick, DrawableSliderTick>(10, 100);
|
||||
registerPool<SliderRepeat, DrawableSliderRepeat>(5, 50);
|
||||
|
||||
registerPool<Spinner, DrawableSpinner>(2, 20);
|
||||
registerPool<SpinnerTick, DrawableSpinnerTick>(10, 100);
|
||||
registerPool<SpinnerBonusTick, DrawableSpinnerBonusTick>(10, 100);
|
||||
}
|
||||
|
||||
private void registerPool<TObject, TDrawable>(int initialSize, int? maximumSize = null)
|
||||
|
|
Loading…
Reference in New Issue