fix: reduce questie fps stutter hot paths
This commit is contained in:
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
- **[Performance - Minimap Filter And Learner Kill Hot Paths]** (#20) Reduced two likely stutter sources introduced after 1.6.2: minimap fade passes now cache expensive quest-filter visibility checks for already-visible icons instead of re-running them every 0.1s per icon, while still forcing a fresh check before hidden icons reappear; and the learner kill path no longer runs the spawn-evidence merge scan before the merger's three-evidence minimum can succeed.
|
||||||
- **[Map Tooltip - Objective Progress Refresh]** (#18) Minimap and world-map objective pin tooltips now refresh the underlying objective before rendering progress text, so kill counters update on hover instead of staying at the count captured when the pin was drawn.
|
- **[Map Tooltip - Objective Progress Refresh]** (#18) Minimap and world-map objective pin tooltips now refresh the underlying objective before rendering progress text, so kill counters update on hover instead of staying at the count captured when the pin was drawn.
|
||||||
- **[Learner - Stop Recording Bystander Kills As Your Own]** Kills of mobs you never engaged (other players killing nearby mobs) were being recorded as spawns at *your* position and inflating the kill count. The combat-log handler passed `px,py=nil` to `LearnNPC` for uncredited kills, whose `GetPlayerCoords` fallback then stored your location as the mob's spawn. Spawn recording (`LearnNPC` + GUID evidence) is now gated on a captured position, so only credited kills (your own / party kills you engaged, where a real position was captured) store a spawn. Bystander kills no longer pollute the learner with your coordinates or inflate the count; the NPC's name/quest data is still learned via mouseover/target.
|
- **[Learner - Stop Recording Bystander Kills As Your Own]** Kills of mobs you never engaged (other players killing nearby mobs) were being recorded as spawns at *your* position and inflating the kill count. The combat-log handler passed `px,py=nil` to `LearnNPC` for uncredited kills, whose `GetPlayerCoords` fallback then stored your location as the mob's spawn. Spawn recording (`LearnNPC` + GUID evidence) is now gated on a captured position, so only credited kills (your own / party kills you engaged, where a real position was captured) store a spawn. Bystander kills no longer pollute the learner with your coordinates or inflate the count; the NPC's name/quest data is still learned via mouseover/target.
|
||||||
- **[Fix - Fade Pass Crash On Stale Frame]** Hardened `ShowQuestIcons`/`HideQuestIcons` against a stale-frame desync (`attempt to index local 'icon'`): a frame name lingering in the registry after its frame was reset is now skipped gracefully instead of erroring out of the whole fade pass (and `ShowQuestIcons` no longer `error()`s on the desync), with nil-guards on `icon`/`icon.data`/`icon.data.QuestData`.
|
- **[Fix - Fade Pass Crash On Stale Frame]** Hardened `ShowQuestIcons`/`HideQuestIcons` against a stale-frame desync (`attempt to index local 'icon'`): a frame name lingering in the registry after its frame was reset is now skipped gracefully instead of erroring out of the whole fade pass (and `ShowQuestIcons` no longer `error()`s on the desync), with nil-guards on `icon`/`icon.data`/`icon.data.QuestData`.
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ local tunpack = unpack;
|
|||||||
local drawTimer
|
local drawTimer
|
||||||
local fadeLogicTimerShown
|
local fadeLogicTimerShown
|
||||||
local fadeLogicCoroutine
|
local fadeLogicCoroutine
|
||||||
|
local MINIMAP_VISIBILITY_CHECK_INTERVAL = 1
|
||||||
|
|
||||||
local function _ResolveMapUiMapId(uiMapId, x, y)
|
local function _ResolveMapUiMapId(uiMapId, x, y)
|
||||||
-- Ghost map 946 has no real coordinate data; redirect to Eversong (1941).
|
-- Ghost map 946 has no real coordinate data; redirect to Eversong (1941).
|
||||||
@@ -69,6 +70,15 @@ local function _ResolveMapUiMapId(uiMapId, x, y)
|
|||||||
return uiMapId
|
return uiMapId
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function _ShouldMinimapIconBeHidden(icon, forceRefresh)
|
||||||
|
local now = GetTime()
|
||||||
|
if forceRefresh or (not icon._lastShouldBeHiddenCheck) or (now - icon._lastShouldBeHiddenCheck) >= MINIMAP_VISIBILITY_CHECK_INTERVAL then
|
||||||
|
icon._lastShouldBeHiddenCheck = now
|
||||||
|
icon._lastShouldBeHiddenResult = icon:ShouldBeHidden()
|
||||||
|
end
|
||||||
|
return icon._lastShouldBeHiddenResult
|
||||||
|
end
|
||||||
|
|
||||||
local isDrawQueueDisabled = false
|
local isDrawQueueDisabled = false
|
||||||
|
|
||||||
--* TODO: How the frames are handled needs to be reworked, why are we getting them from _G
|
--* TODO: How the frames are handled needs to be reworked, why are we getting them from _G
|
||||||
@@ -362,6 +372,7 @@ function QuestieMap:RefreshMinimapIconVisibility()
|
|||||||
for minimapFrame, data in pairs(HBDPins.activeMinimapPins) do
|
for minimapFrame, data in pairs(HBDPins.activeMinimapPins) do
|
||||||
if minimapFrame and minimapFrame.miniMapIcon and minimapFrame.FadeLogic then
|
if minimapFrame and minimapFrame.miniMapIcon and minimapFrame.FadeLogic then
|
||||||
minimapFrame.minimapVisibilityCutoff = minimapVisibilityCutoff
|
minimapFrame.minimapVisibilityCutoff = minimapVisibilityCutoff
|
||||||
|
minimapFrame._lastShouldBeHiddenCheck = nil
|
||||||
minimapFrame:FadeLogic()
|
minimapFrame:FadeLogic()
|
||||||
if minimapFrame.GlowUpdate then
|
if minimapFrame.GlowUpdate then
|
||||||
minimapFrame:GlowUpdate()
|
minimapFrame:GlowUpdate()
|
||||||
@@ -686,7 +697,7 @@ function QuestieMap:DrawManualIcon(data, areaID, x, y, typ)
|
|||||||
-- when deciding whether to RE-SHOW an already-hidden icon, so a filtered icon
|
-- when deciding whether to RE-SHOW an already-hidden icon, so a filtered icon
|
||||||
-- that was already visible (e.g. a dungeon quest) lingered on the minimap
|
-- that was already visible (e.g. a dungeon quest) lingered on the minimap
|
||||||
-- while the world map correctly hid it. Hiding here keeps both maps in sync. (#11)
|
-- while the world map correctly hid it. Hiding here keeps both maps in sync. (#11)
|
||||||
if self:ShouldBeHidden() then
|
if _ShouldMinimapIconBeHidden(self) then
|
||||||
if not self.hidden then
|
if not self.hidden then
|
||||||
self:FakeHide()
|
self:FakeHide()
|
||||||
end
|
end
|
||||||
@@ -718,7 +729,7 @@ function QuestieMap:DrawManualIcon(data, areaID, x, y, typ)
|
|||||||
-- Previously FadeLogic re-showed ANY FakeHidden minimap icon once in
|
-- Previously FadeLogic re-showed ANY FakeHidden minimap icon once in
|
||||||
-- range, so the world-map quest-type filters never applied to the
|
-- range, so the world-map quest-type filters never applied to the
|
||||||
-- minimap. ShouldBeHidden mirrors the world-map draw-time check.
|
-- minimap. ShouldBeHidden mirrors the world-map draw-time check.
|
||||||
if not self:ShouldBeHidden() then
|
if not _ShouldMinimapIconBeHidden(self, true) then
|
||||||
self:FakeShow()
|
self:FakeShow()
|
||||||
end
|
end
|
||||||
elseif (distance > profile.fadeLevel) then
|
elseif (distance > profile.fadeLevel) then
|
||||||
@@ -866,7 +877,7 @@ function QuestieMap:DrawWorldIcon(data, areaID, x, y, showFlag)
|
|||||||
if (x and y) then
|
if (x and y) then
|
||||||
-- Proactively hide any filtered minimap icon even if currently shown,
|
-- Proactively hide any filtered minimap icon even if currently shown,
|
||||||
-- keeping the minimap in sync with the world-map filters. (#11)
|
-- keeping the minimap in sync with the world-map filters. (#11)
|
||||||
if self:ShouldBeHidden() then
|
if _ShouldMinimapIconBeHidden(self) then
|
||||||
if not self.hidden then
|
if not self.hidden then
|
||||||
self:FakeHide()
|
self:FakeHide()
|
||||||
end
|
end
|
||||||
@@ -896,7 +907,7 @@ function QuestieMap:DrawWorldIcon(data, areaID, x, y, showFlag)
|
|||||||
-- Previously FadeLogic re-showed ANY FakeHidden minimap icon once in
|
-- Previously FadeLogic re-showed ANY FakeHidden minimap icon once in
|
||||||
-- range, so the world-map quest-type filters never applied to the
|
-- range, so the world-map quest-type filters never applied to the
|
||||||
-- minimap. ShouldBeHidden mirrors the world-map draw-time check.
|
-- minimap. ShouldBeHidden mirrors the world-map draw-time check.
|
||||||
if not self:ShouldBeHidden() then
|
if not _ShouldMinimapIconBeHidden(self, true) then
|
||||||
self:FakeShow()
|
self:FakeShow()
|
||||||
end
|
end
|
||||||
elseif (distance > profile.fadeLevel) then
|
elseif (distance > profile.fadeLevel) then
|
||||||
|
|||||||
@@ -4439,15 +4439,15 @@ function QuestieLearner:OnCombatLogEvent(timestamp, eventType, srcGUID, srcName,
|
|||||||
-- "y", tostring(py))
|
-- "y", tostring(py))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Phase 3: weighted merge when evidence count is sufficient.
|
-- Phase 3: weighted merge when evidence count is sufficient. The merger
|
||||||
-- Temporarily lowered to 1 for Sunstrider/Mana Wyrm diagnostics so we can
|
-- itself requires at least three evidence points, so avoid doing its scan
|
||||||
-- verify the promotion path immediately.
|
-- on every early kill while the candidate still cannot be promoted.
|
||||||
local guidSpawns = Questie.dbLearner.global.npcs[npcId]
|
local guidSpawns = Questie.dbLearner.global.npcs[npcId]
|
||||||
and Questie.dbLearner.global.npcs[npcId][8]
|
and Questie.dbLearner.global.npcs[npcId][8]
|
||||||
if guidSpawns then
|
if guidSpawns then
|
||||||
local count = 0
|
local count = 0
|
||||||
for _ in pairs(guidSpawns) do count = count + 1 end
|
for _ in pairs(guidSpawns) do count = count + 1 end
|
||||||
if self:IsLearnerLiveEnabled() and count >= 1 then
|
if self:IsLearnerLiveEnabled() and count >= 3 then
|
||||||
_MergeSpawnEvidence(npcId)
|
_MergeSpawnEvidence(npcId)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user