fix(unitframes): honour a class power style changed outside the options panel - #1232
Open
dfrisone wants to merge 2 commits into
Open
fix(unitframes): honour a class power style changed outside the options panel#1232dfrisone wants to merge 2 commits into
dfrisone wants to merge 2 commits into
Conversation
…ns panel Reported by @n0ObiX_ on 8.7.5: a Spec Override setting Enable Class Resource to None for Arms does not apply on login. Switching to another spec and back makes it work. frames._toggleClassPower is the only thing that honours a classPowerStyle change -- it tears the bar down, rebuilds it, and re-anchors the health bar -- and it had exactly two callers: the options dropdown, and the PLAYER_SPECIALIZATION_CHANGED watcher. So a style changed through any other path left the live bar stale. Spec Overrides applying at login is one such path; so are a profile switch and an import. The reported workaround is the diagnosis: switching spec away and back is the one event that does call it. Note the watcher deliberately does nothing on PLAYER_ENTERING_WORLD beyond setting its init flag, so login was never covered. Realise the style on any reload instead, gated on the built style actually differing, because the toggle is a full teardown and running it on every reload would thrash the bar. frames._classPowerBuiltStyle records what is currently built, set both by the toggle and by the init build path -- the latter so the first reload of a session does not see a nil marker, assume a change, and pay a pointless rebuild for users with no override at all. The spec-change watcher is unaffected: it calls the toggle itself, which updates the marker, so the reload it queues finds them equal and no-ops.
… of combat Two defects from a review of the previous commit. The built-style marker was seeded inside PositionClassPowerBar, which is a REPOSITIONING function, not a build. ReassertClassPower calls it from Blizzard's SetParent and Hide hooks on form and spec changes, with no rebuild behind it, so it stamped the CURRENT PROFILE style onto a bar that was still built as something else. That claims a style is built when it is not, and the reload pass then sees no change and skips the rebuild, which is exactly the reported bug coming back. It only bites while the Blizzard style is live, since _blizzCPActive gates the reassert, but the whole point of the marker is that it describes what is built, so it has to be written where the build happens. Moved to the init build block, guarded on frames.player to match the toggle, which returns before stamping when there is no frame. The reload pass had no combat gate. ReloadFrames() itself early-returns in lockdown, but this runs from the throttle body AFTER that return, so the guard does not cover it -- the same trap the UpdateFrameVisibility note a few lines up already documents. Unguarded it would reparent and hide Blizzard's class power frame and re-anchor the health bar mid-fight; ReassertClassPower guards Show() on that same frame the same way. Skipping alone is not enough either, because nothing re-arms the pass once combat ends, so the style would stay stale until some later reload. Defers to PLAYER_REGEN_ENABLED and re-runs. Both call sites now share one RealiseClassPowerStyle helper instead of open-coding the check.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported by @n0ObiX_ on 8.7.5: a Spec Override setting Enable Class Resource to None for Arms does not apply on login. Switching to another spec and back makes it work.
Cause
frames._toggleClassPoweris the only thing that honours aclassPowerStylechange. It tears the bar down, rebuilds it, and re-anchors the health bar. It had exactly two callers: the options dropdown, and thePLAYER_SPECIALIZATION_CHANGEDwatcher.So a style changed through any other path left the live bar stale. Spec Overrides applying at login is one such path; so are a profile switch and an import. The reported workaround is the diagnosis, since switching spec away and back is the one event that does call it. The watcher deliberately does nothing on
PLAYER_ENTERING_WORLDbeyond setting its init flag, so login was never covered.Fix
Realise the style on any reload instead, gated on the built style actually differing, because the toggle is a full teardown and running it on every reload would thrash the bar.
frames._classPowerBuiltStylerecords what is currently built. It is written in exactly two places, both real build sites: the init build, and the toggle itself. The init one matters so the first reload of a session does not see a nil marker, assume a change, and pay a pointless rebuild for users with no override at all.The spec-change watcher is unaffected. It calls the toggle itself, which updates the marker, so the reload it queues finds them equal and no-ops.
Two things the self-review caught after the first in-game pass
Both are in the second commit, and neither was visible to a passing test of the reported case.
The marker was originally seeded inside
PositionClassPowerBar. That is a repositioning function, not a build, andReassertClassPowercalls it from Blizzard'sSetParentandHidehooks on form and spec changes with no rebuild behind it. It therefore stamped the current profile style onto a bar still built as something else, which makes the reload pass see no change and skip the rebuild: the reported bug, back again. It only bites while the Blizzard style is live, since_blizzCPActivegates the reassert. A marker that records what is built has to be written where the build happens, so it moved to the init build block, guarded onframes.playerto match the toggle.The call also had no combat gate.
ReloadFrames()early-returns in lockdown, but this runs from the throttle body after that return, so that guard does not cover it, which is the same trap theUpdateFrameVisibilitynote a few lines up already documents. Unguarded it would reparent and hide Blizzard's class power frame and re-anchor the health bar mid-fight;ReassertClassPowerguardsShow()on that same frame the same way. Skipping alone was not enough either, because nothing re-arms the pass once combat ends, so it defers toPLAYER_REGEN_ENABLEDand re-runs.Performance
Steady state is a table lookup, a db read, and a string compare per reload pass, then an early return. The teardown only runs on an actual change.
No polling is added. The deferral frame has no
OnUpdateand registersPLAYER_REGEN_ENABLEDonly while a change is pending in combat, unregistering as soon as it fires. Neither_toggleClassPowernorResizeFrameForClassPowerre-arms the reload pass, so there is no loop, and the marker would make a second pass a no-op even if something did.Net it is marginally cheaper than before the review, since the marker write moved off
PositionClassPowerBar, which runs on every Blizzard reparent, onto a build path that runs once.Notes
One file. No new strings, no options changes, no saved-variable changes.
Tested in game: the reported Spec Override case now applies at login, and re-tested after the review changes.