Thread Tools Display Modes
04-11-16, 07:58 AM   #1
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
How can I do this without causing a taint?

Hiya!

So I've managed to get the bottom action bars working like this.



But, unfortunately, it's causing combat taints. Any changes to the bars and it gets blocked, which is a huge problem whenever exiting a vehicle while still in combat.

The frame hierarchy pretty much goes like this:

Code:
MultiBarHolder
	MultiBarLeft
		MultiBarBottomLeftButton1..12
	MultiBarRight
		MultiBarBottomRightButton1..12
So essentially I've got a holder frame containing two frames, anchored to the left and right respectively of the holder frame. And then those two frames contain the bottom left and bottom right action buttons respectively. I have a single handler function that handles everything on that bottom bar; the action bars, the xp/rep bars, all of it. And it runs whenever a related event fires (visibility of the action bars, faction watch status, XP update, etc.) with no real issue. Except for this part here;

Lua Code:
  1. if VisibleLeft and VisibleRight then
  2.     ns.MultiBarHolder:SetHeight(40)
  3.     ns.MultiBarHolder:SetWidth((458*2))
  4. elseif VisibleLeft or VisibleRight then
  5.     ns.MultiBarHolder:SetHeight(40)
  6.     ns.MultiBarHolder:SetWidth(460)
  7. else
  8.     ns.MultiBarHolder:SetHeight(1)
  9.     ns.MultiBarHolder:SetWidth(460)
  10. end

I'm not even touching the action bars, or the frames they're sitting on. I'm changing the height and width of the holder frame it's all anchored to, and for some reason that causes the code to freak out. I tried to log the taint, and this section was the culprit, every single time. So I'm guessing that I need to handle this frame's sizing securely somehow?
  Reply With Quote
04-11-16, 08:10 AM   #2
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
You can't resize or mess with any secure frames in combat in response to an event. You can, however, use macro conditionals to alter the behavior of your action bar. See code below for example:

Lua Code:
  1. local Bar = CreateFrame("Frame", barName, UIParent, "SecureHandlerStateTemplate")
  2. RegisterStateDriver(Bar, "visibility", "[petbattle][vehicleui] hide; show") -- hide the bar if SecureCmdOptionParse returns true for petbattle or vehicleui, else show

Your holder frame automatically becomes protected when you anchor secure frames to it. Moving or altering the holder frame insecurely also makes changes to where the bars are drawn on screen, which causes your errors.
Regions may be explicitly protected by Blizzard scripts or XML; other regions can become protected by becoming children of protected regions or by being positioned relative to protected regions.
__________________

Last edited by MunkDev : 04-11-16 at 08:59 AM.
  Reply With Quote
04-11-16, 09:10 AM   #3
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Yeah, I assumed that was the case, heh. Been trying to figure out just how state handlers and state drivers work, but I really don't seem to be getting it. I mean, I noticed that SecureStateHeaderTemplate has attributes called headwidth and headheight. How am I supposed to be leveraging that?

My first guess was that it'd either be RegisterStateDriver(Bar, "headwidth", "40") or Bar:SetAttribute("headwidth", "40"). But trying it out definitely didn't work. I must be missing something here, or just not getting it.
  Reply With Quote
04-11-16, 09:41 AM   #4
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
A state driver is just a macro condition that makes changes to your secure header. State drivers are used for things like action bar paging or modified actions. You can also create custom conditions that fire custom state updates. Here's an example of how that works:

Lua Code:
  1. -- registers a state driver that sends ctrlsh, ctrl, shift or nil depending on modifier(s) held down
  2. RegisterStateDriver(Bar, "modifier", "[mod:ctrl,mod:shift] ctrlsh; [mod:ctrl] ctrl; [mod:shift] shift; nil")
  3.  
  4. -- state drivers fire pre-defined snippets of code in the form of strings attached to the header with a dedicated attribute
  5. -- the attribute is "_onstate-XXX" for a given state driver.
  6. Bar:SetAttribute("_onstate-modifier", [[
  7.     -- change the "modifier" attribute on all children of the header to the new modifier value
  8.     control:ChildUpdate("modifier", newstate)
  9. ]])

Likewise, you may do something like this to change the size in response to a macro condition:
Lua Code:
  1. RegisterStateDriver(Bar, "override", "[petbattle][vehicleui] minimize; maximize")
  2.  
  3. Bar:SetAttribute("_onstate-override", [[
  4.     if newstate == "minimize" then
  5.         self:SetHeight(40)
  6.     elseif newstate == "maximize" then
  7.         self:SetHeight(60)
  8.     end
  9. ]])

...or this to show a custom target button when the target exists:
Lua Code:
  1. local MyTargetFrame = CreateFrame("Button", "MyTargetFrame", UIParent, "SecureActionButtonTemplate, SecureHandlerStateTemplate")
  2. MyTargetFrame:SetAttribute("type", "unit")
  3. MyTargetFrame:SetAttribute("unit", "target")
  4. RegisterStateDriver(MyTargetFrame, "unitexists", "[@target,exists,nodead] true; nil")
  5.  
  6. MyTargetFrame:SetAttribute("_onstate-unitexists", [[
  7.     if newstate then
  8.         self:Show()
  9.     else
  10.         self:Hide()
  11.     end
  12. ]])
Although the last bit can be simplified by using RegisterUnitWatch.

If you explain exactly what you're trying to do and provide the current code you're using, I'll be able to supply a working solution.
__________________
  Reply With Quote
04-11-16, 09:42 AM   #5
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2012
Posts: 341
So, do you want to change your bar width/height at will, or do you change it, when some specific even fires or something happens, like you get into vehicle and so on?

-- updated

Whatevs, MunkDev explained possible scenarios quite well
__________________
  Reply With Quote
04-11-16, 10:04 AM   #6
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Alright, sweet, think I'm starting to get it now!

But essentially, in my actionbars.lua file I'm creating a holder frame for the action bars.
Lua Code:
  1. ns.MultiBarHolder = CreateFrame("Frame","MultiBarHolder",MainMenuBar,"SecureHandlerStateTemplate")
  2. ns.MultiBarHolder:SetPoint("BOTTOM",MainMenuBar,"BOTTOM",0,29)

And this frame essentially contains two more frames, MultiBarLeft and MultiBarRight, both of which are filled with the MultiBarBottomLeft/Right action buttons. And this part is perfectly fine, they're static frames anchored inside of the holder frame, and there's nothing happening to them.

Then there's this function, located inside bottomframe.lua, that works as a visibility handler for the bottom chunk of the UI. It scales the bottom frame based on what's in it, like it shows in the GIF at the top, and it runs on events updating experience and reputation, upon login, OnHide and OnShow for the game's default MultiBarBottom frames, so pretty much anything that affects the visibility of its contents.

Lua Code:
  1. local function BottomElementsHandler()
  2.  
  3.         -- Checking button visibility on their original container frames
  4.         local VisibleLeft = MultiBarBottomLeft:IsVisible()
  5.         local VisibleRight = MultiBarBottomRight:IsVisible()
  6.         local RepVisible = ns.Reputation:IsShown()
  7.         local ExpVisible = ns.Experience:IsShown()
  8.         local BarWidth = 483
  9.         local BarHeight = 11
  10.  
  11.         -- Visibility handling for the MultiBars
  12.             if VisibleLeft and VisibleRight then
  13.                 ns.MultiBarHolder:SetHeight(40)
  14.                 ns.MultiBarHolder:SetWidth((458*2))
  15.             elseif VisibleLeft or VisibleRight then
  16.                 ns.MultiBarHolder:SetHeight(40)
  17.                 ns.MultiBarHolder:SetWidth(460)
  18.             else
  19.                 ns.MultiBarHolder:SetHeight(1)
  20.                 ns.MultiBarHolder:SetWidth(460)
  21.             end
  22.  
  23.         -- Visibility for the MultiBar art
  24.         if VisibleLeft or VisibleRight then
  25.             ns.MultiBarRightArt:Show()
  26.             ns.MultiBarLeftArt:Show()
  27.         else
  28.             ns.MultiBarRightArt:Hide()
  29.             ns.MultiBarLeftArt:Hide()
  30.         end
  31.  
  32.         -- Set width for the statusbars
  33.         if (ns.MultiBarHolder:GetWidth() > 500) then
  34.             BarWidth = ns.MultiBarHolder:GetWidth()+4
  35.         else
  36.             BarWidth = 464
  37.         end
  38.  
  39.         -- Set the anchor points of the Exp and Rep bars
  40.         if RepVisible and ExpVisible then
  41.             ns.ExpRepHolder:SetHeight(BarHeight)
  42.             ns.Reputation:SetPoint("RIGHT",ns.ExpRepHolder,"RIGHT")
  43.             ns.Reputation:SetPoint("LEFT",ns.ExpRepHolder,"CENTER")
  44.             ns.Experience:SetPoint("LEFT",ns.ExpRepHolder,"LEFT")
  45.             ns.Experience:SetPoint("RIGHT",ns.ExpRepHolder,"CENTER")
  46.         elseif RepVisible or ExpVisible then
  47.             ns.ExpRepHolder:SetHeight(BarHeight)
  48.             ns.Reputation:SetPoint("LEFT",ns.ExpRepHolder,"LEFT")
  49.             ns.Reputation:SetPoint("RIGHT",ns.ExpRepHolder,"RIGHT")
  50.             ns.Experience:SetPoint("LEFT",ns.ExpRepHolder,"LEFT")
  51.             ns.Experience:SetPoint("RIGHT",ns.ExpRepHolder,"RIGHT")
  52.         else
  53.             ns.ExpRepHolder:SetHeight(1)
  54.         end
  55.  
  56.         ns.ExpRepHolder:SetWidth(BarWidth)
  57.  
  58.         MicroBarTexture:SetWidth(ns.MultiBarHolder:GetWidth()+4)
  59.  
  60.         LeftEdgeArt:SetPoint("TOPRIGHT",ns.ExpRepHolder,"TOPLEFT",83,28)
  61.         RightEdgeArt:SetPoint("TOPLEFT",ns.ExpRepHolder,"TOPRIGHT",-83,28)
  62.  
  63.  
  64.     end

And it's really just the visibility for the MultiBarHolder, on line 12 - 21, that screws up. It should be doing exactly the same thing, set its own width and height based on the visibility of its two child frames, and that is pretty much the extent of it.
  Reply With Quote
04-11-16, 10:10 AM   #7
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
What do you use to change VisibleLeft and VisibleRight? You should definitely not keep these lines in this function. You have to move all the adjustments to the secure parts of your holder frame into the restricted environment.
__________________
  Reply With Quote
04-11-16, 10:19 AM   #8
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
There's nothing changing them, aside from in that function. It just gets :IsVisible() on line 4 and 5, so that I don't have to do a full MultiBarBottomSomething:IsVisible() every on every if/else check, and the reason why is really just because it was the easiest way to find the visibility of those frames. When I looked through the settings lua files in the game source I couldn't find any global relating to the visibility of these frames, or whether or not these options were checked, so I decided to leave the original MultiBarBottom frames present but empty so that I can check their visibility directly!
  Reply With Quote
04-11-16, 10:38 AM   #9
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
Lol, my bad for not reading every line. Here's something that should work:
Lua Code:
  1. ns.MultiBarHolder = CreateFrame("Frame","MultiBarHolder",MainMenuBar,"SecureHandlerBaseTemplate, SecureHandlerShowHideTemplate, SecureHandlerStateTemplate")
  2. ns.MultiBarHolder:SetPoint("BOTTOM",MainMenuBar,"BOTTOM",0,29)
  3.  
  4. -- Set frame ref so they can be retrieved securely.
  5. ns.MultiBarHolder:SetFrameRef("MultiBarBottomLeft", MultiBarBottomLeft)
  6. ns.MultiBarHolder:SetFrameRef("MultiBarBottomRight", MultiBarBottomRight)
  7.  
  8. -- store the bars as global values in the holder's secure environment
  9. ns.MultiBarHolder:Execute([[
  10.     -- anytime you execute something on the holder frame, these variables are available "globally"
  11.     MultiBarBottomLeft = self:GetFrameRef("MultiBarBottomLeft")
  12.     MultiBarBottomRight = self:GetFrameRef("MultiBarBottomRight")
  13.  
  14.     -- also store the holder frame as something that won't be overwritten by locals
  15.     Holder = self
  16. ]])
  17.  
  18. local VisibilitySnippet = [[
  19.     -- self refers to the calling frame in this snippet, so use Holder to get the holder frame
  20.     -- this is still within the holder frame's secure environment though!
  21.  
  22.     Holder:RunAttribute("UpdateVisibility")
  23. ]]
  24.  
  25. ns.MultiBarHolder:WrapScript(MultiBarBottomLeft, "OnShow", VisibilitySnippet)
  26. ns.MultiBarHolder:WrapScript(MultiBarBottomRight, "OnShow", VisibilitySnippet)
  27. ns.MultiBarHolder:WrapScript(MultiBarBottomLeft, "OnHide", VisibilitySnippet)
  28. ns.MultiBarHolder:WrapScript(MultiBarBottomRight, "OnHide", VisibilitySnippet)
  29.  
  30. ns.MultiBarHolder:SetAttribute("UpdateVisibility", [[
  31.     local VisibleLeft = MultiBarBottomLeft:IsVisible()
  32.     local VisibleRight = MultiBarBottomRight:IsVisible()
  33.  
  34.     if VisibleLeft and VisibleRight then
  35.         self:SetSize(458 * 2, 40)
  36.     elseif VisibleLeft or VisibleRight then
  37.         self:SetSize(460, 40)
  38.     else
  39.         self:SetSize(460, 1)
  40.     end
  41. ]])
  42.  
  43. --Update the visibility when the holder is shown/hidden
  44. ns.MultiBarHolder:SetAttribute("_onshow", ns.MultiBarHolder:GetAttribute("UpdateVisibility"))
  45. ns.MultiBarHolder:SetAttribute("_onhide", ns.MultiBarHolder:GetAttribute("UpdateVisibility"))
  46.  
  47. local function BottomElementsHandler()
  48.  
  49.     -- Checking button visibility on their original container frames
  50.     local VisibleLeft = MultiBarBottomLeft:IsVisible()
  51.     local VisibleRight = MultiBarBottomRight:IsVisible()
  52.     local RepVisible = ns.Reputation:IsShown()
  53.     local ExpVisible = ns.Experience:IsShown()
  54.     local BarWidth = 483
  55.     local BarHeight = 11
  56.  
  57.     -- Visibility handling for the MultiBars
  58.     -- if VisibleLeft and VisibleRight then
  59.     --     ns.MultiBarHolder:SetHeight(40)
  60.     --     ns.MultiBarHolder:SetWidth((458*2))
  61.     -- elseif VisibleLeft or VisibleRight then
  62.     --     ns.MultiBarHolder:SetHeight(40)
  63.     --     ns.MultiBarHolder:SetWidth(460)
  64.     -- else
  65.     --     ns.MultiBarHolder:SetHeight(1)
  66.     --     ns.MultiBarHolder:SetWidth(460)
  67.     -- end
  68.  
  69.     -- Visibility for the MultiBar art
  70.     if VisibleLeft or VisibleRight then
  71.         ns.MultiBarRightArt:Show()
  72.         ns.MultiBarLeftArt:Show()
  73.     else
  74.         ns.MultiBarRightArt:Hide()
  75.         ns.MultiBarLeftArt:Hide()
  76.     end
  77.  
  78.     -- Set width for the statusbars
  79.     if (ns.MultiBarHolder:GetWidth() > 500) then
  80.         BarWidth = ns.MultiBarHolder:GetWidth()+4
  81.     else
  82.         BarWidth = 464
  83.     end
  84.  
  85.     -- Set the anchor points of the Exp and Rep bars
  86.     if RepVisible and ExpVisible then
  87.         ns.ExpRepHolder:SetHeight(BarHeight)
  88.         ns.Reputation:SetPoint("RIGHT",ns.ExpRepHolder,"RIGHT")
  89.         ns.Reputation:SetPoint("LEFT",ns.ExpRepHolder,"CENTER")
  90.         ns.Experience:SetPoint("LEFT",ns.ExpRepHolder,"LEFT")
  91.         ns.Experience:SetPoint("RIGHT",ns.ExpRepHolder,"CENTER")
  92.     elseif RepVisible or ExpVisible then
  93.         ns.ExpRepHolder:SetHeight(BarHeight)
  94.         ns.Reputation:SetPoint("LEFT",ns.ExpRepHolder,"LEFT")
  95.         ns.Reputation:SetPoint("RIGHT",ns.ExpRepHolder,"RIGHT")
  96.         ns.Experience:SetPoint("LEFT",ns.ExpRepHolder,"LEFT")
  97.         ns.Experience:SetPoint("RIGHT",ns.ExpRepHolder,"RIGHT")
  98.     else
  99.         ns.ExpRepHolder:SetHeight(1)
  100.     end
  101.  
  102.     ns.ExpRepHolder:SetWidth(BarWidth)
  103.  
  104.     MicroBarTexture:SetWidth(ns.MultiBarHolder:GetWidth()+4)
  105.  
  106.     LeftEdgeArt:SetPoint("TOPRIGHT",ns.ExpRepHolder,"TOPLEFT",83,28)
  107.     RightEdgeArt:SetPoint("TOPLEFT",ns.ExpRepHolder,"TOPRIGHT",-83,28)
  108.  
  109. end
__________________

Last edited by MunkDev : 04-11-16 at 10:51 AM.
  Reply With Quote
04-11-16, 11:52 AM   #10
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Huh, so that's how it all fits together? Don't know if I would've figured that out on my own, heh!

Can't quite seem to get it working, though. Think it's the VisibilitySnippet part that doesn't run, for some reason?
  Reply With Quote
04-11-16, 12:08 PM   #11
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
Hard to debug without having access to the full code, but you could try forcing an update by adding this at the end:
Lua Code:
  1. ns.MultiBarHolder:Show()
Are you not getting any errors?
__________________
  Reply With Quote
04-11-16, 12:22 PM   #12
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
I could put the source online, if you'd like to have a look at the whole of it!

But no errors, no. Tried circumventing the VisibilitySnippet by just putting the RunAttribute() right into the end of the WrapScript() like ns.MultiBarHolder:WrapScript(MultiBarBottomLeft, "OnShow", 'Holder:RunAttribute("UpdateVisibility")'), but that didn't seem to get me anywhere. Same situation without any errors.

Also tried to straight-up do MultiBarBottomLeft:SetScript("OnShow", VisibilitySnippet), which of course returns the expected usage of SetScript and the fact that it's expecting a function and getting what I'm guessing is a string?

EDIT: Here's a dropbox link to the project. https://www.dropbox.com/s/84p8ac0weg...estUI.zip?dl=0

I should really find an actual name for it soon, haha. And maybe put it up on my Github instead.

Last edited by Folji : 04-11-16 at 12:32 PM.
  Reply With Quote
04-11-16, 01:00 PM   #13
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
The secure environment doesn't allow direct functions. All script snippets are strings that are compiled on the fly, which means you can't sneak information in there inside combat. I've been doing some probing, and it seems that the multibars always return false when :IsVisible is used securely. The snippets don't run because the bars themselves don't actually trigger any OnShow or OnHide script. I'm not sure why.
__________________
  Reply With Quote
04-11-16, 01:21 PM   #14
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
Okay, I managed to get it working by creating two separate dummy frames and anchoring them to each bar. Why I had to do this is beyond me, but at least the thing is triggering correctly now.

Lua Code:
  1. ns.probeLeft = CreateFrame("Frame", nil, MultiBarBottomLeft, "SecureHandlerBaseTemplate")
  2. ns.probeRight = CreateFrame("Frame", nil, MultiBarBottomRight, "SecureHandlerBaseTemplate")
  3.  
  4. ns.MultiBarHolder:SetFrameRef("MultiBarBottomLeft", ns.probeLeft)
  5. ns.MultiBarHolder:SetFrameRef("MultiBarBottomRight", ns.probeRight)



Here's the modified zip. Hope I didn't screw up your formatting too much since it seems we're using different editors.

https://www.dropbox.com/s/wbh5t8ndu5...estUI.zip?dl=0

Btw, you can discard my old feedback about the look of the art. It looks better in person without screenshot compression.
__________________

Last edited by MunkDev : 04-11-16 at 01:26 PM.
  Reply With Quote
04-11-16, 01:33 PM   #15
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Really? Yikes. They've really locked the secure environment down tight, huh?

Thanks a whole lot for the help with this, Munk! Don't think I would've figured it out on my own, not by simply staring at the documentation, haha. And now that I've seen how secure state handlers and state drivers work, it'll be a lot easier to implement conditional visibility later! Woo!
  Reply With Quote
04-11-16, 01:46 PM   #16
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
The secure environment normally works just fine, without these issues. I'm using a very similar approach to completely replace the spell flyout and that works without fault. It's just the implementation of the action bars are really jacked into everything. I guess this is the reason most action bar replacements resort to using community-created libs and just stuff the default bars into a hidden frame. They are pretty annoying to deal with compared to creating your own bars.
__________________
  Reply With Quote
04-11-16, 02:01 PM   #17
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Heheh yeah, I've noticed that a lot of the older game code at least, the core GUI elements. There's a lot of moments where you never know when you're going to encounter a hardcoded function call overriding whatever you're trying to do with the core elements. So you either have to override it completely or try a long-winding workaround!
  Reply With Quote
04-11-16, 02:48 PM   #18
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Whats that execute snippet is good for? You should be able to call the GetFrameRef function in any secure environemnt, also self is a valid frame reference to the handler itself. Or is it only to minimalize the number of GetFrameRef calls?

Last edited by Resike : 04-11-16 at 02:50 PM.
  Reply With Quote
04-11-16, 03:42 PM   #19
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
Originally Posted by Resike View Post
Whats that execute snippet is good for? You should be able to call the GetFrameRef function in any secure environemnt, also self is a valid frame reference to the handler itself. Or is it only to minimalize the number of GetFrameRef calls?
In that context, self will be overwritten and refer to the wrapped frame, which is why the explicit Holder is there. And yes, they are simply globally defined in that environment to remove a bunch of GetFrameRef calls. This is not at all necessary, just makes the code more readable.
__________________
  Reply With Quote
04-15-16, 01:56 PM   #20
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by MunkDev View Post
In that context, self will be overwritten and refer to the wrapped frame, which is why the explicit Holder is there. And yes, they are simply globally defined in that environment to remove a bunch of GetFrameRef calls. This is not at all necessary, just makes the code more readable.
Well me likey everything which can reduce call times. Gonna use it from now.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » How can I do this without causing a taint?


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off