Quantcast

Added a couple of minor performance improvements (caching), experimental. Highly explosive.

Daniel Yates [06-27-11 - 15:23]
Added a couple of minor performance improvements (caching), experimental. Highly explosive.
Filename
Modules/Auras.lua
Modules/Buttons.lua
Modules/ButtonsConfig.lua
diff --git a/Modules/Auras.lua b/Modules/Auras.lua
index 9a583ac..5f432f9 100644
--- a/Modules/Auras.lua
+++ b/Modules/Auras.lua
@@ -221,6 +221,7 @@ function ModuleFrame:MergeAuraAction(actionTable, actionData)
 	return actionTable;
 end
 --[[
+
 ----------------------------------------------------------------------------------------------------
 CreateAuraAction

@@ -286,4 +287,4 @@ function ModuleFrame:OnInitialize()
 	CoreFrame:RegisterModuleEvent("OnAuraHide");
 	-- Done.
 	return true;
-end
\ No newline at end of file
+end
diff --git a/Modules/Buttons.lua b/Modules/Buttons.lua
index e9eebda..967cdb8 100644
--- a/Modules/Buttons.lua
+++ b/Modules/Buttons.lua
@@ -11,17 +11,35 @@ local Modules          = CoreFrame.Modules;
 ----------------------------------------------------------------------------------------------------
 Variables
 	Buttons            Stores all registered buttons in a table.
+	ButtonsBySlot      All button objects by their action/slot ID.
 	ButtonData         Stores the switches for each button - whether it should glow, etc.
+	ButtonCache        Stores a cache of the aura actions that apply to specific action buttons.
 	ThrottleActive     Stores the current throttle state.
 	ThrottlePending    Stores the status of any pending mass updates.
 	ThrottleTimer      Stores the current throttle timer for mass updates.
 ----------------------------------------------------------------------------------------------------
 --]]
 local Buttons          = {};
+local ButtonsBySlot    = {};
 local ButtonData       = {};
+local ButtonCache      = setmetatable({}, { __mode = "k" });
 local ThrottleActive   = nil;
 local ThrottlePending  = nil;
 local ThrottleTimer    = 0;
+-- Upvalues.
+local unpack, setmetatable, ActionButton_ShowOverlayGlow, ActionButton_HideOverlayGlow, wipe, type, GetActionInfo,
+	GetMacroSpell, GetMacroItem, pairs, IsSpellOVerlayed, hooksecurefunc = unpack, setmetatable,
+	ActionButton_ShowOverlayGlow, ActionButton_HideOverlayGlow, wipe, type, GetActionInfo, GetMacroSpell, GetMacroItem,
+	pairs, IsSpellOVerlayed, hooksecurefunc;
+-- Caches.
+local spellcache = setmetatable({}, {__index=function(t,v) local a = {GetSpellInfo(v)} if GetSpellInfo(v) then t[v] = a end return a end});
+local function GetSpellInfo(a)
+    return unpack(spellcache[a]);
+end
+local itemcache = setmetatable({}, {__index=function(t,v) local a = {GetItemInfo(v)} if GetItemInfo(v) then t[v] = a end return a end});
+local function GetItemInfo(a)
+    return unpack(spellcache[a]);
+end
 --[[
 ----------------------------------------------------------------------------------------------------
 OnButtonUpdate
@@ -86,37 +104,60 @@ function ModuleFrame:ProcessButtonActions(button)
 		ButtonData[buttonID] = buttonData;
 		return;
 	end
+	-- Make sure button is cached by slot.
+	ButtonsBySlot[buttonAction] = button;
 	-- Get the button action data.
 	buttonActionType, buttonActionID = GetActionInfo(buttonAction);
 	-- Get macro names if needed.
 	if(buttonActionType == "macro") then
 		buttonMacro = GetMacroSpell(buttonActionID) or GetMacroItem(buttonActionID);
 	end
+	-- Create cache if needed.
+	if(not ButtonCache[buttonAction]) then
+		ButtonCache[buttonAction] = {};
+	end
+	local buttonCache = ButtonCache[buttonAction];
 	-- Right, first off we need to go over all the auras see if they're linked to this one.
 	for auraID, _ in pairs(CustomAuras) do
+		-- Update cache if needed...
+		if(not buttonCache[auraID]) then
+			buttonCache[auraID] = {};
+		end
+		local auraCache = buttonCache[auraID];
 		-- Aura needs to be active.
 		if(Modules.Auras:IsAuraShown(auraID)) then
 			-- And go over the actions.
 			for auraActionID, auraActionData in pairs(Modules.Auras:GetAuraActions(auraID)) do
 				-- Action needs to be a valid ID (> 0)
 				if(auraActionData["id"] and auraActionData["id"] > 0) then
-					-- If the type/data keys match, or this is a macro/spell combo then continue.
-					if(buttonActionType == auraActionData["type"]
-					or (buttonActionType == "macro" and auraActionData["type"] == "spell")
-					or (buttonActionType == "macro" and auraActionData["type"] == "item")) then
-						-- Compare ID's. If they match, we're golden. If they don't, do macro
-						-- comparisons.
-						if((buttonActionID == auraActionData["id"]
-						and buttonActionType == auraActionData["type"])
-						or buttonMacro and (auraActionData["type"] == "spell"
-						and GetSpellInfo(auraActionData["id"]) == buttonMacro
-						or auraActionData["type"] == "item"
-						and GetItemInfo(auraActionData["id"]) == buttonMacro)) then
-							-- Enable glows if the action says so.
-							Modules.Auras:MergeAuraAction(buttonData, auraActionData);
-							-- Fire the OnAuraDisplay event.
-							CoreFrame:FireModuleEvent("OnButtonDisplayAura", buttonID, auraID,
-								auraActionData, auraActionID);
+					-- Check cache for a shortcut.
+					if(auraCache[auraActionID] == true and CoreFrame:GetModuleSetting("Buttons", "EnableCache")) then
+						-- Enable glows if the action says so.
+						Modules.Auras:MergeAuraAction(buttonData, auraActionData);
+						-- Fire the OnAuraDisplay event.
+						CoreFrame:FireModuleEvent("OnButtonDisplayAura", buttonID, auraID, auraActionData,
+							auraActionID);
+					else
+						-- If the type/data keys match, or this is a macro/spell combo then continue.
+						if(buttonActionType == auraActionData["type"]
+						or (buttonActionType == "macro" and auraActionData["type"] == "spell")
+						or (buttonActionType == "macro" and auraActionData["type"] == "item")) then
+							-- Compare ID's. If they match, we're golden. If they don't, do macro
+							-- comparisons.
+							if((buttonActionID == auraActionData["id"]
+							and buttonActionType == auraActionData["type"])
+							or buttonMacro and (auraActionData["type"] == "spell"
+							and GetSpellInfo(auraActionData["id"]) == buttonMacro
+							or auraActionData["type"] == "item"
+							and GetItemInfo(auraActionData["id"]) == buttonMacro)) then
+								-- Enable glows if the action says so.
+								Modules.Auras:MergeAuraAction(buttonData, auraActionData);
+								-- Fire the OnAuraDisplay event.
+								CoreFrame:FireModuleEvent("OnButtonDisplayAura", buttonID, auraID,
+									auraActionData, auraActionID);
+								-- Cache it.
+								auraCache[auraActionID] = true;
+							end
 						end
 					end
 				end
@@ -140,6 +181,7 @@ function ModuleFrame:ProcessButtonActions(button)
 				or GetItemInfo(blizzAuraID) == buttonMacro)) then
 					-- Yeah, it's a match. Timers/Stacks aren't on for blizz ones.
 					buttonData["glow"] = true;
+					break; -- Break early, it doesn't matter if any others are glowing or not.
 				end
 			end
 		end
@@ -274,7 +316,8 @@ function ModuleFrame:FixSettings(force)
 		PowerAurasButtons_SettingsDB["Buttons"] = {
 			["Throttle"] = 0.05,
 			["RegisterBlizzardButtons"] = true,
-			["ShowBlizzardGlows"] = true
+			["ShowBlizzardGlows"] = true,
+			["EnableCache"] = true,
 		};
 	end
 end
@@ -340,6 +383,23 @@ function ModuleFrame:OnInitialize()
 	CoreFrame:RegisterModuleEventListener("OnAuraShow", ModuleFrame, ModuleFrame.OnUpdateTrigger);
 	CoreFrame:RegisterModuleEventListener("OnAuraHide", ModuleFrame, ModuleFrame.OnUpdateTrigger);
 	CoreFrame:RegisterModuleEventListener("OnActionCreate", ModuleFrame);
+	-- Cache clearing functions, ABS fires even if macros are updated!
+	if(CoreFrame:GetModuleSetting("Buttons", "EnableCache") == true) then
+		CoreFrame:RegisterBlizzEventListener("ACTIONBAR_SLOT_CHANGED", ModuleFrame, function(self, id)
+			-- Cache macros only.
+			local buttonType, macroID = GetActionInfo(id);
+			if(buttonType ~= "macro" or not ButtonsBySlot[id]
+				or not CoreFrame:GetModuleSetting("Buttons", "EnableCache")) then return; end
+			-- Make sure table exists.
+			if(not ButtonCache[id]) then
+				ButtonCache[id] = {};
+			else
+				wipe(ButtonCache[id]);
+			end
+			-- Trigger re-update.
+			ModuleFrame:OnButtonUpdate(ButtonsBySlot[id]);
+		end);
+	end
 	-- Done.
 	return true;
-end
\ No newline at end of file
+end
diff --git a/Modules/ButtonsConfig.lua b/Modules/ButtonsConfig.lua
index 0f09cfb..7a06736 100644
--- a/Modules/ButtonsConfig.lua
+++ b/Modules/ButtonsConfig.lua
@@ -113,6 +113,20 @@ function ModuleFrame:OnCreateInterfaceOptionsFrame(name)
 		-- Save.
 		CoreFrame:SetModuleSetting("Buttons", "ShowBlizzardGlows", self:GetChecked());
 	end);
+	-- And another.
+	InterfaceOptions.Cache = CreateFrame("CheckButton", "PowerAurasButtons_ButtonsCacheActions",
+		InterfaceOptions, "ChatConfigCheckButtonTemplate");
+	InterfaceOptions.Cache:SetPoint("TOPLEFT", InterfaceOptions, "TOPLEFT", 10, -165);
+	PowerAurasButtons_ButtonsCacheActionsText:SetText(CoreFrame.L["Enable Action Cache"]);
+	InterfaceOptions.Cache:SetChecked(
+		CoreFrame:GetModuleSetting("Buttons", "EnableCache"));
+	-- Save on click.
+	InterfaceOptions.Cache:SetScript("OnClick", function(self)
+		-- Requires a reload to take effect, so get a glowbox ready and running.
+		Modules.Config:CreateGlowBoxWidget(InterfaceOptions);
+		-- Save.
+		CoreFrame:SetModuleSetting("Buttons", "EnableCache", self:GetChecked());
+	end);
 	-- Tooltips.
 	Modules.Config:RegisterConfigTooltip(InterfaceOptions.ThrottleSlider, {
 		title = "Update Throttle",
@@ -128,6 +142,10 @@ function ModuleFrame:OnCreateInterfaceOptionsFrame(name)
 		title = "Show Blizzard Glows |cFFFF0000*BETA*|r",
 		text = "Select this if you want Blizzard's default action button glows to be displayed."
 	});
+	Modules.Config:RegisterConfigTooltip(InterfaceOptions.Cache, {
+		title = "Enable Action Cache",
+		text = "Attempts to cache data to speed up performance, may cause issues."
+	});
 end
 --[[
 ----------------------------------------------------------------------------------------------------
@@ -142,4 +160,4 @@ function ModuleFrame:OnInitialize()
 	CoreFrame:RegisterModuleEventListener("OnCreateInterfaceOptionsFrame", ModuleFrame);
 	-- Done.
 	return true;
-end
\ No newline at end of file
+end