mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 23:15:34 +08:00
Simplify by removing custom enumerator
This commit is contained in:
parent
2dee5e03e3
commit
bbcbd7e3fb
@ -2,9 +2,7 @@
|
|||||||
// 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;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
@ -39,15 +37,10 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
{
|
{
|
||||||
DrawableHitObject blockingObject = null;
|
DrawableHitObject blockingObject = null;
|
||||||
|
|
||||||
using (var enumerator = new HitObjectEnumerator(hitObjectContainer, hitObject.HitObject.StartTime))
|
foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime))
|
||||||
{
|
{
|
||||||
while (enumerator.MoveNext())
|
if (hitObjectCanBlockFutureHits(obj))
|
||||||
{
|
blockingObject = obj;
|
||||||
Debug.Assert(enumerator.Current != null);
|
|
||||||
|
|
||||||
if (hitObjectCanBlockFutureHits(enumerator.Current))
|
|
||||||
blockingObject = enumerator.Current;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no previous hitobject, allow the hit.
|
// If there is no previous hitobject, allow the hit.
|
||||||
@ -77,18 +70,13 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
if (!IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset))
|
if (!IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset))
|
||||||
throw new InvalidOperationException($"A {hitObject} was hit before it become hittable!");
|
throw new InvalidOperationException($"A {hitObject} was hit before it become hittable!");
|
||||||
|
|
||||||
using (var enumerator = new HitObjectEnumerator(hitObjectContainer, hitObject.HitObject.StartTime))
|
foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime))
|
||||||
{
|
{
|
||||||
while (enumerator.MoveNext())
|
if (obj.Judged)
|
||||||
{
|
continue;
|
||||||
Debug.Assert(enumerator.Current != null);
|
|
||||||
|
|
||||||
if (enumerator.Current.Judged)
|
if (hitObjectCanBlockFutureHits(obj))
|
||||||
continue;
|
((DrawableOsuHitObject)obj).MissForcefully();
|
||||||
|
|
||||||
if (hitObjectCanBlockFutureHits(enumerator.Current))
|
|
||||||
((DrawableOsuHitObject)enumerator.Current).MissForcefully();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,90 +87,22 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
private static bool hitObjectCanBlockFutureHits(DrawableHitObject hitObject)
|
private static bool hitObjectCanBlockFutureHits(DrawableHitObject hitObject)
|
||||||
=> hitObject is DrawableHitCircle;
|
=> hitObject is DrawableHitCircle;
|
||||||
|
|
||||||
private struct HitObjectEnumerator : IEnumerator<DrawableHitObject>
|
private IEnumerable<DrawableHitObject> enumerateHitObjectsUpTo(double targetTime)
|
||||||
{
|
{
|
||||||
private readonly IEnumerator<DrawableHitObject> hitObjectEnumerator;
|
foreach (var obj in hitObjectContainer.AliveObjects)
|
||||||
private readonly double targetTime;
|
|
||||||
|
|
||||||
private DrawableHitObject currentTopLevel;
|
|
||||||
private int currentNestedIndex;
|
|
||||||
|
|
||||||
public HitObjectEnumerator(HitObjectContainer hitObjectContainer, double targetTime)
|
|
||||||
{
|
{
|
||||||
hitObjectEnumerator = hitObjectContainer.AliveObjects.GetEnumerator();
|
if (obj.HitObject.StartTime >= targetTime)
|
||||||
this.targetTime = targetTime;
|
yield break;
|
||||||
|
|
||||||
currentTopLevel = null;
|
yield return obj;
|
||||||
currentNestedIndex = -1;
|
|
||||||
Current = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
for (int i = 0; i < obj.NestedHitObjects.Count; i++)
|
||||||
/// Attempts to move to the next top-level or nested hitobject.
|
{
|
||||||
/// Stops when no such hitobject is found or until the hitobject start time reaches <see cref="targetTime"/>.
|
if (obj.NestedHitObjects[i].HitObject.StartTime >= targetTime)
|
||||||
/// </summary>
|
break;
|
||||||
/// <returns>Whether a new hitobject was moved to.</returns>
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
// If we don't already have a top-level hitobject, try to get one.
|
|
||||||
if (currentTopLevel == null)
|
|
||||||
return moveNextTopLevel();
|
|
||||||
|
|
||||||
// If we have a top-level hitobject, try to move to the next nested hitobject or otherwise move to the next top-level hitobject.
|
yield return obj.NestedHitObjects[i];
|
||||||
if (!moveNextNested())
|
}
|
||||||
return moveNextTopLevel();
|
|
||||||
|
|
||||||
// Guaranteed by moveNextNested() to have a hitobject.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to move to the next top-level hitobject.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Whether a new top-level hitobject was found.</returns>
|
|
||||||
private bool moveNextTopLevel()
|
|
||||||
{
|
|
||||||
currentNestedIndex = -1;
|
|
||||||
|
|
||||||
hitObjectEnumerator.MoveNext();
|
|
||||||
currentTopLevel = hitObjectEnumerator.Current;
|
|
||||||
|
|
||||||
Current = currentTopLevel;
|
|
||||||
|
|
||||||
return Current?.HitObject.StartTime < targetTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to move to the next nested hitobject in the current top-level hitobject.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Whether a new nested hitobject was moved to.</returns>
|
|
||||||
private bool moveNextNested()
|
|
||||||
{
|
|
||||||
currentNestedIndex++;
|
|
||||||
if (currentNestedIndex >= currentTopLevel.NestedHitObjects.Count)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Current = currentTopLevel.NestedHitObjects[currentNestedIndex];
|
|
||||||
Debug.Assert(Current != null);
|
|
||||||
|
|
||||||
return Current?.HitObject.StartTime < targetTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
|
||||||
{
|
|
||||||
hitObjectEnumerator.Reset();
|
|
||||||
currentTopLevel = null;
|
|
||||||
currentNestedIndex = -1;
|
|
||||||
Current = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DrawableHitObject Current { get; set; }
|
|
||||||
|
|
||||||
object IEnumerator.Current => Current;
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
hitObjectEnumerator?.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user