Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions spec/System/TestPowerReport_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,136 @@ describe("PowerReportListControl", function()
assert.are.equal("allocated", list[1].name)
end)
end)

describe("Power report cluster calculations", function()
local calcsTab, originalCalculator, originalTime, originalProgress, originalComplete
local clusterNodes, clusterCalls, hitDPS

before_each(function()
newBuild()
runCallback("OnFrame")
calcsTab = build.calcsTab
calcsTab.nodePowerMaxDepth = 1
originalCalculator = calcsTab.miscCalculator[1]
originalTime = GetTime
originalProgress = build.powerBuilderProgressCallback
originalComplete = build.powerBuilderCallback
clusterNodes = { }
clusterCalls = 0
for _, node in pairs(build.spec.tree.clusterNodeMap) do
clusterNodes[node] = true
end
for _, stat in ipairs(data.powerStatList) do
if stat.stat == "TotalDPS" then
hitDPS = stat
break
end
end
calcsTab.miscCalculator[1] = function(mod, ...)
for node in pairs(mod.addNodes or { }) do
if clusterNodes[node] then
clusterCalls = clusterCalls + 1
break
end
end
return originalCalculator(mod, ...)
end
end)

after_each(function()
calcsTab.miscCalculator[1] = originalCalculator
_G.GetTime = originalTime
build.powerBuilderProgressCallback = originalProgress
build.powerBuilderCallback = originalComplete
calcsTab.powerBuilder = nil
calcsTab.powerBuildFlag = false
build.treeTab.viewer.showHeatMap = false
end)

it("skips cluster calculations for Offence/Defence while initializing power tables", function()
calcsTab.powerStat = data.powerStatList[1]
calcsTab:PowerBuilder()
assert.are.equal(0, clusterCalls)
assert.is_not_nil(next(clusterNodes))
for node in pairs(clusterNodes) do
assert.same({ }, node.power)
end
end)

it("clears Hit DPS cluster values in Offence/Defence and restores them on returning", function()
calcsTab.powerStat = hitDPS
calcsTab:PowerBuilder()
assert.is_true(clusterCalls > 0)
local initialCalls = clusterCalls
local initialPowers = { }
for node in pairs(clusterNodes) do
initialPowers[node] = copyTable(node.power)
if not node.alloc and node.modKey ~= "" and not calcsTab.mainEnv.grantedPassives[node.id] then
assert.is_number(node.power.singleStat)
end
end

clusterCalls = 0
calcsTab.powerStat = data.powerStatList[1]
calcsTab:PowerBuilder()
assert.are.equal(0, clusterCalls)
for node in pairs(clusterNodes) do
assert.same({ }, node.power)
end

calcsTab.powerStat = hitDPS
calcsTab:PowerBuilder()
assert.are.equal(initialCalls, clusterCalls)
for node in pairs(clusterNodes) do
assert.same(initialPowers[node], node.power)
end
end)

it("reports progress and completes only the replacement after a metric switch", function()
local clock = 0
_G.GetTime = function()
clock = clock + 101
return clock
end
-- Exercise real traversal and coroutine scheduling without repeating the stat calculations.
calcsTab.miscCalculator[1] = function()
return calcsTab.miscCalculator[2]
end
local progress = { }
local completions = 0
build.powerBuilderProgressCallback = function(percent)
assert.is_true(percent >= 0 and percent <= 100)
assert.is_true(percent >= (progress[#progress] or 0))
table.insert(progress, percent)
end
build.powerBuilderCallback = function()
completions = completions + 1
originalComplete()
end

build.treeTab:SetPowerCalc(hitDPS)
calcsTab:BuildPower()
local abandonedBuilder = calcsTab.powerBuilder
calcsTab:BuildPower()
assert.is_true(#progress > 0)
assert.are.equal(0, completions)
build.treeTab:SetPowerCalc(data.powerStatList[1])
assert.same({ }, build.treeTab.controls.powerReportList.originalList)
progress = { }
calcsTab:BuildPower()
assert.is_not.equal(abandonedBuilder, calcsTab.powerBuilder)
for _ = 1, 10000 do
if not calcsTab.powerBuilder then
break
end
calcsTab:BuildPower()
end
assert.is_nil(calcsTab.powerBuilder)
assert.is_true(#progress > 0)
assert.are.equal(1, completions)
assert.same({ }, build.treeTab.controls.powerReportList.originalList)
assert.are.equal("suspended", coroutine.status(abandonedBuilder))
calcsTab:BuildPower()
assert.are.equal(1, completions)
end)
end)
15 changes: 8 additions & 7 deletions src/Classes/CalcsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ end
function CalcsTabClass:PowerBuilder()
-- local timer_start = GetTime()
local useFullDPS = self.powerStat and self.powerStat.stat == "FullDPS"
local useClusterPower = self.powerStat and self.powerStat.stat and not self.powerStat.ignoreForNodes
local calcFunc, calcBase = self:GetMiscCalculator()
local cache = { }
local distanceMap = { }
Expand Down Expand Up @@ -597,9 +598,11 @@ function CalcsTabClass:PowerBuilder()
distanceMap = nil
table.sort(distanceList, function(a, b) return a[1] < b[1] end)
-- Count eligible cluster nodes
for _, node in pairs(self.build.spec.tree.clusterNodeMap) do
if not node.alloc and node.modKey ~= "" and not self.mainEnv.grantedPassives[node.id] then
total = total + 1
if useClusterPower then
for _, node in pairs(self.build.spec.tree.clusterNodeMap) do
if not node.alloc and node.modKey ~= "" and not self.mainEnv.grantedPassives[node.id] then
total = total + 1
end
end
end

Expand Down Expand Up @@ -716,14 +719,12 @@ function CalcsTabClass:PowerBuilder()
node.power = {}
end
wipeTable(node.power)
if not node.alloc and node.modKey ~= "" and not self.mainEnv.grantedPassives[node.id] then
if useClusterPower and not node.alloc and node.modKey ~= "" and not self.mainEnv.grantedPassives[node.id] then
if not cache[node.modKey] then
cache[node.modKey] = calcFunc({ addNodes = { [node] = true } }, useFullDPS)
end
local output = cache[node.modKey]
if self.powerStat and self.powerStat.stat and not self.powerStat.ignoreForNodes then
node.power.singleStat = self:CalculatePowerStat(self.powerStat, output, calcBase)
end
node.power.singleStat = self:CalculatePowerStat(self.powerStat, output, calcBase)
nodeIndex = nodeIndex + 1
if coroutine.running() and GetTime() - start > 100 then
if self.build.powerBuilderProgressCallback then
Expand Down
Loading