ThornyFFXI/LuAshitacast

Table modified while iterating on it

Closed this issue · 2 comments

Here :

baseTable[newKey] = newSet;

Depending your set layout, it will miss some of the user's _Priority, as the modify a table on which we are currently iterrating.

I got a fix with :

local function shallowcopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in pairs(orig) do
            copy[orig_key] = orig_value
        end
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

local EvaluateLevels = function(baseTable, level)
    for name,set in pairs(shallowcopy(baseTable)) do
        if (#name > 9) and (string.sub(name, -9) == '_Priority') then
            local newSet = {};
            for slotName,slotEntries in pairs(set) do
                if (gData.Constants.EquipSlots[slotName] ~= nil) then
                    if type(slotEntries) == 'string' then
                        newSet[slotName] = slotEntries;
                    elseif type(slotEntries) == 'table' then
                        if slotEntries[1] == nil then
                            newSet[slotName] = slotEntries;
                        else
                            for _,potentialEntry in ipairs(slotEntries) do
                                if EvaluateItem(potentialEntry, level) then
                                    newSet[slotName] = potentialEntry;
                                    break;
                                end
                            end
                        end
                    end
                end
            end
            local newKey = string.sub(name, 1, -10);
            baseTable[newKey] = newSet;
        end
    end
end

You're correct, though I think a shallow copy is unnecessary. Instead, I will store the new values in a table and insert them after iteration is complete. Thank you for the report, this should be fixed in 1.44.

Instead, I will store the new values in a table and insert them after iteration is complete.

Yes that's better :D