local DEBUG = -- function() end d if not InventoryManager then InventoryManager = {} end local IM = InventoryManager local _Pending = nil local _Delay = nil -- function _Loop_fn(entry) local _Loop_fn = nil -- function _Finish_fn(finished_ok) local _Finish_fn = nil local _Event_Next = nil local _Event_Abort = nil local _Event_Filter_fn = nil -- Simple processing loop, call next element after delay local function ProcessLoop() if not _Pending or #_Pending == 0 then if _Finish_fn then _Finish_fn(true) end return end local entry = _Pending[#_Pending] _Pending[#_Pending] = nil _Loop_fn(entry) zo_callLater(ProcessLoop, _Delay) end -- Event driven processing loop, called directly for first element, -- then is fired by _Loop_fn's completion for the subsequent ones. local function EventProcessLoop(eventCode, a1, a2, a3, a4, a5, a6, a7, a8) -- Bail out if this event is not meant for us. if _Event_Filter_fn then if not _Event_Filter_fn(eventCode, a1, a2, a3, a4, a5, a6, a7, a8) then return end end if not _Pending or #_Pending == 0 then if _Event_Next then EVENT_MANAGER:UnregisterForEvent("IMEventProcessLoop", _Event_Next) end if _Event_Abort then EVENT_MANAGER:UnregisterForEvent("IMEventProcessLoop", _Event_Abort) end if _Finish_fn then _Finish_fn(true, eventCode, a1, a2, a3, a4, a5, a6, a7, a8) end return end local entry = _Pending[#_Pending] _Pending[#_Pending] = nil zo_callLater(function() _Loop_fn(entry, eventCode, a1, a2, a3, a4, a5, a6, a7, a8) end, _Delay) end local function EventProcessLoopAbort() if _Event_Next then EVENT_MANAGER:UnregisterForEvent("IMEventProcessLoop", _Event_Next) end if _Event_Abort then EVENT_MANAGER:UnregisterForEvent("IMEventProcessLoop", _Event_Abort) end if _Finish_fn then _Finish_fn(false) end end function IM:DoEventProcessing(list, loop_fn, finish_fn, loop_event, abort_event, run_delay, event_filter_fn) _Pending = list _Loop_fn = loop_fn _Finish_fn = finish_fn _Delay = run_delay or 1 _Event_Next = loop_event _Event_Abort = abort_event _Event_Filter_fn = event_filter_fn if _Event_Next then EVENT_MANAGER:RegisterForEvent("IMEventProcessLoop", _Event_Next, EventProcessLoop) end if _Event_Abort then EVENT_MANAGER:RegisterForEvent("IMEventProcessLoop", _Event_Abort, EventProcessLoopAbort) end zo_callLater(function() EventProcessLoop() end, _Delay) end function IM:DoDelayedProcessing(list, loop_fn, finish_fn, run_delay, init_delay) _Pending = list _Loop_fn = loop_fn _Finish_fn = finish_fn _Delay = run_delay or 1 local _Init_Delay = init_delay or _Delay zo_callLater(ProcessLoop, _Init_Delay) end function IM:CreateInventoryList(bagId, action, filter_fn, list) self:SetCurrentInventory(bagId) if not list then list = { } else for i = 1, #list / 2, 1 do local tmp = list[i] list[i] = list[(#list+1) - i] list[(#list+1) - i] = tmp end end for i,_ in pairs(self.currentInventory) do if #list > 90 then break end local data = self:GetItemData(i) data.action, data.index, data.text = self.currentRuleset:Match(data, action) if ((not action) or data.action == action) and filter_fn(data) then list[#list + 1] = data end end for i = 1, #list / 2, 1 do local tmp = list[i] list[i] = list[(#list+1) - i] list[(#list+1) - i] = tmp end return list end function IM:ProcessBag(bagId, action, filter_fn, loop_fn, finish_fn, run_delay, init_delay) local list = IM:CreateInventoryList(bagId, action, filter_fn) self:DoDelayedProcessing(list, loop_fn, finish_fn, run_delay, init_delay) end function IM:EventProcessBag(bagId, action, filter_fn, loop_fn, finish_fn, loop_event, abort_event, run_delay, event_filter_fn) local list = IM:CreateInventoryList(bagId, action, filter_fn) self:DoEventProcessing(list, loop_fn, finish_fn, loop_event, abort_event, run_delay, event_filter_fn) end function IM:AbortProcessing() _Pending = nil end