Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

osu!taiko Hit & KiaiHitExplosion pooling #31297

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions osu.Game.Rulesets.Taiko/Edit/TaikoEditorPlayfield.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Pooling;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Skinning;

Expand All @@ -20,6 +24,24 @@ private void load()
Anchor = Anchor.TopLeft,
Origin = Anchor.TopRight,
});

AddRangeInternal([poolHitEditorMode]);
}

/// <summary>
/// <see cref="Hit"/> to <see cref="DrawableHit"/> pool that
/// returns <see cref="DrawableHit"/> in editor mode (it will recreates its drawable hierarchy each <c>OnApply</c>).
/// </summary>
private readonly HitPool poolHitEditorMode = new HitPool(50, editorMode: true);

protected override IDrawablePool? PropertyBasedDrawableHitObjectPool(HitObject hitObject)
{
switch (hitObject)
{
// We should to return the editor pool, and suppress non-editor pools.
case Hit: return poolHitEditorMode;
default: return null;
}
}
}
}
7 changes: 4 additions & 3 deletions osu.Game.Rulesets.Taiko/Edit/TaikoSelectionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,15 @@ public void SetStrongState(bool state)

public void SetRimState(bool state)
{
if (SelectedItems.OfType<Hit>().All(h => h.Type == (state ? HitType.Rim : HitType.Centre)))
var expectedType = state ? HitType.Rim : HitType.Centre;
if (SelectedItems.OfType<Hit>().All(h => h.Type == expectedType))
return;

EditorBeatmap.PerformOnSelection(h =>
{
if (h is Hit taikoHit)
if (h is Hit taikoHit && taikoHit.Type != expectedType)
{
taikoHit.Type = state ? HitType.Rim : HitType.Centre;
taikoHit.Type = expectedType;
EditorBeatmap.Update(h);
}
});
Expand Down
18 changes: 9 additions & 9 deletions osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
using System;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
Expand Down Expand Up @@ -77,9 +77,9 @@ protected override void LoadComplete()
OnNewResult += onNewResult;
}

protected override void RecreatePieces()
protected override void OnApply()
{
base.RecreatePieces();
base.OnApply();
updateColour();
Height = HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE;
}
Expand Down Expand Up @@ -119,8 +119,8 @@ protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
return base.CreateNestedHitObject(hitObject);
}

protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollBody),
_ => new ElongatedCirclePiece());
protected override SkinnableDrawable OnLoadCreateMainPiece()
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollBody), _ => new ElongatedCirclePiece());

public override bool OnPressed(KeyBindingPressEvent<TaikoAction> e) => false;

Expand Down Expand Up @@ -174,7 +174,7 @@ protected override void Update()
private void updateColour(double fadeDuration = 0)
{
Color4 newColour = Interpolation.ValueAt((float)rollingHits / rolling_hits_for_engaged_colour, colourIdle, colourEngaged, 0, 1);
(MainPiece.Drawable as IHasAccentColour)?.FadeAccent(newColour, fadeDuration);
(MainPiece?.Drawable as IHasAccentColour)?.FadeAccent(newColour, fadeDuration);
}

public partial class StrongNestedHit : DrawableStrongNestedHit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,13 @@ public DrawableDrumRollTick([CanBeNull] DrumRollTick tick)
FillMode = FillMode.Fit;
}

protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece());
protected override SkinnableDrawable OnLoadCreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece());

protected override void OnApply()
{
base.OnApply();

IsFirstTick.Value = HitObject.FirstTick;
}

protected override void RecreatePieces()
{
base.RecreatePieces();
Size = new Vector2(HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
}

Expand Down
17 changes: 17 additions & 0 deletions osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Skinning;

namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
Expand All @@ -26,12 +28,27 @@ protected override void LoadComplete()
{
base.LoadComplete();
ApplyMaxResult();
Size = new osuTK.Vector2(0.3f);
}

private static float degree = 0f;
protected override void PrepareForUse()
{
const float single_rotation_degree = 7f;

base.PrepareForUse();
degree = (degree + single_rotation_degree) % 360f;
Rotation = degree;
}

protected override void LoadSamples()
{
// block base call - flying hits are not supposed to play samples
// the base call could overwrite the type of this hit
}

// TODO: which skin use?
protected override SkinnableDrawable? OnLoadCreateMainPiece()
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell), _ => new SwellCirclePiece(), confineMode: ConfineMode.ScaleToFit);
}
}
22 changes: 12 additions & 10 deletions osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,32 @@ public TaikoAction? HitAction

private readonly Bindable<HitType> type = new Bindable<HitType>();

private readonly bool editorMode = false;

public DrawableHit()
: this(null)
{
}

public DrawableHit([CanBeNull] Hit hit)
public DrawableHit([CanBeNull] Hit hit, bool editorMode = false)
: base(hit)
{
FillMode = FillMode.Fit;
this.editorMode = editorMode;
}

protected override void OnApply()
{
base.OnApply(); // it's empty actually
type.BindTo(HitObject.TypeBindable);
// this doesn't need to be run inline as RecreatePieces is called by the base call below.
type.BindValueChanged(_ => Scheduler.AddOnce(RecreatePieces));

base.OnApply();
}

protected override void RecreatePieces()
{
if (editorMode)
{
// We in Editor Mode so the performance is not critical and we can recreate piece.
if (MainPiece != null) Content.Remove(MainPiece, true);
Content.Add(MainPiece = OnLoadCreateMainPiece());
}
updateActionsFromType();
base.RecreatePieces();
Size = new Vector2(HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
}

Expand All @@ -90,7 +92,7 @@ private void updateActionsFromType()
: new[] { TaikoAction.LeftRim, TaikoAction.RightRim };
}

protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre
protected override SkinnableDrawable OnLoadCreateMainPiece() => HitObject.Type == HitType.Centre
? new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit)
: new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);

Expand Down
12 changes: 6 additions & 6 deletions osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Screens.Play;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
Expand Down Expand Up @@ -136,17 +136,17 @@ private void load(OsuColour colours)
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
}

protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell),
protected override SkinnableDrawable OnLoadCreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell),
_ => new SwellCirclePiece
{
// to allow for rotation transform
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
});

protected override void RecreatePieces()
protected override void OnApply()
{
base.RecreatePieces();
base.OnApply();
Size = baseSize = new Vector2(TaikoHitObject.DEFAULT_SIZE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected override void CheckForResult(bool userTriggered, double timeOffset)

public override bool OnPressed(KeyBindingPressEvent<TaikoAction> e) => false;

protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick),
_ => new TickPiece());
protected override SkinnableDrawable OnLoadCreateMainPiece()
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
Expand Down Expand Up @@ -71,7 +72,7 @@ protected void ProxyContent()

/// <summary>
/// Moves <see cref="Content"/> to the normal hitobject layer.
/// Does nothing is content is not currently proxied.
/// Does nothing if content is not currently proxied.
/// </summary>
protected void UnproxyContent()
{
Expand Down Expand Up @@ -141,22 +142,15 @@ protected DrawableTaikoHitObject([CanBeNull] TObject hitObject)
RelativeSizeAxes = Axes.Both;
}

protected override void OnApply()
[BackgroundDependencyLoader]
private void load()
{
base.OnApply();

// TODO: THIS CANNOT BE HERE, it makes pooling pointless (see https://github.com/ppy/osu/issues/21072).
RecreatePieces();
}

protected virtual void RecreatePieces()
{
if (MainPiece != null)
Content.Remove(MainPiece, true);

Content.Add(MainPiece = CreateMainPiece());
var drawable = OnLoadCreateMainPiece();
if (drawable is not null)
Content.Add(MainPiece = drawable);
}

protected abstract SkinnableDrawable CreateMainPiece();
/// <summary>Creates <c>MainPiece</c>. Calls only on <c>load</c> or in EditorMode.</summary>
protected abstract SkinnableDrawable OnLoadCreateMainPiece();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ protected DrawableTaikoStrongableHitObject([CanBeNull] TObject hitObject)

protected override void OnApply()
{
isStrong.BindTo(HitObject.IsStrongBindable);
// this doesn't need to be run inline as RecreatePieces is called by the base call below.
isStrong.BindValueChanged(_ => Scheduler.AddOnce(RecreatePieces));

base.OnApply();
isStrong.BindTo(HitObject.IsStrongBindable);
}

protected override void OnFree()
Expand Down
6 changes: 6 additions & 0 deletions osu.Game.Rulesets.Taiko/Objects/Hit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public Hit()
SamplesBindable.BindCollectionChanged((_, _) => updateTypeFromSamples());
}

public Hit(HitType type, bool isStroing) : this()
{
IsStrong = isStroing;
Type = type;
}

private void updateTypeFromSamples()
{
Type = getRimSamples().Any() ? HitType.Rim : HitType.Centre;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.UI;
using osuTK;

namespace osu.Game.Rulesets.Taiko.Skinning.Default
{
public partial class DefaultKiaiHitExplosion : CircularContainer
public partial class DefaultKiaiHitExplosion : CircularContainer, IAnimatableHitExplosion
{
public override bool RemoveWhenNotAlive => true;

Expand Down Expand Up @@ -51,14 +53,16 @@ private void load(OsuColour colours)
};
}

protected override void LoadComplete()
public void Animate(DrawableHitObject _drawableHitObject)
{
base.LoadComplete();

this.ScaleTo(new Vector2(1, 3f), 500, Easing.OutQuint);
this.FadeOut(250);
}

Expire(true);
public void AnimateSecondHit()
{
this.ScaleTo(new Vector2(TaikoStrongableHitObject.STRONG_SCALE, 3f), 500, Easing.OutQuint);
this.FadeOut(250);
}
}
}
Loading