Mutagen-Modding / Mutagen

A .NET library for analyzing, creating, and manipulating Bethesda mods
GNU General Public License v3.0
117 stars 32 forks source link

LList Contains key /w sublist and circular support #535

Open Noggog opened 1 month ago

Noggog commented 1 month ago

Add convenience function for checking if an item is on a LList. It should check any refrenced LLists as well, and prevent any circular LList issues.

Pseudocode example:

public bool IsOnLList(ILeveledListGetter list, FormKey formKey)
{
    return IsOnLList(list, formKey, new HashSet<FormKey>());
}

private bool IsOnLList(ILeveledListGetter list, FormKey formKey, HashSet<FormKey> passedLLists)
{
    var passedLLists = new HashSet<FormKey>();
    foreach (var item on list.Entries)
    {
        if (item.FormKey == formKey) 
        {
             // found it
             return true;
        }

        if (item.TryResolve<ILeveledListGetter>(cache, out var subLList)
            // If we've seen it before, skip  (Add will return false if already on the set)
            && passedLLists.Add(item))
        {
             // Look on the other LList
             if (IsOnLList(subLList, formKey, passedLLists)) return true;
        }
    }
}

Another thing to consider is beyond just providing this convenience call, is it might be better to come up with an alternative pattern than just a simple call. For example, if the user is going to check if a LList has several formkeys in a loop, then the same work will be repeated many times. Alternatively, the LList could be processed once into a HashSet up front, and then simple contains calls could be made for each FormKey. We'd have to think of the best way to offer this to the user that would make sense to them