mirror of
https://github.com/ppy/osu.git
synced 2025-01-30 03:02:54 +08:00
WIP: use pooling without spliting Hit
into two classes
But there is still problem with Editor. We should to call `ReLoadMainPiece` from Editor to update drawable hit's OR do it somehow else by reaching TaikoPlayfield from Editor. (we should to get `TaikoPlayfield` from Editor in any case: we should to take DrawableHit's somehow)
This commit is contained in:
parent
fa0d2f4af2
commit
45c81aacc4
@ -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
|
||||
{
|
||||
@ -77,9 +77,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
OnNewResult += onNewResult;
|
||||
}
|
||||
|
||||
protected override void RecreatePieces()
|
||||
protected override void RestorePieceState()
|
||||
{
|
||||
base.RecreatePieces();
|
||||
updateColour();
|
||||
Height = HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE;
|
||||
}
|
||||
@ -119,8 +118,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
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;
|
||||
|
||||
@ -174,7 +173,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
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
|
||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
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()
|
||||
{
|
||||
@ -45,9 +45,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
IsFirstTick.Value = HitObject.FirstTick;
|
||||
}
|
||||
|
||||
protected override void RecreatePieces()
|
||||
protected override void RestorePieceState()
|
||||
{
|
||||
base.RecreatePieces();
|
||||
Size = new Vector2(HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
@ -26,6 +28,17 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
{
|
||||
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()
|
||||
@ -33,5 +46,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
@ -55,15 +55,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
{
|
||||
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));
|
||||
type.BindValueChanged(_ => Scheduler.AddOnce(RestorePieceState));
|
||||
|
||||
base.OnApply();
|
||||
}
|
||||
|
||||
protected override void RecreatePieces()
|
||||
protected override void RestorePieceState()
|
||||
{
|
||||
updateActionsFromType();
|
||||
base.RecreatePieces();
|
||||
Size = new Vector2(HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
@ -90,7 +89,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
: 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);
|
||||
|
||||
|
@ -10,16 +10,16 @@ using osu.Framework.Allocation;
|
||||
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
|
||||
{
|
||||
@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
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
|
||||
@ -144,9 +144,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
Origin = Anchor.Centre,
|
||||
});
|
||||
|
||||
protected override void RecreatePieces()
|
||||
protected override void RestorePieceState()
|
||||
{
|
||||
base.RecreatePieces();
|
||||
Size = baseSize = new Vector2(TaikoHitObject.DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
|
||||
public override bool OnPressed(KeyBindingPressEvent<TaikoAction> e) => false;
|
||||
|
||||
protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick),
|
||||
_ => new TickPiece());
|
||||
protected override void RestorePieceState() { }
|
||||
protected override SkinnableDrawable OnLoadCreateMainPiece()
|
||||
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
@ -141,22 +142,31 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var drawable = OnLoadCreateMainPiece();
|
||||
if (drawable is not null)
|
||||
Content.Add(MainPiece = drawable);
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
base.OnApply();
|
||||
|
||||
// TODO: now it fixed, yes?
|
||||
// TODO: THIS CANNOT BE HERE, it makes pooling pointless (see https://github.com/ppy/osu/issues/21072).
|
||||
RecreatePieces();
|
||||
RestorePieceState();
|
||||
}
|
||||
|
||||
protected virtual void RecreatePieces()
|
||||
protected abstract void RestorePieceState();
|
||||
protected abstract SkinnableDrawable OnLoadCreateMainPiece();
|
||||
|
||||
// TODO: call it from Editor OR even delete it and use somehow TaikoPlayfield from Editor
|
||||
public unsafe void ReLoadMainPiece()
|
||||
{
|
||||
if (MainPiece != null)
|
||||
Content.Remove(MainPiece, true);
|
||||
|
||||
Content.Add(MainPiece = CreateMainPiece());
|
||||
Content.Remove(MainPiece, true);
|
||||
load();
|
||||
}
|
||||
|
||||
protected abstract SkinnableDrawable CreateMainPiece();
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
{
|
||||
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));
|
||||
isStrong.BindValueChanged(_ => Scheduler.AddOnce(RestorePieceState));
|
||||
|
||||
base.OnApply();
|
||||
}
|
||||
|
@ -42,6 +42,11 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
||||
SamplesBindable.BindCollectionChanged((_, _) => updateTypeFromSamples());
|
||||
}
|
||||
|
||||
public Hit(HitType type) : this()
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
|
||||
private void updateTypeFromSamples()
|
||||
{
|
||||
Type = getRimSamples().Any() ? HitType.Rim : HitType.Centre;
|
||||
|
23
osu.Game.Rulesets.Taiko/UI/HitPool.cs
Normal file
23
osu.Game.Rulesets.Taiko/UI/HitPool.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// 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.
|
||||
|
||||
using osu.Framework.Graphics.Pooling;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
/// <summary>Pool for hit of a specific HitType.</summary>
|
||||
internal partial class HitPool : DrawablePool<DrawableHit>
|
||||
{
|
||||
private readonly HitType hitType;
|
||||
|
||||
public HitPool(HitType hitType, int initialSize)
|
||||
: base(initialSize)
|
||||
{
|
||||
this.hitType = hitType;
|
||||
}
|
||||
|
||||
protected override DrawableHit CreateNewDrawable() => new DrawableHit(new Hit(hitType));
|
||||
}
|
||||
}
|
@ -7,17 +7,18 @@ using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Pooling;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Taiko.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.UI
|
||||
@ -180,7 +181,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
inputDrum,
|
||||
};
|
||||
|
||||
RegisterPool<Hit, DrawableHit>(50);
|
||||
RegisterPool<Hit.StrongNestedHit, DrawableHit.StrongNestedHit>(50);
|
||||
|
||||
RegisterPool<DrumRoll, DrawableDrumRoll>(5);
|
||||
@ -194,13 +194,31 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
|
||||
var hitWindows = new TaikoHitWindows();
|
||||
|
||||
HitResult[] usableHitResults = Enum.GetValues<HitResult>().Where(r => hitWindows.IsHitResultAllowed(r)).ToArray();
|
||||
HitResult[] usableHitResults = Enum.GetValues<HitResult>().Where(hitWindows.IsHitResultAllowed).ToArray();
|
||||
|
||||
AddInternal(judgementPooler = new JudgementPooler<DrawableTaikoJudgement>(usableHitResults));
|
||||
|
||||
foreach (var result in usableHitResults)
|
||||
explosionPools.Add(result, new HitExplosionPool(result));
|
||||
AddRangeInternal(explosionPools.Values);
|
||||
|
||||
AddRangeInternal(poolsHit.Values);
|
||||
}
|
||||
|
||||
private readonly IDictionary<HitType, HitPool> poolsHit = new Dictionary<HitType, HitPool>()
|
||||
{
|
||||
{HitType.Centre, new HitPool(HitType.Centre, 50)},
|
||||
{HitType.Rim, new HitPool(HitType.Rim, 50)},
|
||||
};
|
||||
protected override IDrawablePool? AdditionalPrepareDrawablePool(HitObject hitObject)
|
||||
{
|
||||
switch (hitObject)
|
||||
{
|
||||
case Hit hit: return poolsHit[hit.Type];
|
||||
// TODO: ???
|
||||
//case Hit.StrongNestedHit hitStrong: return ;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -11,19 +11,19 @@ using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Pooling;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Pooling;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
using osu.Game.Rulesets.Objects.Pooling;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
@ -350,6 +350,8 @@ namespace osu.Game.Rulesets.UI
|
||||
OnHitObjectRemoved(entry.HitObject);
|
||||
}
|
||||
|
||||
protected virtual IDrawablePool AdditionalPrepareDrawablePool(HitObject hitObject) => null;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="HitObjectLifetimeEntry"/> for a given <see cref="HitObject"/>.
|
||||
/// </summary>
|
||||
@ -430,12 +432,13 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
private IDrawablePool prepareDrawableHitObjectPool(HitObject hitObject)
|
||||
{
|
||||
var additional = AdditionalPrepareDrawablePool(hitObject);
|
||||
if (additional is not null) return additional;
|
||||
|
||||
var lookupType = hitObject.GetType();
|
||||
|
||||
IDrawablePool pool;
|
||||
|
||||
// Tests may add derived hitobject instances for which pools don't exist. Try to find any applicable pool and dynamically assign the type if the pool exists.
|
||||
if (!pools.TryGetValue(lookupType, out pool))
|
||||
if (!pools.TryGetValue(lookupType, out var pool))
|
||||
{
|
||||
foreach (var (t, p) in pools)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user