View Single Post
05-23-11, 02:17 PM   #6
Saiket
A Chromatic Dragonspawn
 
Saiket's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 154
Your original code creates at least three garbage tables every time one of the hooked functions is called. Some of those hooked functions, like ActionButton_UpdateUsable, get called a lot: once per visible action button for each action that becomes usable/unusable. Every action button is registered for ACTIONBAR_UPDATE_USABLE, and each one responds by calling ActionButton_UpdateUsable separately.



Imagine you have 20 action buttons visible, and 10 of them become unusable when you unstealth. If you unstealth, ACTIONBAR_UPDATE_USABLE fires 10 times, and ActionButton_UpdateUsable gets called 10*20 = 200 times. Then, your hook creates one garbage table each call:
Code:
hooksecurefunc("ActionButton_UpdateUsable", function(self)
                for i, v in pairs({"ActionButton", "MultiBarBottomLeftButton", "MultiBarBottomRightButton", "MultiBarLeftButton", "MultiBarRightButton", "MultiCastActionButton", "MultiCastSummonSpellButton", "MultiCastRecallSpellButton"}) do
Then, BorderBeautification gets called for each of those 8 object types, totaling 200*8 = 1600 calls. Each of those calls creates two more garbage tables for top and bottom color:
Code:
local BorderBeautification = function(object)
       
                if IsAddOnLoaded("FacePaint") and FacePaint then
                        tc = {r = topcolor.r, g = topcolor.g, b = topcolor.b, a = topalpha}
                        bc = {r = bottomcolor.r, g = bottomcolor.g, b = bottomcolor.b, a = bottomalpha}
                else
                        tc = {r = BorderColors.top.r, g = BorderColors.top.g, b = BorderColors.top.b, a = BorderColors.top.a}
                        bc = {r = BorderColors.bot.r, g = BorderColors.bot.g, b = BorderColors.bot.b, a = BorderColors.bot.a}
                end
In total, 3400 garbage tables created by unstealthing in this case--200 object list tables plus 1600*2 color tables.

That explains why your memory usage ballooned when you spammed stealth/unstealth. The other technique in your second version is more efficient because it doesn't recolor the same button multiple times per event like the first did. It still would still create a fair number of garbage color tables though.



I suggest using the preexisting topcolor/bottomcolor and BorderColors tables instead of copying them each time. Using the second version of your code, here's an updated colorit function that doesn't create any new tables:
lua Code:
  1. local colorit = function(object)
  2.     local tc, bc, ta, ba;
  3.     if IsAddOnLoaded("FacePaint") and FacePaint.enable and not FacePaint.invert then
  4.         tc, ta = topcolor, topalpha;
  5.         bc, ba = bottomcolor, bottomalpha;
  6.     elseif IsAddOnLoaded("FacePaint") and FacePaint.enable and FacePaint.invert then
  7.         tc, ta = bottomcolor, bottomalpha;
  8.         bc, ba = topcolor, topalpha;
  9.     else
  10.         tc, bc = bordercolor.top, bordercolor.bot;
  11.         ta, ba = tc.a, bc.a;
  12.     end
  13.     object:SetGradientAlpha("VERTICAL", bc.r, bc.g, bc.b, ba, tc.r, tc.g, tc.b, ta)
  14. end
  Reply With Quote