diff --git a/IIfA/IIfADataCollection.lua b/IIfA/IIfADataCollection.lua index 84d0d48..ec82dad 100644 --- a/IIfA/IIfADataCollection.lua +++ b/IIfA/IIfADataCollection.lua @@ -126,8 +126,6 @@ function IIfA:CollectGuildBank(curGuild) p("IIfA - Guild Bank Collected - " .. curGuild .. ", itemCount=" .. itemCount) end - - function IIfA:ScanCurrentCharacter() local playerName = GetUnitName('player') @@ -308,12 +306,15 @@ function IIfA:GuildBankAddRemove(eventID, slotId) end) end - +function IIfA:IgnoreHouse(houseCollectibleId) + houseCollectibleId = houseCollectibleId or GetCollectibleIdForHouse(GetCurrentZoneHouseId()) +end function IIfA:RescanHouse(houseCollectibleId) houseCollectibleId = houseCollectibleId or GetCollectibleIdForHouse(GetCurrentZoneHouseId()) if not houseCollectibleId or not IIfA.trackedBags[houseCollectibleId] then return end - + + -- if GetHouseCategoryType(GetCurrentZoneHouseId()) == HOUSE_CATEGORY_TYPE_NOTABLE then return end IIfA.data.collectHouseData[houseCollectibleId] = IIfA.data.collectHouseData[houseCollectibleId] or IIfA:GetHouseTracking() if not IIfA.data.collectHouseData[houseCollectibleId] then @@ -324,33 +325,42 @@ function IIfA:RescanHouse(houseCollectibleId) IIfA.trackedBags[houseCollectibleId] = true end + -- TODO: Debug this --- stuff them all into an array local function getAllPlacedFurniture() local ret = {} + local counter = 1 + local furnitureId = nil while(true) do - local furnitureId = GetNextPlacedHousingFurnitureId(furnitureId) - if(not furnitureId) then return ret end + furnitureId = GetNextPlacedHousingFurnitureId(furnitureId) + if (not furnitureId or counter > 10000 ) then return ret end local itemLink = GetPlacedFurnitureLink(furnitureId, LINK_STYLE_BRACKETS) - if not ret[itemLink] then - ret[itemLink] = 1 - else - ret[itemLink] = ret[itemLink] + 1 - end + -- if not ret[itemLink] then + -- ret[itemLink] = 1 + -- else + ret[itemLink] = ( ret[itemLink] or 1 ) + 1 + -- end + counter = counter + 1 end + return ret end + + IIfA.getAllPlacedFurniture = getAllPlacedFurniture -- call with libAsync to avoid lag task:Call(function() -- clear and re-create, faster than conditionally updating IIfA:ClearLocationData(houseCollectibleId) --- end):Then(function() - for itemLink, itemCount in pairs(getAllPlacedFurniture()) do + + + end):Then(function() -- TODO - can this go again? Having it in here at least prevented the crash + local placedFurniture = getAllPlacedFurniture() + for itemLink, itemCount in pairs(placedFurniture) do -- (bagId, slotId, fromXfer, itemCount, itemLink, itemName, locationID) p("furniture item <<1>> x<<2>>", itemLink, itemCount) IIfA:EvalBagItem(houseCollectibleId, tonumber(IIfA_GetItemID(itemLink)), false, itemCount, itemLink, GetItemLinkName(itemLink), houseCollectibleId) end end) - end -- try to read item name from bag/slot - if that's empty, we read it from item link @@ -697,12 +707,9 @@ function IIfA:ClearLocationData(location, bagID) -- if loc is characterid, bagI local itemLocation = nil local LocationCount = 0 local itemName, itemData - local bChar - if bagID == nil then - bChar = nil - else - bChar = location == IIfA.currentCharacterId - end + + local bChar = (bagID == nil and nil) or location == IIfA.currentCharacterId + if(DBv3)then p(zo_strformat("IIfA:ClearLocationData(<<1>>, <<2>>)", location, bagID)) diff --git a/IIfA/libs/LibAsync/LibAsync.lua b/IIfA/libs/LibAsync/LibAsync.lua index 77100f0..8127aec 100644 --- a/IIfA/libs/LibAsync/LibAsync.lua +++ b/IIfA/libs/LibAsync/LibAsync.lua @@ -1,4 +1,4 @@ -local MAJOR, MINOR = "LibAsync", 1.4 +local MAJOR, MINOR = "LibAsync", 1.7 local async, oldminor = LibStub:NewLibrary(MAJOR, MINOR) if not async then return end -- the same or newer version of this lib is already loaded into memory @@ -48,7 +48,7 @@ local function DoJob(job) if call then DoCallback(job, index) else - assert(index == 0, "No call on non-empty stack?!") + -- assert(index == 0, "No call on non-empty stack?!") jobs[job.name] = nil call = job.finally if call then pcall(safeCall) end @@ -57,27 +57,33 @@ local function DoJob(job) end -- time we can spend until the next frame must be shown -local frameTimeTarget = 13 +local frameTimeTarget = GetCVar("VSYNC") == "1" and 14 or(tonumber(GetCVar("MinFrameTime.2")) * 1000) + -- we allow a function to use 25% of the frame time before it gets critical local spendTimeDef = frameTimeTarget * 0.75 -local spendTimeDefNoHUD = spendTimeDef * 1.54 +local spendTimeDefNoHUD = 15 local spendTime = spendTimeDef local debug = false +local running local GetFrameTimeMilliseconds, GetGameTimeMilliseconds = GetFrameTimeMilliseconds, GetGameTimeMilliseconds -local identifier = "ASYNCTASKS_JOBS" local function GetThreshold() return(HUD_SCENE:IsShowing() or HUD_UI_SCENE:IsShowing()) and spendTimeDef or spendTimeDefNoHUD end local job = nil +local cpuLoad = 0 +local name local function Scheduler() + if not running then return end + + job = nil local start = GetFrameTimeMilliseconds() - local runTime = start - if (GetGameTimeMilliseconds() - start) > spendTime then - spendTime = 750 / GetFramerate() + local runTime, cpuLoad = start, GetGameTimeMilliseconds() - start + if cpuLoad > spendTime then + spendTime = math.min(30, spendTime + spendTime * 0.02) if debug then df("initial gap: %ims. skip. new threshold: %ims", GetGameTimeMilliseconds() - start, spendTime) end @@ -86,26 +92,27 @@ local function Scheduler() if debug then df("initial gap: %ims", GetGameTimeMilliseconds() - start) end - local name while (GetGameTimeMilliseconds() - start) <= spendTime do - name, job = next(jobs) + name, job = next(jobs, name) + if not job then name, job = next(jobs) end if job then runTime = GetGameTimeMilliseconds() DoJob(job) + spendTime = spendTime - 0.001 else -- Finished - em:UnregisterForUpdate(identifier) + running = false spendTime = GetThreshold() - return + return end end - spendTime = GetThreshold() + -- spendTime = GetThreshold() if debug and job then local now = GetGameTimeMilliseconds() local freezeTime = now - start if freezeTime >= 16 then runTime = now - runTime - df("%s freeze. used %ims, resulting frametime %ims.", job.name, runTime, freezeTime) + df("%s freeze. allowed: %ims, used %ims, resulting fps %i.", job.name, spendTime, runTime, 1000 / freezeTime) end end end @@ -118,6 +125,10 @@ function async:SetDebug(enabled) debug = enabled end +function async:GetCpuLoad() + return cpuLoad / frameTimeTarget +end + -- Class task local task = async.task or ZO_Object:Subclass() @@ -139,8 +150,8 @@ end -- Resume the execution context. function task:Resume() + running = true jobs[self.name] = self - em:RegisterForUpdate(identifier, 0, Scheduler) return self end @@ -174,7 +185,7 @@ do local insert = table.insert -- Continue your task context execution with the given FuncOfTask after the previous as finished. function task:Then(funcOfTask) - assert(self.lastCallIndex > 0 and self.lastCallIndex <= #self.callstack, "cap!") + -- assert(self.lastCallIndex > 0 and self.lastCallIndex <= #self.callstack, "cap!") insert(self.callstack, self.lastCallIndex, funcOfTask) return self end @@ -338,3 +349,22 @@ end -- async.BREAK is the new 'break' for breaking loops. As Lua would not allowed the keyword 'break' in that context. -- To break a for-loop, return async.BREAK async.BREAK = true + +local function stateChange(oldState, newState) + if newState == SCENE_SHOWN or newState == SCENE_HIDING then + spendTime = GetThreshold() + end +end + +local identifier = "ASYNCTASKS_JOBS" + +HUD_SCENE:RegisterCallback("StateChange", stateChange) +HUD_UI_SCENE:RegisterCallback("StateChange", stateChange) + +function async:Unload() + HUD_SCENE:UnregisterCallback("StateChange", stateChange) + HUD_UI_SCENE:UnregisterCallback("StateChange", stateChange) +end + +em:UnregisterForUpdate(identifier) +em:RegisterForUpdate(identifier, 0, Scheduler)