diff core.lua @ 125:a9cf9b2fbf9b

- Fix interactions with AddonLoader. - Plugins get a :Print with a clickable prefix, with overrideable behaviors. - 'Deactivate' event gets a [wrapper around] current raiders table. - Fix sorting bug in player history data. - Smarter status line text when viewing unfiltered history. - Do not disable history regeneration button when current history is empty. - :BuildMainDisplay can handle the CLI args now.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Sun, 19 Aug 2012 21:08:59 -0400
parents fb4bda3ad05c
children dc39ce56a62d
line wrap: on
line diff
--- a/core.lua	Fri Aug 17 02:48:13 2012 -0400
+++ b/core.lua	Sun Aug 19 21:08:59 2012 -0400
@@ -21,6 +21,8 @@
 -    join       time player joined the raid (or first time we've seen them)
 -    leave      time player left the raid (or time we've left the raid, if
                 'online' is not 'no_longer')
+-    needinfo   true if haven't yet gotten close enough to player to request
+                unit data; SHOULD be missing
 
 Common g_loot entry indices:
 - kind          time/boss/loot
@@ -444,8 +446,10 @@
 	--
 	-- Returns an opaque token and a matching number.  Calling tostring() on
 	-- the token will yield a formatted clickable string that can be displayed
-	-- in chat.  The MethodName and raw function callbacks will both be
-	-- passed the addon table and the same matching number.
+	-- in local chat.  Clicking a tab_title hyperlink opens the GUI to that
+	-- tab; the MethodName and raw function callbacks will be passed the addon
+	-- table, the same matching number, and the mouse button (ala OnClick) as
+	-- arguments.
 	--
 	-- This is largely an excuse to fool around with Lua data constructs.
 	function addon.format_hypertext (text, color, func)
@@ -473,14 +477,15 @@
 		if ltype ~= "OuroLoot" then return end
 		arg = tonumber(arg)
 		local f = func_map[text_map[arg]]
-		if type(f) == 'function' then
-			f (addon, arg)
-		elseif type(f) == 'string' then
+		local t = type(f)
+		if t == 'string' then
 			if type(addon[f]) == 'function' then
-				addon[f](addon,arg)         -- method name
+				addon[f](addon,arg,mousebutton)   -- method
 			else
-				addon:BuildMainDisplay(f)   -- tab title fragment
+				addon:BuildMainDisplay(f)         -- tab title fragment
 			end
+		elseif t == 'function' then
+			f (addon, arg, mousebutton)
 		end
 	end)
 
@@ -754,7 +759,7 @@
 	g_restore_p = OuroLootSV ~= nil
 	self.dprint('flow', "oninit sets restore as", g_restore_p)
 
-	-- Primarily for plugins, but can be of use to me also...
+	-- Primarily for plugins, but can be of use to me also...  LCALLBACK
 	self.callbacks = LibStub("CallbackHandler-1.0"):New(self)
 	--function self.callbacks:OnUsed (target_aka_self, eventname)  end
 	--function self.callbacks:OnUnused (target_aka_self, eventname)  end
@@ -870,11 +875,12 @@
 	self:RegisterEvent("PLAYER_LOGOUT")
 	self:RegisterEvent(RAID_ROSTER_UPDATE_EVENT,"RAID_ROSTER_UPDATE")
 
-	-- Cribbed from Talented.  I like the way jerry thinks: the first string
-	-- argument can be a format spec for the remainder of the arguments.
-	-- AceConsole:Printf isn't used because we can't specify a prefix without
-	-- jumping through ridonkulous hoops.  The part about overriding :Print
-	-- with a version using prefix hyperlinks is my fault.
+	-- This Print cribbed from Talented.  I like the way jerry thinks: the
+	-- first string argument can be a format spec for the remainder of the
+	-- arguments.  AceConsole:Printf isn't used because we can't specify a
+	-- prefix without jumping through ridonkulous hoops.
+	--
+	-- Everything dealing with a prefix hyperlink is my fault.
 	--
 	-- CFPrint added instead of the usual Print testing of the first arg for
 	-- frame-ness, which would slow down all printing and only rarely be useful.
@@ -1012,7 +1018,10 @@
 	frame creation.
 	]]
 	local bliz = CreateFrame("Frame")
-	bliz.name = "Ouro Loot"
+	bliz.name = "Ouro Loot"  -- must match X-LoadOn-InterfaceOptions
+	if AddonLoader then
+		AddonLoader:RemoveInterfaceOptions(bliz.name)
+	end
 	bliz:SetScript("OnShow", function(_b)
 		local button = CreateFrame("Button",nil,_b,"UIPanelButtonTemplate")
 		button:SetWidth(150)
@@ -1020,9 +1029,9 @@
 		button:SetScript("OnClick", function()
 			InterfaceOptionsFrameCancel:Click()
 			HideUIPanel(GameMenuFrame)
-			addon:OpenMainDisplayToTab"Options"
+			addon:BuildMainDisplay('opt')
 		end)
-		button:SetText('"/ouroloot opt"')
+		button:SetText('"/ouroloot options"')
 		button:SetPoint("TOPLEFT",20,-20)
 		_b:SetScript("OnShow",nil)
 	end)
@@ -1048,32 +1057,67 @@
 	- db:  (OUT) AceDB object, set during init.
 	- opts:  (OUT) Pointer to plugin's "db.profile" subtable.
 
-	OnInitialize, [default_]OnEnable, register_text_generator, register_tab_control
-	are all inherited.
+	Inherited unchanged:
+
+	Inherited module variants:
+	- OnInitialize, OnEnable
+	- register_text_generator, register_tab_control:  also flag plugin as
+		a text-generating module in main addon
 	]]
 	local prototype = {}
-	local registry
+	local textgen_registry, chat_prefixes, chat_codes
 
 	-- By default, no plugins.  First one in sets up code for any after.
-	addon.get_plugin = flib.nullfunc
-
-	-- Fires before the plugin's own OnEnable (inherited or otherwise).
+	addon.get_textgen_plugin = flib.nullfunc
+
+	-- Called as part of NewModule, after embedding and metas are done.
+	-- Mostly this is one-time setup stuff that we don't need until a plugin
+	-- is actually built.
 	function addon:OnModuleCreated (plugin)
-		if not registry then
-			registry = {}
-			addon.get_plugin = function(a,t) return registry[t] end
-			prototype.register_text_generator = function(p,t,...)
-				registry[t] = p
-				return addon:register_text_generator(t,...)
-			end
-			prototype.register_tab_control = function(p,t,...)
-				registry[t] = p
-				return addon:register_tab_control(t,...)
+		textgen_registry, chat_prefixes, chat_codes = {}, {}, {}
+		addon.get_textgen_plugin = function(a,t)
+			return textgen_registry[t]
+		end
+		prototype.register_text_generator = function(p,t,...)
+			textgen_registry[t] = p
+			return addon:register_text_generator(t,...)
+		end
+		prototype.register_tab_control = function(p,t,...)
+			textgen_registry[t] = p
+			return addon:register_tab_control(t,...)
+		end
+
+		function addon:ModulePrefixClick (codenum, mousebutton)
+			local plugin = assert(chat_codes[codenum])
+			if not plugin:IsEnabled() then return end
+			if mousebutton == 'LeftButton' then
+				if plugin.PrefixLeftClick then
+					plugin:PrefixLeftClick(codenum)
+				else
+					self:BuildMainDisplay()
+				end
+			elseif mousebutton == 'RightButton' then
+				local uniqueval = plugin.name
+				if plugin.PrefixRightClick then
+					uniqueval = plugin:PrefixRightClick(codenum)
+				end
+				self:BuildMainDisplay('opt',uniqueval)
 			end
 		end
+		function addon:OnModuleCreated (plugin)
+			local token, code = self.format_hypertext (plugin.moduleName,
+				--[[heirloom]]7, "ModulePrefixClick")
+			chat_prefixes[plugin] = token
+			chat_codes[code] = plugin
+			-- remove the libraries' embedded pointers so that the prototype
+			-- can be inherited
+			plugin.Print = nil
+		end
+
+		return self:OnModuleCreated(plugin)
 	end
 
-	local function module_OnInit (plugin)
+	function prototype.OnInitialize (plugin)
 		if plugin.option_defaults then
 			plugin.db = addon.db:RegisterNamespace (plugin.moduleName, plugin.option_defaults)
 			plugin.opts = plugin.db.profile
@@ -1081,14 +1125,14 @@
 		end
 	end
 
-	local function module_OnEnable (plugin)
-	end
-
-	local function module_GetOption (plugin, info)
+	--function prototype.OnEnable (plugin)
+	--end
+
+	function prototype.GetOption (plugin, info)
 		local name = info[#info]
 		return plugin.db.profile[name]
 	end
-	local function module_SetOption (plugin, info, value)
+	function prototype.SetOption (plugin, info, value)
 		local name = info[#info]
 		plugin.db.profile[name] = value
 		local arg = info.arg
@@ -1097,11 +1141,16 @@
 		end
 	end
 
-	prototype.OnInitialize = module_OnInit
-	prototype.OnEnable = module_OnEnable
-	prototype.default_OnEnable = module_OnEnable
-	prototype.GetOption = module_GetOption
-	prototype.SetOption = module_SetOption
+	-- may eventually just rework the main print routines and inherit all 3
+	function prototype.Print (plugin, str, ...)
+		local AC = LibStub("AceConsole-3.0")
+		local ps = tostring(chat_prefixes[plugin])
+		if type(str) == 'string' and str:find("%", nil, --[[plainmatch=]]true) then
+			return AC:Print (ps, str:format(...))
+		else
+			return AC:Print (ps, str, ...)
+		end
+	end
 
 	addon:SetDefaultModuleLibraries("AceConsole-3.0")
 	addon:SetDefaultModulePrototype(prototype)
@@ -1139,8 +1188,9 @@
     The two boolean predicates are self-explanatory.  The threshold is an
     ITEM_QUALITY_* constant integer.
 
-'Deactivate'
-    After all system events have been unregistered.
+'Deactivate', raiderdata
+    After all system events have been unregistered.  Argument is a holder of
+	the current g_loot.raiders table (in 'raidersnap').
 
 'Reset'
     Clicking "Clear Loot", after all data manipulation is finished.
@@ -1930,7 +1980,10 @@
 	self:UnregisterEvent("PLAYER_ENTERING_WORLD")
 	self:UnregisterEvent("CHAT_MSG_LOOT")
 	_LFR_suppressing = nil
-	self:Fire ('Deactivate')
+	-- Passing .raiders directly doesn't work with a proxy (again, WTB Lua
+	-- 5.2 and its __pairs iterators).  Give it the same structure as a boss
+	-- entry instead.
+	self:Fire ('Deactivate', { raidersnap = g_loot.raiders })
 	self:Print("Deactivated.")
 end
 
@@ -3057,7 +3110,7 @@
 		return L > R    -- reverse of normal order, newest first
 	end
 	local function sort_player (p)
-		local new_uniques, uniques_bywhen, when_array = new(), new(), new()
+		local new_uniques, uniques_bywhen, when_array = {}, new(), new()
 		for u,tstamp in pairs(p.when) do
 			uniques_bywhen[tstamp] = u
 			when_array[#when_array+1] = tstamp
@@ -3067,7 +3120,8 @@
 			new_uniques[i] = uniques_bywhen[tstamp]
 		end
 		p.unique = new_uniques
-		del(new_uniques)  del(uniques_bywhen)  del(when_array)
+		del(uniques_bywhen)
+		del(when_array)
 	end
 
 	function addon:repair_history_integrity()