1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 10:52:53 +08:00

Redirect HitObjectEntryManager child mapping to HOLE

This commit is contained in:
Bartłomiej Dach 2023-07-03 22:33:11 +02:00
parent 2b098bdf61
commit bae7670855
No known key found for this signature in database
2 changed files with 14 additions and 23 deletions

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects
/// <summary> /// <summary>
/// The list of <see cref="HitObjectLifetimeEntry"/> for the <see cref="HitObject"/>'s nested objects (if any). /// The list of <see cref="HitObjectLifetimeEntry"/> for the <see cref="HitObject"/>'s nested objects (if any).
/// </summary> /// </summary>
public readonly List<HitObjectLifetimeEntry> NestedEntries = new List<HitObjectLifetimeEntry>(); public List<HitObjectLifetimeEntry> NestedEntries { get; internal set; } = new List<HitObjectLifetimeEntry>();
/// <summary> /// <summary>
/// The result that <see cref="HitObject"/> was judged with. /// The result that <see cref="HitObject"/> was judged with.

View File

@ -43,11 +43,6 @@ namespace osu.Game.Rulesets.Objects.Pooling
/// </remarks> /// </remarks>
private readonly Dictionary<HitObjectLifetimeEntry, HitObject> parentMap = new Dictionary<HitObjectLifetimeEntry, HitObject>(); private readonly Dictionary<HitObjectLifetimeEntry, HitObject> parentMap = new Dictionary<HitObjectLifetimeEntry, HitObject>();
/// <summary>
/// Stores the list of child entries for each hit object managed by this <see cref="HitObjectEntryManager"/>.
/// </summary>
private readonly Dictionary<HitObject, List<HitObjectLifetimeEntry>> childrenMap = new Dictionary<HitObject, List<HitObjectLifetimeEntry>>();
public void Add(HitObjectLifetimeEntry entry, HitObject? parent) public void Add(HitObjectLifetimeEntry entry, HitObject? parent)
{ {
HitObject hitObject = entry.HitObject; HitObject hitObject = entry.HitObject;
@ -57,14 +52,13 @@ namespace osu.Game.Rulesets.Objects.Pooling
// Add the entry. // Add the entry.
entryMap[hitObject] = entry; entryMap[hitObject] = entry;
childrenMap[hitObject] = new List<HitObjectLifetimeEntry>();
// If the entry has a parent, set it and add the entry to the parent's children. // If the entry has a parent, set it and add the entry to the parent's children.
if (parent != null) if (parent != null)
{ {
parentMap[entry] = parent; parentMap[entry] = parent;
if (childrenMap.TryGetValue(parent, out var parentChildEntries)) if (entryMap.TryGetValue(parent, out var parentEntry))
parentChildEntries.Add(entry); parentEntry.NestedEntries.Add(entry);
} }
hitObject.DefaultsApplied += onDefaultsApplied; hitObject.DefaultsApplied += onDefaultsApplied;
@ -81,15 +75,12 @@ namespace osu.Game.Rulesets.Objects.Pooling
entryMap.Remove(hitObject); entryMap.Remove(hitObject);
// If the entry has a parent, unset it and remove the entry from the parents' children. // If the entry has a parent, unset it and remove the entry from the parents' children.
if (parentMap.Remove(entry, out var parent) && childrenMap.TryGetValue(parent, out var parentChildEntries)) if (parentMap.Remove(entry, out var parent) && entryMap.TryGetValue(parent, out var parentEntry))
parentChildEntries.Remove(entry); parentEntry.NestedEntries.Remove(entry);
// Remove all the entries' children. // Remove all the entries' children.
if (childrenMap.Remove(hitObject, out var childEntries)) foreach (var childEntry in entry.NestedEntries)
{
foreach (var childEntry in childEntries)
Remove(childEntry); Remove(childEntry);
}
hitObject.DefaultsApplied -= onDefaultsApplied; hitObject.DefaultsApplied -= onDefaultsApplied;
OnEntryRemoved?.Invoke(entry, parent); OnEntryRemoved?.Invoke(entry, parent);
@ -105,16 +96,16 @@ namespace osu.Game.Rulesets.Objects.Pooling
/// </summary> /// </summary>
private void onDefaultsApplied(HitObject hitObject) private void onDefaultsApplied(HitObject hitObject)
{ {
if (!childrenMap.Remove(hitObject, out var childEntries)) if (!entryMap.TryGetValue(hitObject, out var entry))
return; return;
// Remove all the entries' children. At this point the parents' (this entries') children list has been removed from the map, so this does not cause upwards traversal. // Replace the entire list rather than clearing to prevent circular traversal later.
foreach (var entry in childEntries) var previousEntries = entry.NestedEntries;
Remove(entry); entry.NestedEntries = new List<HitObjectLifetimeEntry>();
// The removed children list needs to be added back to the map for the entry to potentially receive children. // Remove all the entries' children. At this point the parents' (this entries') children list has been reconstructed, so this does not cause upwards traversal.
childEntries.Clear(); foreach (var nested in previousEntries)
childrenMap[hitObject] = childEntries; Remove(nested);
} }
} }
} }