Merge pull request #2 from manavortex/master

Baertram [06-27-18 - 13:53]
Merge pull request #2 from manavortex/master

Updates from manavortex/master branch -> FCOIS integration
Filename
.gitignore
IIfA/IIfABackpack.lua
IIfA/IIfADataCollection.lua
IIfA/IIfAEvents.lua
IIfA/IIfASceneFuncs.lua
IIfA/IIfASettingsAdapter.lua
IIfA/IIfA_xml_adapter.lua
IIfA/libs/LibAsync/LibAsync.lua
diff --git a/.gitignore b/.gitignore
index 3fa3560..04cf002 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ IIfA/.idea/dictionaries/P.xml
 IIfA/.idea/misc.xml
 IIfA/.idea/modules.xml
 IIfA/.idea/workspace.xml
+assets/
\ No newline at end of file
diff --git a/IIfA/IIfABackpack.lua b/IIfA/IIfABackpack.lua
index 2f4a9c7..c9472b1 100644
--- a/IIfA/IIfABackpack.lua
+++ b/IIfA/IIfABackpack.lua
@@ -757,6 +757,8 @@ p("OnChestSelect '<<1>>' - <<2>>", choiceText, choice)
 				if cName == self.EMPTY_STRING then
 					cName = GetCollectibleName(cId)
 				end
+                		--remove gender specific characters from house bank chest name
+                		cName = zo_strformat("<<C:1>>", cName)
 				if cName == choiceText then
 					IIfA:SetInventoryListFilter("Housing Storage", ctr)
 					break
@@ -788,6 +790,8 @@ p("OnChestSelect '<<1>>' - <<2>>", choiceText, choice)
 				if cName == self.EMPTY_STRING then
 					cName = GetCollectibleName(cId)
 				end
+                		--remove gender specific characters from house bank chest name
+                		cName = zo_strformat("<<C:1>>", cName)
 				entry = comboBox:CreateItemEntry(cName, OnChestSelect)
 				comboBox:AddItem(entry)
 			end
diff --git a/IIfA/IIfADataCollection.lua b/IIfA/IIfADataCollection.lua
index 84d0d48..2f4f935 100644
--- a/IIfA/IIfADataCollection.lua
+++ b/IIfA/IIfADataCollection.lua
@@ -80,8 +80,7 @@ function IIfA:CollectGuildBank(curGuild)
 		end
 	end

-	SelectGuildBank(CurGB)
-	local count = 0
+	SelectGuildBank(curGB)

 	if(IIfA.data.guildBanks[curGuild] == nil) then
 		IIfA.data.guildBanks[curGuild] = {}
@@ -95,7 +94,7 @@ function IIfA:CollectGuildBank(curGuild)
 		IIfA.BagSlotInfo = IIfA.BagSlotInfo or {}
 		p("Collect guild bank - <<1>>", curGuild)
 		local guildData = IIfA.data.guildBanks[curGuild]
-		local itemCount, i, slotIndex
+		local itemCount, slotIndex
 		itemCount = 0
 		slotIndex = ZO_GetNextBagSlotIndex(BAG_GUILDBANK, nil)
 		while slotIndex do
@@ -105,7 +104,6 @@ function IIfA:CollectGuildBank(curGuild)

 		p("GuildBank Item Count = " .. itemCount)

---		guildData.items = #ZO_GuildBankBackpack.data
 		guildData.lastCollected = GetDate() .. "@" .. GetFormattedTime();

 		IIfA:ClearLocationData(curGuild)
@@ -122,12 +120,10 @@ function IIfA:CollectGuildBank(curGuild)
 			IIfA.BagSlotInfo[curGuild][slotIndex] = itemKey
 			slotIndex = ZO_GetNextBagSlotIndex(BAG_GUILDBANK, slotIndex)
 		end
+		p("IIfA - Guild Bank Collected - " .. curGuild .. ", itemCount=" .. itemCount)
 	end)
-	p("IIfA - Guild Bank Collected - " .. curGuild .. ", itemCount=" .. itemCount)
 end

-
-
 function IIfA:ScanCurrentCharacter()

 	local playerName = GetUnitName('player')
@@ -308,12 +304,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 +323,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
@@ -452,6 +460,7 @@ function IIfA:EvalBagItem(bagId, slotId, fromXfer, qty, itemLink, itemName, loca
 	-- item count is either passed or we have to get it from bag/slot ID or item link
 	local bAddQty = false
 	if qty ~= nil then bAddQty = true end
+
 	local itemCount = qty or getItemCount(bagId, slotId, itemLink)

 	--p("trying to save <<1>> x<<2>>", itemLink, itemCount)
@@ -697,12 +706,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/IIfAEvents.lua b/IIfA/IIfAEvents.lua
index d0f29a6..b190a01 100644
--- a/IIfA/IIfAEvents.lua
+++ b/IIfA/IIfAEvents.lua
@@ -154,7 +154,7 @@ local function fgb4(...)
 	IIfA_EventDump(...)
 end
 local function fgb5(...)
-	d("gb items ready")
+	d("inventory fragment state change")
 	IIfA_EventDump(...)
 end

@@ -206,6 +206,7 @@ function IIfA:RegisterForEvents()

 	--    ZO_QuickSlot:RegisterForEvent(EVENT_ABILITY_COOLDOWN_UPDATED, IIfA_EventDump)
 	ZO_PreHook('ZO_InventorySlot_ShowContextMenu', function(rowControl) IIfA:ProcessRightClick(rowControl) end)
+
 end


diff --git a/IIfA/IIfASceneFuncs.lua b/IIfA/IIfASceneFuncs.lua
index e58fbe8..8999738 100644
--- a/IIfA/IIfASceneFuncs.lua
+++ b/IIfA/IIfASceneFuncs.lua
@@ -37,22 +37,34 @@ function IIfA:RegisterForSceneChanges()
 			end
 		end
 	end
+
+	INVENTORY_FRAGMENT:RegisterCallback("StateChange", function(...)
+	   	IIfA:ProcessInventoryTabChange("", ...)
+	end)
+	CRAFT_BAG_FRAGMENT:RegisterCallback("StateChange", function(...)
+	   	IIfA:ProcessInventoryTabChange("", ...)
+	end)
+	WALLET_FRAGMENT:RegisterCallback("StateChange", function(...)
+	   	IIfA:ProcessInventoryTabChange("", ...)
+	end)
+	QUICKSLOT_FRAGMENT:RegisterCallback("StateChange", function(...)
+	   	IIfA:ProcessInventoryTabChange("_quickSlots", ...)
+	end)
 end

 function IIfA:GetSceneSettings(sceneName)

 	sceneName = sceneName or IIfA:GetCurrentSceneName()
-
-
 	local settings = IIfA:GetSettings().frameSettings
-
 	if not settings[sceneName] then
 		-- if we have to create a new set of scene info, register it in the scene change too, it'll be set again during next opening

 		local scene = SCENE_MANAGER:GetScene(sceneName)
-		scene:RegisterCallback("StateChange", function(...)
-				IIfA:ProcessSceneChange(sceneName, ...)
-			end)
+		if scene then
+			scene:RegisterCallback("StateChange", function(...)
+					IIfA:ProcessSceneChange(sceneName, ...)
+				end)
+		end
 		-- save the settings in the settings table, base it on HUD
 		settings[sceneName] = ZO_DeepTableCopy(settings["hud"])
 		settings[sceneName].hidden = true
@@ -68,6 +80,23 @@ function IIfA:ProcessSceneChange(sceneName, oldState, newState)
 	-- IIfA:DebugOut(zo_strformat("ProcessSceneChange <<1>>: <<2>> -> <<3>>", sceneName, oldState, newState))
 	if SCENE_SHOWN == newState then
 		sceneName = IIfA:GetCurrentSceneName()
+		if sceneName == "inventory" then
+			if not QUICKSLOT_FRAGMENT:IsHidden() then
+				sceneName = sceneName .. "_quickslots"
+			end
+		end
+		local settings = IIfA:GetSceneSettings(sceneName)
+		self:RePositionFrame(settings)
+	elseif SCENE_HIDDEN == newState then
+		IIFA_GUI:SetHidden(true)
+	end
+end
+
+
+function IIfA:ProcessInventoryTabChange(tabName, oldState, newState)
+	-- IIfA:DebugOut(zo_strformat("ProcessSceneChange <<1>>: <<2>> -> <<3>>", oldState, newState))
+	if newState == SCENE_SHOWN then
+		sceneName = "inventory" .. tabName
 		local settings = IIfA:GetSceneSettings(sceneName)
 		self:RePositionFrame(settings)

@@ -81,6 +110,10 @@ function IIfA:SaveFrameInfo(calledFrom)
 	if (calledFrom == "onHide") then return end

 	local sceneName = IIfA:GetCurrentSceneName()
+	if not QUICKSLOT_FRAGMENT:IsHidden() then
+		sceneName = sceneName .. "_quickslots"
+	end
+
 	local settings = IIfA:GetSceneSettings(sceneName)

     settings.hidden = IIFA_GUI:IsControlHidden()
@@ -95,7 +128,7 @@ function IIfA:SaveFrameInfo(calledFrom)
 	end
 end

--- called only from bindings.xml on keypress
+-- called from bindings.xml on keypress, and on /iifa toggle chat cmd
 function IIfA:ToggleInventoryFrame()
 	IIFA_GUI:SetHidden(not IIFA_GUI:IsControlHidden())
 	if not IIFA_GUI:IsControlHidden() then
diff --git a/IIfA/IIfASettingsAdapter.lua b/IIfA/IIfASettingsAdapter.lua
index 1bb55f6..7143a8b 100644
--- a/IIfA/IIfASettingsAdapter.lua
+++ b/IIfA/IIfASettingsAdapter.lua
@@ -137,7 +137,10 @@ end
 function IIfA:GetTrackingWithHouseNames()
 	local ret = {}
 	for collectibleId, trackIt in pairs(IIfA.data.collectHouseData) do
-		ret[GetCollectibleName(collectibleId)] = true
+        local collectibleName = GetCollectibleName(collectibleId)
+        --remove gender specific characters from house name
+        collectibleName = zo_strformat("<<C:1>>", collectibleName)
+		ret[collectibleName] = true
 	end
 	return ret
 end
@@ -147,6 +150,8 @@ function IIfA:RebuildHouseMenuDropdowns()
 	local ignored = {}
 	for collectibleId, trackIt in pairs(IIfA.data.collectHouseData) do
 		local collectibleName = GetCollectibleName(collectibleId)
+		--remove gender specific characters from house name
+        collectibleName = zo_strformat("<<C:1>>", collectibleName)
 		-- cache house name for lookup
 		IIfA.houseNameToIdTbl[collectibleName] = collectibleId
 		local targetTable = (trackIt and tracked) or ignored
@@ -155,12 +160,14 @@ function IIfA:RebuildHouseMenuDropdowns()
 	IIfA.houseNamesIgnored = ignored
 	IIfA.houseNamesTracked = tracked
 end
+
 function IIfA:GetIgnoredHouseNames()
 	if nil == IIfA.houseNamesIgnored then
 		IIfA:RebuildHouseMenuDropdowns()
 	end
 	return IIfA.houseNamesIgnored
 end
+
 function IIfA:GetTrackedHouseNames()
 	if nil == IIfA.houseNamesIgnored then
 		IIfA:RebuildHouseMenuDropdowns()
@@ -175,6 +182,7 @@ function IIfA:GetAllHouseIds()
 	end
 	return ret
 end
+
 function IIfA:SetTrackingForHouse(houseCollectibleId, trackIt)
 	houseCollectibleId = houseCollectibleId or GetCollectibleIdForHouse(GetCurrentZoneHouseId())
 	if tonumber(houseCollectibleId) ~= houseCollectibleId then
diff --git a/IIfA/IIfA_xml_adapter.lua b/IIfA/IIfA_xml_adapter.lua
index 51f7818..c04e0c7 100644
--- a/IIfA/IIfA_xml_adapter.lua
+++ b/IIfA/IIfA_xml_adapter.lua
@@ -508,7 +508,7 @@ function IIfA:RePositionFrame(settings)
 	if bMinimize then
 		IIFA_GUI:SetResizeHandleSize(0)
 		-- have to change the constraints, it even constrains resizing by code, not just resize by sizing handles
-   		IIFA_GUI:SetDimensionConstraints(IIfA.minWidth, 33, -1, 1400)
+   		IIFA_GUI:SetDimensionConstraints(IIfA.minWidth, 44, -1, 1400)

 		IIFA_GUI:SetHeight(33)
 		IIFA_GUI:SetWidth(settings.width)
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)