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
23 changes: 17 additions & 6 deletions EllesmereUIDamageMeters/EllesmereUIDamageMeters.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ local RANK_STRINGS = {}
for i = 1, 40 do RANK_STRINGS[i] = i .. "." end
local MIN_W, MIN_H = 150, 50
local TICK_COMBAT = 1
local REFRESH_RATE_FLOOR = 0.5 -- default floor; skipped when unsafeRefreshRate is on
local REFRESH_RATE_HARD_FLOOR = 0.05 -- absolute floor regardless of unsafeRefreshRate: guards against a corrupt/imported 0 or negative value reaching the ticker
ns._REFRESH_RATE_FLOOR = REFRESH_RATE_FLOOR -- published so the options page's toggle-off snap-back uses the same value instead of a second hardcoded 0.5
local PEAK_BUDGET = 1.5
local BAR_TEX = "Interface\\Buttons\\WHITE8X8"
local MEDIA = "Interface\\AddOns\\EllesmereUIDamageMeters\\Media\\"
Expand Down Expand Up @@ -131,6 +134,7 @@ local DM_DEFAULTS = {
standaloneTimerShowOOC = false,
standaloneTimerDesatOOC = false,
refreshRate = 1,
unsafeRefreshRate = false, -- opt-in: lets refreshRate go below the 0.5s floor
hideResetButton = false, -- display the "reset data" button on the damage meter header
-- toggleWindowsKey (unset by default) is the hotkey that hides/shows every
-- meter window at once. Runtime only: the hidden state is never saved, so a
Expand Down Expand Up @@ -258,14 +262,18 @@ local function EnsureDB()
-- snapshot per window, so sub-0.5 rates multiply allocation churn far
-- past any visual gain. Clamp every stored profile once per session
-- (idempotent; imports of old exports are caught by the ticker clamp
-- until their next login).
-- until their next login). Skipped for a profile with unsafeRefreshRate
-- on; the hard floor still applies regardless, so a corrupt/imported
-- value can't reach the ticker as 0 or negative.
local sv = _G.EllesmereUIDamageMetersDB
if type(sv) == "table" and type(sv.profiles) == "table" then
for _, p in pairs(sv.profiles) do
local dm = type(p) == "table" and p.dm
if type(dm) == "table" and type(dm.refreshRate) == "number"
and dm.refreshRate < 0.5 then
dm.refreshRate = 0.5
if type(dm) == "table" and type(dm.refreshRate) == "number" then
local floor = dm.unsafeRefreshRate and REFRESH_RATE_HARD_FLOOR or REFRESH_RATE_FLOOR
if dm.refreshRate < floor then
dm.refreshRate = floor
end
end
end
end
Expand Down Expand Up @@ -5236,8 +5244,11 @@ StartSharedTicker = function()
if _sharedTicker then _sharedTicker:Cancel() end
local rate = DB().refreshRate or TICK_COMBAT
-- Belt for values the login clamp has not seen yet (a profile imported
-- mid-session from an old export can carry a sub-floor rate).
if rate < 0.5 then rate = 0.5 end
-- mid-session from an old export can carry a sub-floor rate). Respects
-- unsafeRefreshRate the same way the login clamp does; the hard floor
-- applies either way so 0 or negative can never reach the ticker.
local floor = DB().unsafeRefreshRate and REFRESH_RATE_HARD_FLOOR or REFRESH_RATE_FLOOR
if rate < floor then rate = floor end
_sharedTicker = C_Timer.NewTicker(rate, SharedRefreshTick)
StopTimerTicker()
_timerTicker = C_Timer.NewTicker(0.5, TimerTick)
Expand Down
55 changes: 53 additions & 2 deletions EllesmereUIOptions/EUI_DamageMeters_Options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,64 @@ initFrame:SetScript("OnEvent", function(self)
onChanged = VisApply,
onOptionChanged = VisApply },
-- Refresh Rate moved up into the slot the Visibility Options dropdown left
-- behind; its "(seconds)" suffix is attached below.
-- behind; its "(seconds)" suffix is attached below. Range widens once the
-- cog's Unsafe Refresh Rate toggle is on (see below); that toggle rebuilds
-- the page so this table is re-evaluated with the new min/tooltip.
(Cfg("unsafeRefreshRate") and
{ type="slider", text="Refresh Rate",
tooltip = "Below 0.5s multiplies memory allocation per window every tick. Not recommended with several windows open.",
min = 0.1, max = 2, step = 0.05,
getValue = function() return Cfg("refreshRate") or 1 end,
setValue = function(v) Set("refreshRate", v) end,
fmt = function(v) return format("%.2fs", v) end }
or
{ type="slider", text="Refresh Rate",
tooltip = "Increase to improve performance, Decrease to update meters faster",
min = 0.5, max = 2, step = 0.1,
getValue = function() return Cfg("refreshRate") or 1 end,
setValue = function(v) Set("refreshRate", v) end,
fmt = function(v) return format("%.2fs", v) end })
fmt = function(v) return format("%.2fs", v) end }))
if not EllesmereUI._prebuilding then
local rgn = visRow._rightRegion
-- Forward-declared so the row's set() can close the popup before the page
-- rebuild below tears down the button it's anchored to: RefreshPage(true)
-- recreates this whole block's frames, and a still-open popup left anchored
-- to the old (now orphaned) cog button drifts to wherever that frame lands.
local unsafeCogShow
local _, _unsafeCogShow = EllesmereUI.BuildCogPopup({
title = "Refresh Rate",
rows = {
{ type = "toggle", label = "Unsafe Refresh Rate",
tooltip = "Allows Refresh Rate below 0.5s. Each tick fetches a full session snapshot per window, so lower values multiply allocation cost far past any visual gain, especially with several windows open.",
get = function() return Cfg("unsafeRefreshRate") == true end,
set = function(v)
Set("unsafeRefreshRate", v)
if not v then
local floor = ns._REFRESH_RATE_FLOOR or 0.5
local r = Cfg("refreshRate")
if r and r < floor then Set("refreshRate", floor) end
end
if unsafeCogShow and unsafeCogShow._popupFrame then
unsafeCogShow._popupFrame:Hide()
end
EllesmereUI:RefreshPage(true)
end },
},
})
unsafeCogShow = _unsafeCogShow
local unsafeCogBtn = CreateFrame("Button", nil, rgn)
unsafeCogBtn:SetSize(26, 26)
unsafeCogBtn:SetPoint("RIGHT", rgn._control, "LEFT", -8, 0)
rgn._lastInline = unsafeCogBtn
unsafeCogBtn:SetFrameLevel(rgn:GetFrameLevel() + 5)
unsafeCogBtn:SetAlpha(0.4)
local unsafeCogTex = unsafeCogBtn:CreateTexture(nil, "OVERLAY")
unsafeCogTex:SetAllPoints()
unsafeCogTex:SetTexture(EllesmereUI.COGS_ICON)
unsafeCogBtn:SetScript("OnEnter", function(self) self:SetAlpha(0.7) end)
unsafeCogBtn:SetScript("OnLeave", function(self) self:SetAlpha(0.4) end)
unsafeCogBtn:SetScript("OnClick", function(self) unsafeCogShow(self) end)
end
y = y - h

-- Window Border Style (+ directions submenu) | Border Size (+ color)
Expand Down