comparison Modules/Mover.lua @ 122:6724bc8eface

Reduced usage of global functions by defining them locally.
author Zerotorescue
date Sat, 15 Jan 2011 18:52:01 +0100
parents 00cf4fc1697f
children 84e38318f569
comparison
equal deleted inserted replaced
121:ca6280dc2f5b 122:6724bc8eface
1 local addon = select(2, ...); 1 local addon = select(2, ...);
2 local mod = addon:NewModule("Mover", "AceEvent-3.0", "AceTimer-3.0"); 2 local mod = addon:NewModule("Mover", "AceEvent-3.0", "AceTimer-3.0");
3
4 local _G = _G;
5 local select, pairs = _G.select, _G.pairs;
6 local tinsert, twipe, treverse, tsort, tremove = _G.table.insert, _G.table.wipe, _G.table.reverse, _G.table.sort, _G.table.remove;
3 7
4 local Scanner; 8 local Scanner;
5 local queuedMoves = {}; -- table storing all queued moves before BeginMove is called 9 local queuedMoves = {}; -- table storing all queued moves before BeginMove is called
6 local combinedMoves = {}; -- table storing all combined moves (with source and target) that is to be processed by the actual mover in the order of the index (1 to #) 10 local combinedMoves = {}; -- table storing all combined moves (with source and target) that is to be processed by the actual mover in the order of the index (1 to #)
7 local movesSource; 11 local movesSource;
56 Event = "BAG_UPDATE", 60 Event = "BAG_UPDATE",
57 }, 61 },
58 }; 62 };
59 63
60 function mod:AddMove(itemId, amount, numMissing, numAvailable, cost) 64 function mod:AddMove(itemId, amount, numMissing, numAvailable, cost)
61 table.insert(queuedMoves, { 65 tinsert(queuedMoves, {
62 ["itemId"] = itemId, 66 ["itemId"] = itemId,
63 ["num"] = amount, -- can not be unlimited 67 ["num"] = amount, -- can not be unlimited
64 ["missing"] = numMissing, 68 ["missing"] = numMissing,
65 ["available"] = numAvailable, 69 ["available"] = numAvailable,
66 ["cost"] = cost, 70 ["cost"] = cost,
74 function mod:GetMoves() 78 function mod:GetMoves()
75 return queuedMoves; 79 return queuedMoves;
76 end 80 end
77 81
78 function mod:ResetQueue() 82 function mod:ResetQueue()
79 table.wipe(queuedMoves); 83 twipe(queuedMoves);
80 end 84 end
81 85
82 if not table.reverse then 86 if not treverse then
83 table.reverse = function(orig) 87 treverse = function(orig)
84 local temp = {}; 88 local temp = {};
85 local origLength = #orig; 89 local origLength = #orig;
86 for i = 1, origLength do 90 for i = 1, origLength do
87 temp[(origLength - i + 1)] = orig[i]; 91 temp[(origLength - i + 1)] = orig[i];
88 end 92 end
104 for slotId = 1, GetContainerNumSlots(bagId) do 108 for slotId = 1, GetContainerNumSlots(bagId) do
105 local itemId = GetContainerItemID(bagId, slotId); -- we're scanning our local bags here, so no need to get messy with guild bank support 109 local itemId = GetContainerItemID(bagId, slotId); -- we're scanning our local bags here, so no need to get messy with guild bank support
106 local bagFamily = select(2, GetContainerNumFreeSlots(bagId)); 110 local bagFamily = select(2, GetContainerNumFreeSlots(bagId));
107 111
108 if not itemId then 112 if not itemId then
109 table.insert(emptySlots, { 113 tinsert(emptySlots, {
110 ["container"] = bagId, 114 ["container"] = bagId,
111 ["slot"] = slotId, 115 ["slot"] = slotId,
112 ["family"] = bagFamily, 116 ["family"] = bagFamily,
113 }); 117 });
114 end 118 end
152 local sourceItem = sourceContents[singleMove.itemId]; 156 local sourceItem = sourceContents[singleMove.itemId];
153 if not sourceItem then 157 if not sourceItem then
154 addon:Print(("Can't move %s, this doesn't exist in the source."):format(IdToItemLink(singleMove.itemId)), addon.Colors.Red); 158 addon:Print(("Can't move %s, this doesn't exist in the source."):format(IdToItemLink(singleMove.itemId)), addon.Colors.Red);
155 else 159 else
156 -- We want to move the smallest stacks first to keep stuff pretty (and minimize space usage, splitting a stack takes 2 slots, moving something only 1) 160 -- We want to move the smallest stacks first to keep stuff pretty (and minimize space usage, splitting a stack takes 2 slots, moving something only 1)
157 table.sort(sourceItem.locations, function(a, b) 161 tsort(sourceItem.locations, function(a, b)
158 -- -1 indicates unlimited, this is always more than an actual amount 162 -- -1 indicates unlimited, this is always more than an actual amount
159 if a.count == -1 then 163 if a.count == -1 then
160 return false; 164 return false;
161 elseif b.count == -1 then 165 elseif b.count == -1 then
162 return true; 166 return true;
177 181
178 if stackSize then 182 if stackSize then
179 while movingNum > stackSize do 183 while movingNum > stackSize do
180 -- Move a single stack size while the amount remaining to be moved is above the stack size num 184 -- Move a single stack size while the amount remaining to be moved is above the stack size num
181 185
182 table.insert(outgoingMoves, { 186 tinsert(outgoingMoves, {
183 ["itemId"] = singleMove.itemId, 187 ["itemId"] = singleMove.itemId,
184 ["num"] = stackSize, 188 ["num"] = stackSize,
185 ["container"] = itemLocation.container, 189 ["container"] = itemLocation.container,
186 ["slot"] = itemLocation.slot, 190 ["slot"] = itemLocation.slot,
187 }); 191 });
190 singleMove.num = (singleMove.num - stackSize); 194 singleMove.num = (singleMove.num - stackSize);
191 end 195 end
192 end 196 end
193 end 197 end
194 198
195 table.insert(outgoingMoves, { 199 tinsert(outgoingMoves, {
196 ["itemId"] = singleMove.itemId, 200 ["itemId"] = singleMove.itemId,
197 ["num"] = movingNum, 201 ["num"] = movingNum,
198 ["container"] = itemLocation.container, 202 ["container"] = itemLocation.container,
199 ["slot"] = itemLocation.slot, 203 ["slot"] = itemLocation.slot,
200 }); 204 });
210 end 214 end
211 215
212 addon:Debug("%d outgoing moves are possible.", #outgoingMoves); 216 addon:Debug("%d outgoing moves are possible.", #outgoingMoves);
213 217
214 -- No longer needed 218 -- No longer needed
215 table.wipe(queuedMoves); 219 twipe(queuedMoves);
216 220
217 221
218 222
219 -- Process every single outgoing move and find fitting targets 223 -- Process every single outgoing move and find fitting targets
220 224
262 end 266 end
263 end 267 end
264 else 268 else
265 -- Consume empty slot 269 -- Consume empty slot
266 270
267 table.insert(combinedMoves, { 271 tinsert(combinedMoves, {
268 ["itemId"] = outgoingMove.itemId, 272 ["itemId"] = outgoingMove.itemId,
269 ["num"] = outgoingMove.num, 273 ["num"] = outgoingMove.num,
270 ["sourceContainer"] = outgoingMove.container, 274 ["sourceContainer"] = outgoingMove.container,
271 ["sourceSlot"] = outgoingMove.slot, 275 ["sourceSlot"] = outgoingMove.slot,
272 ["targetContainer"] = firstAvailableSlot.container, 276 ["targetContainer"] = firstAvailableSlot.container,
277 -- make a new instance of the ItemMove class so any additional items with this id can be stacked on top of it 281 -- make a new instance of the ItemMove class so any additional items with this id can be stacked on top of it
278 local itemMove = addon.ContainerItem:New(); 282 local itemMove = addon.ContainerItem:New();
279 itemMove:AddLocation(firstAvailableSlot.container, firstAvailableSlot.slot, outgoingMove.num); 283 itemMove:AddLocation(firstAvailableSlot.container, firstAvailableSlot.slot, outgoingMove.num);
280 targetContents[outgoingMove.itemId] = itemMove; 284 targetContents[outgoingMove.itemId] = itemMove;
281 285
282 table.remove(emptySlots, 1); -- no longer empty 286 tremove(emptySlots, 1); -- no longer empty
283 287
284 outgoingMove.num = 0; -- nothing remaining - sanity check 288 outgoingMove.num = 0; -- nothing remaining - sanity check
285 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table 289 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table
286 end 290 end
287 else 291 else
288 -- Find the maximum stack size for this item 292 -- Find the maximum stack size for this item
289 local itemStackCount = select(8, GetItemInfo(outgoingMove.itemId)); 293 local itemStackCount = select(8, GetItemInfo(outgoingMove.itemId));
290 294
291 -- We want to move to the largest stacks first to keep stuff pretty 295 -- We want to move to the largest stacks first to keep stuff pretty
292 table.sort(targetItem.locations, function(a, b) 296 tsort(targetItem.locations, function(a, b)
293 return a.count > b.count; 297 return a.count > b.count;
294 end); 298 end);
295 299
296 for _, itemLocation in pairs(targetItem.locations) do 300 for _, itemLocation in pairs(targetItem.locations) do
297 if itemLocation.count < itemStackCount and outgoingMove.num > 0 then 301 if itemLocation.count < itemStackCount and outgoingMove.num > 0 then
300 local remainingSpace = (itemStackCount - itemLocation.count); 304 local remainingSpace = (itemStackCount - itemLocation.count);
301 if remainingSpace >= outgoingMove.num then 305 if remainingSpace >= outgoingMove.num then
302 -- Enough room to move this entire stack 306 -- Enough room to move this entire stack
303 -- Deposit this item and then forget this outgoing move as everything in it was processed 307 -- Deposit this item and then forget this outgoing move as everything in it was processed
304 308
305 table.insert(combinedMoves, { 309 tinsert(combinedMoves, {
306 ["itemId"] = outgoingMove.itemId, 310 ["itemId"] = outgoingMove.itemId,
307 ["num"] = outgoingMove.num, 311 ["num"] = outgoingMove.num,
308 ["sourceContainer"] = outgoingMove.container, 312 ["sourceContainer"] = outgoingMove.container,
309 ["sourceSlot"] = outgoingMove.slot, 313 ["sourceSlot"] = outgoingMove.slot,
310 ["targetContainer"] = itemLocation.container, 314 ["targetContainer"] = itemLocation.container,
316 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table 320 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table
317 break; -- stop the locations-loop 321 break; -- stop the locations-loop
318 else 322 else
319 -- Deposit this item but don't remove the outgoing move as there are some items left to move 323 -- Deposit this item but don't remove the outgoing move as there are some items left to move
320 324
321 table.insert(combinedMoves, { 325 tinsert(combinedMoves, {
322 ["itemId"] = outgoingMove.itemId, 326 ["itemId"] = outgoingMove.itemId,
323 ["num"] = outgoingMove.num, 327 ["num"] = outgoingMove.num,
324 ["sourceContainer"] = outgoingMove.container, 328 ["sourceContainer"] = outgoingMove.container,
325 ["sourceSlot"] = outgoingMove.slot, 329 ["sourceSlot"] = outgoingMove.slot,
326 ["targetContainer"] = itemLocation.container, 330 ["targetContainer"] = itemLocation.container,
349 -- A not equal-comparison should be quicker than a larger/smaller than-comparison 353 -- A not equal-comparison should be quicker than a larger/smaller than-comparison
350 354
351 -- Check if the item id is nil, this is set to nil when this outgoing move has been processed 355 -- Check if the item id is nil, this is set to nil when this outgoing move has been processed
352 if not outgoingMoves[numOutgoingMoves].itemId or outgoingMoves[numOutgoingMoves].num == 0 then 356 if not outgoingMoves[numOutgoingMoves].itemId or outgoingMoves[numOutgoingMoves].num == 0 then
353 -- Remove this element from the array 357 -- Remove this element from the array
354 table.remove(outgoingMoves, numOutgoingMoves); 358 tremove(outgoingMoves, numOutgoingMoves);
355 end 359 end
356 360
357 -- Proceed with the next element (or previous considering we're going from last to first) 361 -- Proceed with the next element (or previous considering we're going from last to first)
358 numOutgoingMoves = (numOutgoingMoves - 1); 362 numOutgoingMoves = (numOutgoingMoves - 1);
359 end 363 end
360 364
361 addon:Debug("%d moves remaining.", #outgoingMoves); 365 addon:Debug("%d moves remaining.", #outgoingMoves);
362 366
363 backup = (backup + 1); 367 backup = (backup + 1);
364 if backup > 1000 then 368 if backup > 1000 then
365 table.wipe(outgoingMoves); 369 twipe(outgoingMoves);
366 self:Abort("mover crashed", "Error preparing moves, hit an endless loop"); 370 self:Abort("mover crashed", "Error preparing moves, hit an endless loop");
367 onFinish(); 371 onFinish();
368 return; 372 return;
369 end 373 end
370 end 374 end
371 375
372 -- Reverse table, we need to go through it from last to first because we'll be removing elements, but we don't want the actions to be executed in a different order 376 -- Reverse table, we need to go through it from last to first because we'll be removing elements, but we don't want the actions to be executed in a different order
373 combinedMoves = table.reverse(combinedMoves); 377 combinedMoves = treverse(combinedMoves);
374 378
375 addon:Debug("%d moves should be possible.", #combinedMoves); 379 addon:Debug("%d moves should be possible.", #combinedMoves);
376 380
377 -- No longer needed 381 -- No longer needed
378 table.wipe(emptySlots); 382 twipe(emptySlots);
379 383
380 self:ProcessMove(); 384 self:ProcessMove();
381 385
382 -- Even though we aren't completely done yet, allow requeueing 386 -- Even though we aren't completely done yet, allow requeueing
383 onFinish(); 387 onFinish();
407 411
408 if movesSource == addon.Locations.Mailbox then 412 if movesSource == addon.Locations.Mailbox then
409 MailAddonBusy = addon:GetName(); 413 MailAddonBusy = addon:GetName();
410 414
411 -- Since mailbox indexes change as mail is emptied (emptied mail is automatically deleted, thus number 50 would become 49 when 1 disappears), we must start with the last mail first 415 -- Since mailbox indexes change as mail is emptied (emptied mail is automatically deleted, thus number 50 would become 49 when 1 disappears), we must start with the last mail first
412 table.sort(combinedMoves, function(a, b) 416 tsort(combinedMoves, function(a, b)
413 return a.sourceContainer < b.sourceContainer; 417 return a.sourceContainer < b.sourceContainer;
414 end); 418 end);
415 end 419 end
416 420
417 self:RegisterEvent(ContainerFunctions[movesSource].Event, "SourceUpdated"); 421 self:RegisterEvent(ContainerFunctions[movesSource].Event, "SourceUpdated");
480 targetLocationsLocked[move.targetContainer] = {}; 484 targetLocationsLocked[move.targetContainer] = {};
481 end 485 end
482 targetLocationsLocked[move.targetContainer][move.targetSlot] = true; 486 targetLocationsLocked[move.targetContainer][move.targetSlot] = true;
483 487
484 -- This move was processed 488 -- This move was processed
485 table.remove(combinedMoves, numCurrentMove); 489 tremove(combinedMoves, numCurrentMove);
486 else 490 else
487 self:Abort("item disappeared from mouse", "Couldn't move " .. IdToItemLink(move.itemId) .. ", CursorHasItem() is false"); 491 self:Abort("item disappeared from mouse", "Couldn't move " .. IdToItemLink(move.itemId) .. ", CursorHasItem() is false");
488 return; 492 return;
489 end 493 end
490 else 494 else
491 -- When items are deposit automatically we still need to remember when a move has been processed 495 -- When items are deposit automatically we still need to remember when a move has been processed
492 496
493 -- This move was processed 497 -- This move was processed
494 table.remove(combinedMoves, numCurrentMove); 498 tremove(combinedMoves, numCurrentMove);
495 end 499 end
496 end 500 end
497 501
498 -- Proceed with the next element (or previous considering we're going from last to first) 502 -- Proceed with the next element (or previous considering we're going from last to first)
499 numCurrentMove = (numCurrentMove - 1); 503 numCurrentMove = (numCurrentMove - 1);
547 self:CancelTimer(tmrProcessNext, true); -- silent 551 self:CancelTimer(tmrProcessNext, true); -- silent
548 552
549 self:UnregisterEvent("UI_ERROR_MESSAGE"); 553 self:UnregisterEvent("UI_ERROR_MESSAGE");
550 554
551 -- Reset vars 555 -- Reset vars
552 table.wipe(combinedMoves); 556 twipe(combinedMoves);
553 movesSource = nil; 557 movesSource = nil;
554 if MailAddonBusy == addon:GetName() then 558 if MailAddonBusy == addon:GetName() then
555 MailAddonBusy = nil; 559 MailAddonBusy = nil;
556 end 560 end
557 end 561 end