comparison 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
comparison
equal deleted inserted replaced
124:1a248faf1a3b 125:a9cf9b2fbf9b
19 - online 'online', 'offline', 'no_longer' [no longer in raid group] 19 - online 'online', 'offline', 'no_longer' [no longer in raid group]
20 [both of these next two fields use time_t values:] 20 [both of these next two fields use time_t values:]
21 - join time player joined the raid (or first time we've seen them) 21 - join time player joined the raid (or first time we've seen them)
22 - leave time player left the raid (or time we've left the raid, if 22 - leave time player left the raid (or time we've left the raid, if
23 'online' is not 'no_longer') 23 'online' is not 'no_longer')
24 - needinfo true if haven't yet gotten close enough to player to request
25 unit data; SHOULD be missing
24 26
25 Common g_loot entry indices: 27 Common g_loot entry indices:
26 - kind time/boss/loot 28 - kind time/boss/loot
27 - hour 0-23, on the *physical instance server*, not the realm server 29 - hour 0-23, on the *physical instance server*, not the realm server
28 - minute 0-59, ditto 30 - minute 0-59, ditto
442 -- COLOR can be ITEM_QUALITY_* or a formatting string ("|cff...") 444 -- COLOR can be ITEM_QUALITY_* or a formatting string ("|cff...")
443 -- FUNC can be "MethodName", "tab_title", or a function 445 -- FUNC can be "MethodName", "tab_title", or a function
444 -- 446 --
445 -- Returns an opaque token and a matching number. Calling tostring() on 447 -- Returns an opaque token and a matching number. Calling tostring() on
446 -- the token will yield a formatted clickable string that can be displayed 448 -- the token will yield a formatted clickable string that can be displayed
447 -- in chat. The MethodName and raw function callbacks will both be 449 -- in local chat. Clicking a tab_title hyperlink opens the GUI to that
448 -- passed the addon table and the same matching number. 450 -- tab; the MethodName and raw function callbacks will be passed the addon
451 -- table, the same matching number, and the mouse button (ala OnClick) as
452 -- arguments.
449 -- 453 --
450 -- This is largely an excuse to fool around with Lua data constructs. 454 -- This is largely an excuse to fool around with Lua data constructs.
451 function addon.format_hypertext (text, color, func) 455 function addon.format_hypertext (text, color, func)
452 local ret = newproxy(base) 456 local ret = newproxy(base)
453 local num = #text_map + 1 457 local num = #text_map + 1
471 DEFAULT_CHAT_FRAME:HookScript("OnHyperlinkClick", function(self, link, fullstring, mousebutton) 475 DEFAULT_CHAT_FRAME:HookScript("OnHyperlinkClick", function(self, link, fullstring, mousebutton)
472 local ltype, arg = strsplit(":",link) 476 local ltype, arg = strsplit(":",link)
473 if ltype ~= "OuroLoot" then return end 477 if ltype ~= "OuroLoot" then return end
474 arg = tonumber(arg) 478 arg = tonumber(arg)
475 local f = func_map[text_map[arg]] 479 local f = func_map[text_map[arg]]
476 if type(f) == 'function' then 480 local t = type(f)
477 f (addon, arg) 481 if t == 'string' then
478 elseif type(f) == 'string' then
479 if type(addon[f]) == 'function' then 482 if type(addon[f]) == 'function' then
480 addon[f](addon,arg) -- method name 483 addon[f](addon,arg,mousebutton) -- method
481 else 484 else
482 addon:BuildMainDisplay(f) -- tab title fragment 485 addon:BuildMainDisplay(f) -- tab title fragment
483 end 486 end
487 elseif t == 'function' then
488 f (addon, arg, mousebutton)
484 end 489 end
485 end) 490 end)
486 491
487 local old = ItemRefTooltip.SetHyperlink 492 local old = ItemRefTooltip.SetHyperlink
488 function ItemRefTooltip:SetHyperlink (link, ...) 493 function ItemRefTooltip:SetHyperlink (link, ...)
752 -- relogging during a raid and already have collected loot data 757 -- relogging during a raid and already have collected loot data
753 local OuroLootSV = OuroLootSV 758 local OuroLootSV = OuroLootSV
754 g_restore_p = OuroLootSV ~= nil 759 g_restore_p = OuroLootSV ~= nil
755 self.dprint('flow', "oninit sets restore as", g_restore_p) 760 self.dprint('flow', "oninit sets restore as", g_restore_p)
756 761
757 -- Primarily for plugins, but can be of use to me also... 762 -- Primarily for plugins, but can be of use to me also... LCALLBACK
758 self.callbacks = LibStub("CallbackHandler-1.0"):New(self) 763 self.callbacks = LibStub("CallbackHandler-1.0"):New(self)
759 --function self.callbacks:OnUsed (target_aka_self, eventname) end 764 --function self.callbacks:OnUsed (target_aka_self, eventname) end
760 --function self.callbacks:OnUnused (target_aka_self, eventname) end 765 --function self.callbacks:OnUnused (target_aka_self, eventname) end
761 766
762 if _G.OuroLootOptsDB == nil then 767 if _G.OuroLootOptsDB == nil then
868 873
869 function addon:OnEnable() 874 function addon:OnEnable()
870 self:RegisterEvent("PLAYER_LOGOUT") 875 self:RegisterEvent("PLAYER_LOGOUT")
871 self:RegisterEvent(RAID_ROSTER_UPDATE_EVENT,"RAID_ROSTER_UPDATE") 876 self:RegisterEvent(RAID_ROSTER_UPDATE_EVENT,"RAID_ROSTER_UPDATE")
872 877
873 -- Cribbed from Talented. I like the way jerry thinks: the first string 878 -- This Print cribbed from Talented. I like the way jerry thinks: the
874 -- argument can be a format spec for the remainder of the arguments. 879 -- first string argument can be a format spec for the remainder of the
875 -- AceConsole:Printf isn't used because we can't specify a prefix without 880 -- arguments. AceConsole:Printf isn't used because we can't specify a
876 -- jumping through ridonkulous hoops. The part about overriding :Print 881 -- prefix without jumping through ridonkulous hoops.
877 -- with a version using prefix hyperlinks is my fault. 882 --
883 -- Everything dealing with a prefix hyperlink is my fault.
878 -- 884 --
879 -- CFPrint added instead of the usual Print testing of the first arg for 885 -- CFPrint added instead of the usual Print testing of the first arg for
880 -- frame-ness, which would slow down all printing and only rarely be useful. 886 -- frame-ness, which would slow down all printing and only rarely be useful.
881 -- 887 --
882 -- There is no ITEM_QUALITY_LEGENDARY constant. Sigh. 888 -- There is no ITEM_QUALITY_LEGENDARY constant. Sigh.
1010 Stick something in the Blizzard addons options list, where most users 1016 Stick something in the Blizzard addons options list, where most users
1011 will probably look these days. Try to be conservative about needless 1017 will probably look these days. Try to be conservative about needless
1012 frame creation. 1018 frame creation.
1013 ]] 1019 ]]
1014 local bliz = CreateFrame("Frame") 1020 local bliz = CreateFrame("Frame")
1015 bliz.name = "Ouro Loot" 1021 bliz.name = "Ouro Loot" -- must match X-LoadOn-InterfaceOptions
1022 if AddonLoader then
1023 AddonLoader:RemoveInterfaceOptions(bliz.name)
1024 end
1016 bliz:SetScript("OnShow", function(_b) 1025 bliz:SetScript("OnShow", function(_b)
1017 local button = CreateFrame("Button",nil,_b,"UIPanelButtonTemplate") 1026 local button = CreateFrame("Button",nil,_b,"UIPanelButtonTemplate")
1018 button:SetWidth(150) 1027 button:SetWidth(150)
1019 button:SetHeight(22) 1028 button:SetHeight(22)
1020 button:SetScript("OnClick", function() 1029 button:SetScript("OnClick", function()
1021 InterfaceOptionsFrameCancel:Click() 1030 InterfaceOptionsFrameCancel:Click()
1022 HideUIPanel(GameMenuFrame) 1031 HideUIPanel(GameMenuFrame)
1023 addon:OpenMainDisplayToTab"Options" 1032 addon:BuildMainDisplay('opt')
1024 end) 1033 end)
1025 button:SetText('"/ouroloot opt"') 1034 button:SetText('"/ouroloot options"')
1026 button:SetPoint("TOPLEFT",20,-20) 1035 button:SetPoint("TOPLEFT",20,-20)
1027 _b:SetScript("OnShow",nil) 1036 _b:SetScript("OnShow",nil)
1028 end) 1037 end)
1029 InterfaceOptions_AddCategory(bliz) 1038 InterfaceOptions_AddCategory(bliz)
1030 1039
1046 Module support (aka plugins). Field names with special meanings: 1055 Module support (aka plugins). Field names with special meanings:
1047 - option_defaults: (IN) Standard AceDB-style table. Use a profiles key! 1056 - option_defaults: (IN) Standard AceDB-style table. Use a profiles key!
1048 - db: (OUT) AceDB object, set during init. 1057 - db: (OUT) AceDB object, set during init.
1049 - opts: (OUT) Pointer to plugin's "db.profile" subtable. 1058 - opts: (OUT) Pointer to plugin's "db.profile" subtable.
1050 1059
1051 OnInitialize, [default_]OnEnable, register_text_generator, register_tab_control 1060 Inherited unchanged:
1052 are all inherited. 1061
1062 Inherited module variants:
1063 - OnInitialize, OnEnable
1064 - register_text_generator, register_tab_control: also flag plugin as
1065 a text-generating module in main addon
1053 ]] 1066 ]]
1054 local prototype = {} 1067 local prototype = {}
1055 local registry 1068 local textgen_registry, chat_prefixes, chat_codes
1056 1069
1057 -- By default, no plugins. First one in sets up code for any after. 1070 -- By default, no plugins. First one in sets up code for any after.
1058 addon.get_plugin = flib.nullfunc 1071 addon.get_textgen_plugin = flib.nullfunc
1059 1072
1060 -- Fires before the plugin's own OnEnable (inherited or otherwise). 1073 -- Called as part of NewModule, after embedding and metas are done.
1074 -- Mostly this is one-time setup stuff that we don't need until a plugin
1075 -- is actually built.
1061 function addon:OnModuleCreated (plugin) 1076 function addon:OnModuleCreated (plugin)
1062 if not registry then 1077 textgen_registry, chat_prefixes, chat_codes = {}, {}, {}
1063 registry = {} 1078 addon.get_textgen_plugin = function(a,t)
1064 addon.get_plugin = function(a,t) return registry[t] end 1079 return textgen_registry[t]
1065 prototype.register_text_generator = function(p,t,...) 1080 end
1066 registry[t] = p 1081 prototype.register_text_generator = function(p,t,...)
1067 return addon:register_text_generator(t,...) 1082 textgen_registry[t] = p
1068 end 1083 return addon:register_text_generator(t,...)
1069 prototype.register_tab_control = function(p,t,...) 1084 end
1070 registry[t] = p 1085 prototype.register_tab_control = function(p,t,...)
1071 return addon:register_tab_control(t,...) 1086 textgen_registry[t] = p
1072 end 1087 return addon:register_tab_control(t,...)
1073 end 1088 end
1074 end 1089
1075 1090 function addon:ModulePrefixClick (codenum, mousebutton)
1076 local function module_OnInit (plugin) 1091 local plugin = assert(chat_codes[codenum])
1092 if not plugin:IsEnabled() then return end
1093 if mousebutton == 'LeftButton' then
1094 if plugin.PrefixLeftClick then
1095 plugin:PrefixLeftClick(codenum)
1096 else
1097 self:BuildMainDisplay()
1098 end
1099 elseif mousebutton == 'RightButton' then
1100 local uniqueval = plugin.name
1101 if plugin.PrefixRightClick then
1102 uniqueval = plugin:PrefixRightClick(codenum)
1103 end
1104 self:BuildMainDisplay('opt',uniqueval)
1105 end
1106 end
1107 function addon:OnModuleCreated (plugin)
1108 local token, code = self.format_hypertext (plugin.moduleName,
1109 --[[heirloom]]7, "ModulePrefixClick")
1110 chat_prefixes[plugin] = token
1111 chat_codes[code] = plugin
1112 -- remove the libraries' embedded pointers so that the prototype
1113 -- can be inherited
1114 plugin.Print = nil
1115 end
1116
1117 return self:OnModuleCreated(plugin)
1118 end
1119
1120 function prototype.OnInitialize (plugin)
1077 if plugin.option_defaults then 1121 if plugin.option_defaults then
1078 plugin.db = addon.db:RegisterNamespace (plugin.moduleName, plugin.option_defaults) 1122 plugin.db = addon.db:RegisterNamespace (plugin.moduleName, plugin.option_defaults)
1079 plugin.opts = plugin.db.profile 1123 plugin.opts = plugin.db.profile
1080 --plugin:SetEnabledState(plugin.db.profile.enabled) if that flag is needed later 1124 --plugin:SetEnabledState(plugin.db.profile.enabled) if that flag is needed later
1081 end 1125 end
1082 end 1126 end
1083 1127
1084 local function module_OnEnable (plugin) 1128 --function prototype.OnEnable (plugin)
1085 end 1129 --end
1086 1130
1087 local function module_GetOption (plugin, info) 1131 function prototype.GetOption (plugin, info)
1088 local name = info[#info] 1132 local name = info[#info]
1089 return plugin.db.profile[name] 1133 return plugin.db.profile[name]
1090 end 1134 end
1091 local function module_SetOption (plugin, info, value) 1135 function prototype.SetOption (plugin, info, value)
1092 local name = info[#info] 1136 local name = info[#info]
1093 plugin.db.profile[name] = value 1137 plugin.db.profile[name] = value
1094 local arg = info.arg 1138 local arg = info.arg
1095 if type(arg) == 'function' then 1139 if type(arg) == 'function' then
1096 plugin[arg](plugin,info) 1140 plugin[arg](plugin,info)
1097 end 1141 end
1098 end 1142 end
1099 1143
1100 prototype.OnInitialize = module_OnInit 1144 -- may eventually just rework the main print routines and inherit all 3
1101 prototype.OnEnable = module_OnEnable 1145 function prototype.Print (plugin, str, ...)
1102 prototype.default_OnEnable = module_OnEnable 1146 local AC = LibStub("AceConsole-3.0")
1103 prototype.GetOption = module_GetOption 1147 local ps = tostring(chat_prefixes[plugin])
1104 prototype.SetOption = module_SetOption 1148 if type(str) == 'string' and str:find("%", nil, --[[plainmatch=]]true) then
1149 return AC:Print (ps, str:format(...))
1150 else
1151 return AC:Print (ps, str, ...)
1152 end
1153 end
1105 1154
1106 addon:SetDefaultModuleLibraries("AceConsole-3.0") 1155 addon:SetDefaultModuleLibraries("AceConsole-3.0")
1107 addon:SetDefaultModulePrototype(prototype) 1156 addon:SetDefaultModulePrototype(prototype)
1108 1157
1109 local err = [[Module '%s' cannot register itself because it failed a required condition: '%s']] 1158 local err = [[Module '%s' cannot register itself because it failed a required condition: '%s']]
1137 1186
1138 'Activate', enabled_p, rebroadcast_p, threshold 1187 'Activate', enabled_p, rebroadcast_p, threshold
1139 The two boolean predicates are self-explanatory. The threshold is an 1188 The two boolean predicates are self-explanatory. The threshold is an
1140 ITEM_QUALITY_* constant integer. 1189 ITEM_QUALITY_* constant integer.
1141 1190
1142 'Deactivate' 1191 'Deactivate', raiderdata
1143 After all system events have been unregistered. 1192 After all system events have been unregistered. Argument is a holder of
1193 the current g_loot.raiders table (in 'raidersnap').
1144 1194
1145 'Reset' 1195 'Reset'
1146 Clicking "Clear Loot", after all data manipulation is finished. 1196 Clicking "Clear Loot", after all data manipulation is finished.
1147 1197
1148 'NewBoss', boss 1198 'NewBoss', boss
1928 self.rebroadcast = false 1978 self.rebroadcast = false
1929 self:UnregisterEvent(RAID_ROSTER_UPDATE_EVENT) 1979 self:UnregisterEvent(RAID_ROSTER_UPDATE_EVENT)
1930 self:UnregisterEvent("PLAYER_ENTERING_WORLD") 1980 self:UnregisterEvent("PLAYER_ENTERING_WORLD")
1931 self:UnregisterEvent("CHAT_MSG_LOOT") 1981 self:UnregisterEvent("CHAT_MSG_LOOT")
1932 _LFR_suppressing = nil 1982 _LFR_suppressing = nil
1933 self:Fire ('Deactivate') 1983 -- Passing .raiders directly doesn't work with a proxy (again, WTB Lua
1984 -- 5.2 and its __pairs iterators). Give it the same structure as a boss
1985 -- entry instead.
1986 self:Fire ('Deactivate', { raidersnap = g_loot.raiders })
1934 self:Print("Deactivated.") 1987 self:Print("Deactivated.")
1935 end 1988 end
1936 1989
1937 function addon:Clear(verbose_p) 1990 function addon:Clear(verbose_p)
1938 local repopup, st 1991 local repopup, st
3055 -- formatted timestamp. This is expensive, and destructive for P.unique. 3108 -- formatted timestamp. This is expensive, and destructive for P.unique.
3056 local function compare_timestamps (L, R) 3109 local function compare_timestamps (L, R)
3057 return L > R -- reverse of normal order, newest first 3110 return L > R -- reverse of normal order, newest first
3058 end 3111 end
3059 local function sort_player (p) 3112 local function sort_player (p)
3060 local new_uniques, uniques_bywhen, when_array = new(), new(), new() 3113 local new_uniques, uniques_bywhen, when_array = {}, new(), new()
3061 for u,tstamp in pairs(p.when) do 3114 for u,tstamp in pairs(p.when) do
3062 uniques_bywhen[tstamp] = u 3115 uniques_bywhen[tstamp] = u
3063 when_array[#when_array+1] = tstamp 3116 when_array[#when_array+1] = tstamp
3064 end 3117 end
3065 table.sort (when_array, compare_timestamps) 3118 table.sort (when_array, compare_timestamps)
3066 for i,tstamp in ipairs(when_array) do 3119 for i,tstamp in ipairs(when_array) do
3067 new_uniques[i] = uniques_bywhen[tstamp] 3120 new_uniques[i] = uniques_bywhen[tstamp]
3068 end 3121 end
3069 p.unique = new_uniques 3122 p.unique = new_uniques
3070 del(new_uniques) del(uniques_bywhen) del(when_array) 3123 del(uniques_bywhen)
3124 del(when_array)
3071 end 3125 end
3072 3126
3073 function addon:repair_history_integrity() 3127 function addon:repair_history_integrity()
3074 local rcount, pcount, hcount, errors = 0, 0, 0, 0 3128 local rcount, pcount, hcount, errors = 0, 0, 0, 0
3075 local empties_to_delete = {} 3129 local empties_to_delete = {}