2.4.1 updated LibAsync

git [05-20-18 - 09:15]
2.4.1 updated LibAsync
Filename
FurnitureCatalogue.txt
libs/LibAsync/LibAsync.lua
diff --git a/FurnitureCatalogue.txt b/FurnitureCatalogue.txt
index 3073a99..e691ac4 100644
--- a/FurnitureCatalogue.txt
+++ b/FurnitureCatalogue.txt
@@ -1,6 +1,6 @@
 ## Title: FurnitureCatalogue
 ## Author: manavortex
-## Version: 2.4
+## Version: 2.4.1
 ## APIVersion: 100022 100023
 ## SavedVariables: FurnitureCatalogue_Settings
 ## OptionalDependsOn: pChat
diff --git a/libs/LibAsync/LibAsync.lua b/libs/LibAsync/LibAsync.lua
index d5dab4b..6c1cfaa 100644
--- a/libs/LibAsync/LibAsync.lua
+++ b/libs/LibAsync/LibAsync.lua
@@ -1,4 +1,4 @@
-local MAJOR, MINOR = "LibAsync", 1.3
+local MAJOR, MINOR = "LibAsync", 1.6
 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

@@ -27,12 +27,12 @@ local function DoCallback(job, callstackIndex)
 		job.Error = shouldContinue
 		RemoveCall(job, callstackIndex)

-		call = job.OnError
+		call = job.onError
 		if call then
 			pcall(safeCall)
 		else
 			job:Suspend()
-			error(job)
+			error(job.Error)
 		end
 	end
 end
@@ -48,8 +48,8 @@ local function DoJob(job)
 	if call then
 		DoCallback(job, index)
 	else
-		assert(index == 0, "No call on non-empty stack?!")
-		jobs[job] = nil
+		-- assert(index == 0, "No call on non-empty stack?!")
+		jobs[job.name] = nil
 		call = job.finally
 		if call then pcall(safeCall) end
 	end
@@ -57,21 +57,32 @@ 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 = 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 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
@@ -80,25 +91,27 @@ local function Scheduler()
 	if debug then
 		df("initial gap: %ims", GetGameTimeMilliseconds() - start)
 	end
+	local name
 	while (GetGameTimeMilliseconds() - start) <= spendTime do
-		job = next(jobs, job) or next(jobs)
+		name, job = next(jobs)
 		if job then
 			runTime = GetGameTimeMilliseconds()
 			DoJob(job)
+			spendTime = spendTime - 0.001
 		else
 			-- Finished
-			em:UnregisterForUpdate(identifier)
-			spendTime = spendTimeDef
+			running = false
+			spendTime = GetThreshold()
 			return
 		end
 	end
-	spendTime = spendTimeDef
+	-- 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
@@ -111,6 +124,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()
@@ -132,24 +149,24 @@ end

 -- Resume the execution context.
 function task:Resume()
-	jobs[self] = true
-	em:RegisterForUpdate(identifier, 0, Scheduler)
+	running = true
+	jobs[self.name] = self
 	return self
 end

 -- Suspend the execution context and allow to resume anytime later.
 function task:Suspend()
-	jobs[self] = nil
+	jobs[self.name] = nil
 	return self
 end

 -- Interupt and fully stop the execution context. Can be called from outside to stop everything.
 function task:Cancel()
-	if jobs[self] then
-		ZO_ClearNumericallyIndexedTable(self.callstack)
-		self.lastCallIndex = 0
+	ZO_ClearNumericallyIndexedTable(self.callstack)
+	self.lastCallIndex = 0
+	if jobs[self.name] then
 		if not self.finally then
-			jobs[self] = nil
+			jobs[self.name] = nil
 			-- else run job with empty callstack to run finalizer
 		end
 	end
@@ -167,7 +184,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
@@ -277,7 +294,8 @@ do
 					-- repeatly call this function until i >= j
 					return true
 				end
-			end ):Then( function()
+			end )
+			task:Then( function()
 				if compare(pivot, array[i]) then array[i], array[right] = array[right], array[i] end
 				quicksort(left, i - 1)
 				quicksort(i + 1, right)
@@ -330,3 +348,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)