1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-15 02:17:46 +08:00

Merge pull request #27364 from EVAST9919/spinner-alloc

Reduce osu spinner allocations
This commit is contained in:
Dean Herbert 2024-02-25 09:36:02 +08:00 committed by GitHub
commit e8d2abc4f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 36 additions and 10 deletions

View File

@ -279,10 +279,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (HandleUserInput) if (HandleUserInput)
{ {
bool isValidSpinningTime = Time.Current >= HitObject.StartTime && Time.Current <= HitObject.EndTime; bool isValidSpinningTime = Time.Current >= HitObject.StartTime && Time.Current <= HitObject.EndTime;
bool correctButtonPressed = (OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false);
RotationTracker.Tracking = !Result.HasResult RotationTracker.Tracking = !Result.HasResult
&& correctButtonPressed && correctButtonPressed()
&& isValidSpinningTime; && isValidSpinningTime;
} }
@ -292,11 +291,34 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
// Ticks can theoretically be judged at any point in the spinner's duration. // Ticks can theoretically be judged at any point in the spinner's duration.
// A tick must be alive to correctly play back samples, // A tick must be alive to correctly play back samples,
// but for performance reasons, we only want to keep the next tick alive. // but for performance reasons, we only want to keep the next tick alive.
var next = NestedHitObjects.FirstOrDefault(h => !h.Judged); DrawableHitObject nextTick = null;
foreach (var nested in NestedHitObjects)
{
if (!nested.Judged)
{
nextTick = nested;
break;
}
}
// See default `LifetimeStart` as set in `DrawableSpinnerTick`. // See default `LifetimeStart` as set in `DrawableSpinnerTick`.
if (next?.LifetimeStart == double.MaxValue) if (nextTick?.LifetimeStart == double.MaxValue)
next.LifetimeStart = HitObject.StartTime; nextTick.LifetimeStart = HitObject.StartTime;
}
private bool correctButtonPressed()
{
if (OsuActionInputManager == null)
return false;
foreach (var action in OsuActionInputManager.PressedActions)
{
if (action == OsuAction.LeftButton || action == OsuAction.RightButton)
return true;
}
return false;
} }
protected override void UpdateAfterChildren() protected override void UpdateAfterChildren()

View File

@ -2,7 +2,6 @@
// 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 System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Extensions.ObjectExtensions;
@ -33,14 +32,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
drawableSpinner.HitObjectApplied += resetState; drawableSpinner.HitObjectApplied += resetState;
} }
private RotationRecord lastRecord;
public void SetRotation(float currentRotation) public void SetRotation(float currentRotation)
{ {
// If we've gone back in time, it's fine to work with a fresh set of records for now // If we've gone back in time, it's fine to work with a fresh set of records for now
if (records.Count > 0 && Time.Current < records.Last().Time) if (records.Count > 0 && Time.Current < lastRecord.Time)
records.Clear(); records.Clear();
// Never calculate SPM by same time of record to avoid 0 / 0 = NaN or X / 0 = Infinity result. // Never calculate SPM by same time of record to avoid 0 / 0 = NaN or X / 0 = Infinity result.
if (records.Count > 0 && Precision.AlmostEquals(Time.Current, records.Last().Time)) if (records.Count > 0 && Precision.AlmostEquals(Time.Current, lastRecord.Time))
return; return;
if (records.Count > 0) if (records.Count > 0)
@ -52,11 +53,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
result.Value = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; result.Value = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360;
} }
records.Enqueue(new RotationRecord { Rotation = currentRotation, Time = Time.Current }); records.Enqueue(lastRecord = new RotationRecord { Rotation = currentRotation, Time = Time.Current });
} }
private void resetState(DrawableHitObject hitObject) private void resetState(DrawableHitObject hitObject)
{ {
lastRecord = default;
result.Value = 0; result.Value = 0;
records.Clear(); records.Clear();
} }

View File

@ -11,10 +11,12 @@ using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions.ListExtensions;
using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
using osu.Framework.Lists;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Audio; using osu.Game.Audio;
@ -65,7 +67,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
public virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples; public virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples;
private readonly List<DrawableHitObject> nestedHitObjects = new List<DrawableHitObject>(); private readonly List<DrawableHitObject> nestedHitObjects = new List<DrawableHitObject>();
public IReadOnlyList<DrawableHitObject> NestedHitObjects => nestedHitObjects; public SlimReadOnlyListWrapper<DrawableHitObject> NestedHitObjects => nestedHitObjects.AsSlimReadOnly();
/// <summary> /// <summary>
/// Whether this object should handle any user input events. /// Whether this object should handle any user input events.