annotate Modules/Scanner.lua @ 107:aa675033abdc v0.2.7-BETA

Changelog & to-do list updated.
author Zerotorescue
date Wed, 12 Jan 2011 20:09:00 +0100
parents d3fbb5676a5e
children 3bbad0429d87
rev   line source
Zerotorescue@80 1 local addon = select(2, ...);
Zerotorescue@84 2 local mod = addon:NewModule("Scanner", "AceEvent-3.0", "AceTimer-3.0");
Zerotorescue@80 3
Zerotorescue@80 4 addon.Locations = {
Zerotorescue@80 5 Bag = 0,
Zerotorescue@80 6 Bank = 1,
Zerotorescue@80 7 Guild = 2,
Zerotorescue@80 8 };
Zerotorescue@80 9
Zerotorescue@101 10 local Mover, paused, currentLocation;
Zerotorescue@80 11 local itemCache = {};
Zerotorescue@80 12
Zerotorescue@101 13 local function OnMoveAccept(this)
Zerotorescue@101 14 mod:Pause();
Zerotorescue@101 15 Mover:BeginMove(currentLocation, mod.Unpause);
Zerotorescue@101 16
Zerotorescue@101 17 InventoriumItemMover:Hide();
Zerotorescue@101 18 end
Zerotorescue@101 19
Zerotorescue@101 20 local function OnMoveCancel(this)
Zerotorescue@101 21 Mover:ResetQueue();
Zerotorescue@101 22 currentLocation = nil;
Zerotorescue@101 23
Zerotorescue@101 24 InventoriumItemMover:Hide();
Zerotorescue@101 25 end
Zerotorescue@101 26
Zerotorescue@80 27 function mod:ClearCache()
Zerotorescue@80 28 table.wipe(itemCache);
Zerotorescue@80 29 end
Zerotorescue@80 30
Zerotorescue@80 31 function mod:CacheLocation(location, remember)
Zerotorescue@89 32 -- Reset cache just in case it was filled
Zerotorescue@89 33 self:ClearCache();
Zerotorescue@89 34
Zerotorescue@80 35 if location == addon.Locations.Bag or location == addon.Locations.Bank then
Zerotorescue@80 36 local start, stop;
Zerotorescue@80 37 if location == addon.Locations.Bag then
Zerotorescue@80 38 start = 0;
Zerotorescue@80 39 stop = NUM_BAG_SLOTS;
Zerotorescue@80 40 else
Zerotorescue@80 41 -- If we requested the bank then we don't want the bag info
Zerotorescue@80 42 start = ( NUM_BAG_SLOTS + 1 );
Zerotorescue@80 43 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
Zerotorescue@80 44 end
Zerotorescue@80 45
Zerotorescue@80 46 -- Go through all our bags, including the backpack
Zerotorescue@81 47 for i = start, ((location == addon.Locations.Bag and stop) or (location == addon.Locations.Bank and (stop + 1))) do -- if scanning bags stop at normal bag slot, if scanning bank, stop one later to allow BANK_CONTAINER to be scanned too
Zerotorescue@80 48 -- Scan the default 100 slots whenever we're at a non-existing index
Zerotorescue@80 49 local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
Zerotorescue@80 50 local slotId = GetContainerNumSlots(bagId);
Zerotorescue@80 51
Zerotorescue@80 52 while slotId ~= 0 do
Zerotorescue@80 53 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@80 54
Zerotorescue@80 55 local itemId = GetContainerItemID(bagId, slotId);
Zerotorescue@80 56 local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId));
Zerotorescue@80 57
Zerotorescue@80 58 if itemId and itemCount and itemCount > 0 then
Zerotorescue@80 59 local itemMove;
Zerotorescue@80 60 if not itemCache[itemId] then
Zerotorescue@80 61 -- If this is the first time we see this item, make a new object
Zerotorescue@81 62 itemMove = addon.ContainerItem:New();
Zerotorescue@81 63 itemCache[itemId] = itemMove;
Zerotorescue@80 64 else
Zerotorescue@80 65 -- If we had this item in another slot too
Zerotorescue@80 66 itemMove = itemCache[itemId];
Zerotorescue@80 67 end
Zerotorescue@80 68
Zerotorescue@81 69 itemMove:AddLocation(bagId, slotId, itemCount);
Zerotorescue@80 70 end
Zerotorescue@80 71
Zerotorescue@80 72 -- Continue scanning a different slot
Zerotorescue@80 73 slotId = (slotId - 1);
Zerotorescue@80 74 end
Zerotorescue@80 75 end
Zerotorescue@80 76 elseif location == addon.Locations.Guild then
Zerotorescue@84 77 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@84 78 local isViewable = select(3, GetGuildBankTabInfo(tabId));
Zerotorescue@80 79
Zerotorescue@84 80 if isViewable == 1 then
Zerotorescue@84 81 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
Zerotorescue@80 82
Zerotorescue@84 83 while slotId ~= 0 do
Zerotorescue@84 84 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@84 85
Zerotorescue@84 86 local itemLink = GetGuildBankItemLink(tabId, slotId);
Zerotorescue@95 87 local itemId = itemLink and addon:GetItemId(itemLink);
Zerotorescue@84 88 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
Zerotorescue@84 89
Zerotorescue@84 90 if itemLink and itemId and itemCount and itemCount > 0 then
Zerotorescue@84 91 -- If there is actually an item in this slot
Zerotorescue@84 92 local itemMove;
Zerotorescue@84 93 if not itemCache[itemId] then
Zerotorescue@84 94 -- If this is the first time we see this item, make a new object
Zerotorescue@84 95 itemMove = addon.ContainerItem:New();
Zerotorescue@84 96 itemCache[itemId] = itemMove;
Zerotorescue@84 97 else
Zerotorescue@84 98 -- If we had this item in another slot too
Zerotorescue@84 99 itemMove = itemCache[itemId];
Zerotorescue@84 100 end
Zerotorescue@84 101
Zerotorescue@84 102 itemMove:AddLocation(tabId, slotId, itemCount);
Zerotorescue@84 103 end
Zerotorescue@84 104
Zerotorescue@84 105 -- Continue scanning a different slot
Zerotorescue@84 106 slotId = (slotId - 1);
Zerotorescue@80 107 end
Zerotorescue@80 108 end
Zerotorescue@80 109 end
Zerotorescue@80 110 else
Zerotorescue@82 111 error("Invalid location provided for CacheLocation. Must be Bank or Guild.");
Zerotorescue@80 112 end
Zerotorescue@80 113
Zerotorescue@80 114 if not remember then
Zerotorescue@80 115 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
Zerotorescue@80 116 local cacheCopy = CopyTable(itemCache);
Zerotorescue@80 117
Zerotorescue@80 118 self:ClearCache();
Zerotorescue@80 119
Zerotorescue@80 120 return cacheCopy;
Zerotorescue@80 121 end
Zerotorescue@80 122 end
Zerotorescue@80 123
Zerotorescue@80 124 function mod:Scan(location)
Zerotorescue@80 125 -- We might pause the scanning when we invoke moves ourself
Zerotorescue@80 126 if paused then
Zerotorescue@80 127 return;
Zerotorescue@80 128 end
Zerotorescue@80 129
Zerotorescue@80 130 local playerName = UnitName("player");
Zerotorescue@80 131
Zerotorescue@101 132 currentLocation = location;
Zerotorescue@80 133 self:CacheLocation(location, true);
Zerotorescue@80 134
Zerotorescue@80 135 -- Go through all groups
Zerotorescue@80 136 for groupName, values in pairs(addon.db.profile.groups) do
Zerotorescue@80 137 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
Zerotorescue@84 138 local localItemData = addon:GetOptionByKey(groupName, "localItemData");
Zerotorescue@80 139
Zerotorescue@82 140 if values.items and trackAt[playerName] and addon:GetOptionByKey(groupName, "autoRefill") and (location ~= addon.Locations.Bank or not localItemData or not localItemData["Bank"]) then
Zerotorescue@80 141 -- Is this character interested in this data?
Zerotorescue@80 142
Zerotorescue@80 143 local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock");
Zerotorescue@80 144
Zerotorescue@80 145 -- Go through all items
Zerotorescue@80 146 for itemId, _ in pairs(values.items) do
Zerotorescue@80 147
Zerotorescue@81 148 -- Check if we have enough items local (but only do so if this location also has enough available)
Zerotorescue@81 149 local missingItems = itemCache[itemId] and (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
Zerotorescue@80 150
Zerotorescue@81 151 if itemCache[itemId] and missingItems > 0 then
Zerotorescue@80 152 -- Check how many are available
Zerotorescue@81 153 local availableItems = ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
Zerotorescue@101 154 -- Calculate how many we'll be moving (less missing than available? use missing, otherwise use available)
Zerotorescue@101 155 local moving = (((missingItems <= availableItems) and missingItems) or availableItems);
Zerotorescue@80 156
Zerotorescue@80 157 if availableItems > 0 then
Zerotorescue@101 158 --addon:Print("Insufficient " .. IdToItemLink(itemId) .. " but this location has " .. availableItems .. " (moving " .. moving .. ")");
Zerotorescue@80 159
Zerotorescue@101 160 Mover:AddMove(itemId, moving, missingItems, availableItems);
Zerotorescue@80 161 else
Zerotorescue@101 162 --addon:Print("Insufficient " .. IdToItemLink(itemId));
Zerotorescue@80 163 end
Zerotorescue@80 164 end
Zerotorescue@80 165 end
Zerotorescue@80 166 end
Zerotorescue@80 167 end
Zerotorescue@80 168
Zerotorescue@80 169 self:ClearCache();
Zerotorescue@80 170
Zerotorescue@81 171 if Mover:HasMoves() then
Zerotorescue@101 172 if addon.db.profile.defaults.autoRefillSkipConfirm then
Zerotorescue@101 173 OnMoveAccept(true);
Zerotorescue@101 174 else
Zerotorescue@106 175 -- This table is never copied, just referenced. It is the same for every row.
Zerotorescue@101 176 local columns = {
Zerotorescue@101 177 {
Zerotorescue@106 178 value = function(data, cols, realrow, column, table)
Zerotorescue@106 179 return IdToItemLink(data[realrow].rowData.id);
Zerotorescue@101 180 end,
Zerotorescue@101 181 }, -- item
Zerotorescue@101 182 {
Zerotorescue@106 183 value = function(data, cols, realrow, column, table)
Zerotorescue@106 184 return data[realrow].rowData.num;
Zerotorescue@101 185 end,
Zerotorescue@101 186 }, -- moving
Zerotorescue@101 187 {
Zerotorescue@106 188 value = function(data, cols, realrow, column, table)
Zerotorescue@106 189 return addon:DisplayItemCount(data[realrow].rowData.available, data[realrow].rowData.missing); -- available / missing
Zerotorescue@101 190 end,
Zerotorescue@106 191 color = function(data, cols, realrow, column, table)
Zerotorescue@106 192 return ((data[realrow].rowData.available < data[realrow].rowData.missing) and { r = 1, g = 0, b = 0, a = 1 }) or { r = 1, g = 1, b = 1, a = 1 };
Zerotorescue@101 193 end,
Zerotorescue@106 194 }, -- missing / available
Zerotorescue@101 195 };
Zerotorescue@101 196
Zerotorescue@106 197 -- Store the list with rows in this
Zerotorescue@106 198 local data = {};
Zerotorescue@101 199
Zerotorescue@101 200 for i, move in pairs(Mover:GetMoves()) do
Zerotorescue@106 201 table.insert(data, {
Zerotorescue@106 202 ["rowData"] = move, -- this is not a key usually found in a row item and ignored by the library
Zerotorescue@101 203 ["cols"] = columns,
Zerotorescue@106 204 });
Zerotorescue@101 205 end
Zerotorescue@101 206
Zerotorescue@101 207 addon:SetMoverFrameData(data);
Zerotorescue@101 208 end
Zerotorescue@81 209 end
Zerotorescue@81 210 end
Zerotorescue@81 211
Zerotorescue@84 212
Zerotorescue@84 213
Zerotorescue@84 214 -- Events
Zerotorescue@84 215
Zerotorescue@84 216 -- Player bank
Zerotorescue@84 217
Zerotorescue@84 218 function mod:BANKFRAME_OPENED()
Zerotorescue@84 219 addon:Debug("Scanner:BANKFRAME_OPENED");
Zerotorescue@84 220
Zerotorescue@84 221 mod:RegisterEvent("BANKFRAME_CLOSED");
Zerotorescue@84 222
Zerotorescue@84 223 -- Scan once when the bank is opened, but no need to scan after
Zerotorescue@84 224 mod:Scan(addon.Locations.Bank);
Zerotorescue@84 225 end
Zerotorescue@84 226
Zerotorescue@84 227 function mod:BANKFRAME_CLOSED()
Zerotorescue@81 228 addon:Debug("Scanner:BANKFRAME_CLOSED");
Zerotorescue@81 229
Zerotorescue@89 230 self:ClearCache();
Zerotorescue@89 231
Zerotorescue@81 232 mod:UnregisterEvent("BANKFRAME_CLOSED");
Zerotorescue@81 233
Zerotorescue@101 234 InventoriumItemMover:Hide();
Zerotorescue@101 235 Mover:ResetQueue();
Zerotorescue@80 236 end
Zerotorescue@80 237
Zerotorescue@84 238 -- Guild bank
Zerotorescue@84 239
Zerotorescue@84 240 local tmrScanGuild, scanned;
Zerotorescue@84 241 function mod:GUILDBANKBAGSLOTS_CHANGED()
Zerotorescue@84 242 -- This event is spammed the first time the guild bank is opened
Zerotorescue@84 243 if not scanned then
Zerotorescue@84 244 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@84 245 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
Zerotorescue@84 246 end
Zerotorescue@80 247 end
Zerotorescue@80 248
Zerotorescue@84 249 function mod:DoScanGuild()
Zerotorescue@84 250 if not scanned then
Zerotorescue@89 251 addon:Debug("Scanner:DoScanGuild");
Zerotorescue@84 252
Zerotorescue@84 253 scanned = true;
Zerotorescue@84 254
Zerotorescue@84 255 self:Scan(addon.Locations.Guild);
Zerotorescue@84 256 end
Zerotorescue@84 257 end
Zerotorescue@80 258
Zerotorescue@84 259 function mod:GUILDBANKFRAME_CLOSED()
Zerotorescue@81 260 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
Zerotorescue@81 261
Zerotorescue@84 262 scanned = nil;
Zerotorescue@89 263 self:ClearCache();
Zerotorescue@81 264
Zerotorescue@84 265 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 266 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@84 267
Zerotorescue@84 268 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@80 269
Zerotorescue@101 270 InventoriumItemMover:Hide();
Zerotorescue@101 271 Mover:ResetQueue();
Zerotorescue@80 272 end
Zerotorescue@80 273
Zerotorescue@84 274 function mod:GUILDBANKFRAME_OPENED()
Zerotorescue@81 275 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
Zerotorescue@81 276
Zerotorescue@84 277 scanned = nil;
Zerotorescue@80 278
Zerotorescue@84 279 -- Get the contents for every tab into our cache
Zerotorescue@84 280 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@84 281 local isViewable = select(3, GetGuildBankTabInfo(tabId));
Zerotorescue@84 282 if isViewable == 1 then
Zerotorescue@84 283 QueryGuildBankTab(tabId);
Zerotorescue@84 284 end
Zerotorescue@84 285 end
Zerotorescue@84 286
Zerotorescue@84 287 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 288 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@80 289 end
Zerotorescue@80 290
Zerotorescue@80 291 function mod:OnEnable()
Zerotorescue@80 292 -- Scan once when the bankframe is opened
Zerotorescue@84 293 self:RegisterEvent("BANKFRAME_OPENED");
Zerotorescue@84 294 self:RegisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@80 295
Zerotorescue@80 296 Mover = addon:GetModule("Mover");
Zerotorescue@101 297
Zerotorescue@101 298 if not InventoriumItemMover then
Zerotorescue@101 299 addon:CreateMoverFrame(OnMoveAccept, OnMoveCancel);
Zerotorescue@101 300 end
Zerotorescue@80 301 end
Zerotorescue@80 302
Zerotorescue@80 303 function mod:OnDisable()
Zerotorescue@80 304 Mover = nil;
Zerotorescue@101 305 currentLocation = nil;
Zerotorescue@101 306 paused = nil;
Zerotorescue@80 307
Zerotorescue@80 308 -- Bank
Zerotorescue@84 309 self:UnregisterEvent("BANKFRAME_OPENED");
Zerotorescue@80 310
Zerotorescue@80 311 -- Guild
Zerotorescue@84 312 self:GUILDBANKFRAME_CLOSED();
Zerotorescue@84 313 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@80 314 end
Zerotorescue@80 315
Zerotorescue@80 316 function mod:Pause()
Zerotorescue@80 317 paused = true;
Zerotorescue@80 318 end
Zerotorescue@80 319
Zerotorescue@80 320 function mod:Unpause()
Zerotorescue@80 321 paused = nil;
Zerotorescue@80 322 end