Skip to content

Commit 0baf967

Browse files
committed
handle unprotected state mutation in power report
1 parent 95fde4e commit 0baf967

1 file changed

Lines changed: 61 additions & 51 deletions

File tree

src/Classes/CompareTab.lua

Lines changed: 61 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,30 +2657,35 @@ function CompareTabClass:ComparePowerBuilder(compareEntry, powerStat, categories
26572657
t_insert(pGroups, cGroup)
26582658
self.primaryBuild.buildFlag = true
26592659

2660-
-- Get a fresh calculator with the added group
2661-
local gemCalcFunc, gemCalcBase = self.calcs.getMiscCalculator(self.primaryBuild)
2662-
local impact = self:CalculatePowerStat(powerStat, gemCalcBase, calcBase)
2660+
-- Get a fresh calculator with the added group (pcall to guarantee cleanup)
2661+
local ok, gemCalcFunc, gemCalcBase = pcall(self.calcs.getMiscCalculator, self.calcs, self.primaryBuild)
26632662

2664-
-- Remove the temporarily added group
2663+
-- Always remove the temporarily added group
26652664
t_remove(pGroups)
26662665
self.primaryBuild.buildFlag = true
26672666

2668-
local impactStr, impactVal, combinedImpactStr, impactPercent = formatImpact(impact)
2669-
local label = self:GetSocketGroupLabel(cGroup)
2667+
if not ok then
2668+
-- gemCalcFunc contains the error message on failure; skip this group
2669+
ConPrintf("Compare power (gem): %s", tostring(gemCalcFunc))
2670+
else
2671+
local impact = self:CalculatePowerStat(powerStat, gemCalcBase, calcBase)
2672+
local impactStr, impactVal, combinedImpactStr, impactPercent = formatImpact(impact)
2673+
local label = self:GetSocketGroupLabel(cGroup)
26702674

2671-
t_insert(results, {
2672-
category = "Gem",
2673-
categoryColor = colorCodes.GEM,
2674-
nameColor = colorCodes.GEM,
2675-
name = label,
2676-
impact = impactVal,
2677-
impactStr = impactStr,
2678-
impactPercent = impactPercent,
2679-
combinedImpactStr = combinedImpactStr,
2680-
pathDist = nil,
2681-
perPoint = nil,
2682-
perPointStr = nil,
2683-
})
2675+
t_insert(results, {
2676+
category = "Gem",
2677+
categoryColor = colorCodes.GEM,
2678+
nameColor = colorCodes.GEM,
2679+
name = label,
2680+
impact = impactVal,
2681+
impactStr = impactStr,
2682+
impactPercent = impactPercent,
2683+
combinedImpactStr = combinedImpactStr,
2684+
pathDist = nil,
2685+
perPoint = nil,
2686+
perPointStr = nil,
2687+
})
2688+
end
26842689
end
26852690
processed = processed + 1
26862691
if coroutine.running() and GetTime() - start > 100 then
@@ -2715,43 +2720,48 @@ function CompareTabClass:ComparePowerBuilder(compareEntry, powerStat, categories
27152720
-- Apply compare build's config value
27162721
pInput[varData.var] = cVal
27172722

2718-
-- Rebuild the mod list with the new config value
2719-
self.primaryBuild.configTab:BuildModList()
2720-
self.primaryBuild.buildFlag = true
2721-
2722-
-- Get a fresh calculator with the changed config
2723-
local cfgCalcFunc, cfgCalcBase = self.calcs.getMiscCalculator(self.primaryBuild)
2724-
local impact = self:CalculatePowerStat(powerStat, cfgCalcBase, calcBase)
2723+
-- Rebuild and calculate (pcall to guarantee restore on error)
2724+
local ok, cfgCalcFunc, cfgCalcBase = pcall(function()
2725+
self.primaryBuild.configTab:BuildModList()
2726+
self.primaryBuild.buildFlag = true
2727+
return self.calcs.getMiscCalculator(self.primaryBuild)
2728+
end)
27252729

2726-
-- Restore original value
2730+
-- Always restore original value
27272731
pInput[varData.var] = savedVal
27282732
self.primaryBuild.configTab:BuildModList()
27292733
self.primaryBuild.buildFlag = true
27302734

2731-
local impactStr, impactVal, combinedImpactStr, impactPercent = formatImpact(impact)
2732-
2733-
-- Only include configs with non-zero impact
2734-
if impactVal ~= 0 then
2735-
-- Build display name with value change description
2736-
local displayName = varData.label or varData.var
2737-
displayName = displayName:gsub(":$", "")
2738-
2739-
local pDisplay = stripColors(self:FormatConfigValue(varData, pVal))
2740-
local cDisplay = stripColors(self:FormatConfigValue(varData, cVal))
2741-
2742-
t_insert(results, {
2743-
category = "Config",
2744-
categoryColor = colorCodes.FRACTURED,
2745-
nameColor = "^7",
2746-
name = displayName .. " (" .. pDisplay .. " -> " .. cDisplay .. ")",
2747-
impact = impactVal,
2748-
impactStr = impactStr,
2749-
impactPercent = impactPercent,
2750-
combinedImpactStr = combinedImpactStr,
2751-
pathDist = nil,
2752-
perPoint = nil,
2753-
perPointStr = nil,
2754-
})
2735+
if not ok then
2736+
-- cfgCalcFunc contains the error message on failure; skip this config
2737+
ConPrintf("Compare power (config): %s", tostring(cfgCalcFunc))
2738+
else
2739+
local impact = self:CalculatePowerStat(powerStat, cfgCalcBase, calcBase)
2740+
local impactStr, impactVal, combinedImpactStr, impactPercent = formatImpact(impact)
2741+
2742+
-- Only include configs with non-zero impact
2743+
if impactVal ~= 0 then
2744+
-- Build display name with value change description
2745+
local displayName = varData.label or varData.var
2746+
displayName = displayName:gsub(":$", "")
2747+
2748+
local pDisplay = stripColors(self:FormatConfigValue(varData, pVal))
2749+
local cDisplay = stripColors(self:FormatConfigValue(varData, cVal))
2750+
2751+
t_insert(results, {
2752+
category = "Config",
2753+
categoryColor = colorCodes.FRACTURED,
2754+
nameColor = "^7",
2755+
name = displayName .. " (" .. pDisplay .. " -> " .. cDisplay .. ")",
2756+
impact = impactVal,
2757+
impactStr = impactStr,
2758+
impactPercent = impactPercent,
2759+
combinedImpactStr = combinedImpactStr,
2760+
pathDist = nil,
2761+
perPoint = nil,
2762+
perPointStr = nil,
2763+
})
2764+
end
27552765
end
27562766

27572767
processed = processed + 1

0 commit comments

Comments
 (0)