View Single Post
03-17-19, 11:22 PM   #4
Terenna
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 105
As it turned out, there was a taint that was possible with the previous code.

I have completely rectified this and tested the hell out of it in several really weird edge cases and as far as I can tell, no taint. If anyone is interested in the code to alleviate the lack of button population in certain circumstances, you may find it here:
Lua Code:
  1. --[[
  2.     Assess whether the attribute that was changed and triggered the blizzard _onattributechanged event was the 'statehidden' attribute
  3.     Assess whether the player has an OverrideActionBar or VehicleActionBar
  4.     If they do, determine if the 6 (< 7) OverrideActionBarButtons which are used for VehicleActionBar, too, are hidden or not
  5.     If the player has a special bar and the OverrideActionBarButton is hidden, also hide the respective ActionButton that is part of the paging bar
  6.     However, if they have a special bar but the OverrideActionBarButton is shown, also show the respective ActionButton that is part of the paging bar
  7.     Hide the ActionButtons7-12 if the player has a special bar
  8.     If the player doesn't have an OverrideActionBar nor VehicleActionBar, show ActionButtons1-12 that are part of the paging bar
  9. ]]--
  10. local _onAttributeChanged = [[
  11.     if name == 'statehidden' then
  12.         if (HasOverrideActionBar() or HasVehicleActionBar()) then
  13.             for i = 1, 12 do
  14.                 if i < 7 then
  15.                     if overridebuttons[i]:GetAttribute('statehidden') then
  16.                         buttons[i]:SetAttribute('statehidden', true)
  17.                         buttons[i]:Hide()
  18.                     else
  19.                         buttons[i]:SetAttribute('statehidden', false)
  20.                         buttons[i]:Show()
  21.                     end
  22.                 else
  23.                     buttons[i]:SetAttribute('statehidden', true)
  24.                     buttons[i]:Hide()
  25.                 end
  26.             end
  27.         else
  28.             for i = 1, 12 do
  29.                 buttons[i]:SetAttribute('statehidden', false)
  30.                 buttons[i]:Show()
  31.             end
  32.         end
  33.     end
  34. ]]
  35. --[[
  36.     Generate a secure frame, AttributeChangedFrame, that is used to 'hook' into the _onattributechanged
  37.     Set frame references for both the ActionButtons and the OverrideActionBarButtons, which are used for both VehicleActionBar and OverrideActionBar bars
  38.     Make two secure tables, buttons and overridebuttons; populate it with the buttons using the just set frame references
  39.     'Hook' our secure frame to run the secure _onAttributeChanged snippet when the blizzard event, _onattributechanged, fires
  40.     Finish by registering the secure frame as a secure state driver, because for some reason this is required for the _onattributechanged to properly be hooked
  41. ]]--
  42. local AttributeChangedFrame = CreateFrame('Frame', nil, UIParent, 'SecureHandlerAttributeTemplate')
  43. for i = 1, 12 do
  44.     local button = _G['ActionButton'..i]
  45.     AttributeChangedFrame:SetFrameRef('ActionButton'..i, button)
  46. end
  47.  
  48. for i = 1, 6 do
  49.     local overrideButton = _G['OverrideActionBarButton'..i]
  50.     AttributeChangedFrame:SetFrameRef('OverrideActionBarButton'..i, overrideButton)
  51. end
  52.  
  53. AttributeChangedFrame:Execute([[
  54.     buttons = table.new()
  55.     for i = 1, 12 do
  56.         buttons[i] = self:GetFrameRef('ActionButton'..i)
  57.     end
  58.  
  59.     overridebuttons = table.new()
  60.     for j = 1, 6 do
  61.         overridebuttons[j] = self:GetFrameRef('OverrideActionBarButton'..j)
  62.     end
  63. ]])
  64.  
  65. AttributeChangedFrame:SetAttribute('_onattributechanged', _onAttributeChanged)
  66. RegisterStateDriver(AttributeChangedFrame, 'visibility', '[overridebar][shapeshift][vehicleui][possessbar] show; hide')

I've put in a bunch of documentation for why I did what I did. One thing I can't resolve, is why I need to RegisterStateDriver for visibility for the :SetAttribute('_onattributechanged', _onAttributeChanged) to actually fire. Without this RegisterStateDriver(...) line, this doesn't happen. Is there anyone who can explain that finding?

Last edited by Terenna : 03-18-19 at 07:51 AM.
  Reply With Quote