1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-13 16:13:34 +08:00

Implement a less failure-prone method

This commit is contained in:
Dan Balasescu 2024-04-11 23:40:40 +09:00
parent bf63ba3f82
commit 19cc847be6
No known key found for this signature in database
2 changed files with 35 additions and 37 deletions

View File

@ -28,9 +28,13 @@ namespace osu.Game.Tests.NonVisual
{
HitObjects =
{
new TestHitObject(),
new TestHitObject { Nested = 1 },
new TestHitObject(),
new TestHitObject { StartTime = 1 },
new TestHitObject
{
StartTime = 2,
Nested = 1
},
new TestHitObject { StartTime = 3 },
}
};
@ -51,10 +55,18 @@ namespace osu.Game.Tests.NonVisual
HitObjects =
{
// The first object is usually skipped in all implementations
new TestHitObject { Skip = true },
new TestHitObject
{
StartTime = 1,
Skip = true
},
// An intermediate skipped object.
new TestHitObject { Skip = true },
new TestHitObject(),
new TestHitObject
{
StartTime = 2,
Skip = true
},
new TestHitObject { StartTime = 3 },
}
};
@ -71,7 +83,12 @@ namespace osu.Game.Tests.NonVisual
{
HitObjects =
{
new TestHitObject { Skip = true, Nested = 2 },
new TestHitObject
{
StartTime = 1,
Skip = true,
Nested = 2
},
}
};
@ -102,7 +119,7 @@ namespace osu.Game.Tests.NonVisual
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
for (int i = 0; i < Nested; i++)
AddNested(new TestHitObject());
AddNested(new TestHitObject { StartTime = StartTime + 0.1 * i });
}
}

View File

@ -108,20 +108,18 @@ namespace osu.Game.Rulesets.Difficulty
var skills = CreateSkills(Beatmap, playableMods, clockRate);
var progressiveBeatmap = new ProgressiveCalculationBeatmap(Beatmap);
// There is a one-to-many relationship between the hitobjects in the beatmap and the "difficulty hitobjects".
// Each iteration of the loop bellow will add at most one hitobject to the progressive beatmap,
// representing the most-parenting hitobject - the hitobject from the original beatmap.
Dictionary<HitObject, HitObject> hitObjectParentLinks =
createHitObjectParentLinks(Beatmap)
.ToDictionary(k => k.obj, k => k.mostParentingObject);
foreach (var hitObject in getDifficultyHitObjects())
{
// Add hitobjects between the original and progressive beatmap until the current hitobject's parent appears in the progressive beatmap.
// This covers cases where hitobjects aren't assigned "difficulty" representations because they don't meaningfully contribute to the calculations.
HitObject parent = hitObjectParentLinks[hitObject.BaseObject];
while (progressiveBeatmap.HitObjects.LastOrDefault() != parent)
progressiveBeatmap.HitObjects.Add(Beatmap.HitObjects[progressiveBeatmap.HitObjects.Count]);
// Implementations expect the progressive beatmap to only contain top-level objects from the original beatmap.
// At the same time, we also need to consider the possibility DHOs may not be generated for any given object,
// so we'll add all remaining objects up to the current point in time to the progressive beatmap.
for (int i = progressiveBeatmap.HitObjects.Count; i < Beatmap.HitObjects.Count; i++)
{
if (Beatmap.HitObjects[i].StartTime > hitObject.BaseObject.StartTime)
break;
progressiveBeatmap.HitObjects.Add(Beatmap.HitObjects[i]);
}
foreach (var skill in skills)
{
@ -133,23 +131,6 @@ namespace osu.Game.Rulesets.Difficulty
}
return attribs;
static IEnumerable<(HitObject obj, HitObject mostParentingObject)> createHitObjectParentLinks(IBeatmap beatmap)
{
foreach (var link in createNestedLinks(beatmap.HitObjects, null))
yield return link;
static IEnumerable<(HitObject obj, HitObject mostParentingObject)> createNestedLinks(IReadOnlyList<HitObject> objects, [CanBeNull] HitObject parent)
{
foreach (var o in objects)
{
yield return (o, parent ?? o);
foreach (var n in createNestedLinks(o.NestedHitObjects, parent ?? o))
yield return n;
}
}
}
}
/// <summary>