1
0
Bifurcation 0
Ce dépôt a été archivé le 2020-03-15. Vous pouvez voir ses fichiers ou le cloner, mais pas ouvrir de ticket ou de demandes d'ajout, ni soumettre de changements.
questhelperredux/QuestHelper/timeslice.lua
Nathanial.C.Jones 87617c4eed QH Now queries the WoW client for quests, though it doesn't seem to update correctly when a quest is accepted (and though untested, probably doesn't update locations when the WoW poi changes).
Added LibMapData and began transitioning map data needs to use LibMapData.

Began changing the data collection, yet again. Once this goes beta, the new collection system will be in place... My hope is to allow QH to "learn" as you play, eliminating any need for data compilation, though I will still make attempts to compile said data into a full on db.

Added some code that will eventually be usable to get data from LightHeaded. This is not yet implemented in full, but will be the preferred method of QH doesn't know about a quest. Order of preference will eventually be: 1) Learned data, 2) Internal DB, 3) LightHeaded, 4) WoW client.

NOTE: THIS COMMIT IS ON THE WOW-DB-GET BRANCH. An alpha release will be up on the downloads page by 6:30 US EST on February 29, 2012 (tomorrow).

I THINK I have covered all the changes in this, but I have done so much since my last commit, I cannot be sure.
2012-02-29 03:27:41 +00:00

233 lignes
8,4 Kio
Lua

local GetTime = QuestHelper_GetTime
QuestHelper_File["timeslice.lua"] = "4.0.1.$svnversion$"
QuestHelper_Loadtime["timeslice.lua"] = GetTime()
local debug_output = (QuestHelper_File["timeslice.lua"] == "Development Version")
-- Any non-local item here is part of an available public interface.
local coroutine_running = false
local coroutine_stop_time = 0
local coroutine_list = {}
local coroutine_route_pass = 1
local coroutine_verbose = false
local coroutine_time_used = {}
local coroutine_power_up = GetTime()
local coroutine_time_exceeded = 0
function QH_Timeslice_DumpPerf()
local sortable = {}
for k, v in pairs(coroutine_time_used) do
table.insert(sortable, {name = k, amount = v})
end
table.sort(sortable, function(a, b) return a.name < b.name end)
for _, v in pairs(sortable) do
QuestHelper:TextOut(string.format("%s: %f", QuestHelper:HighlightText(v.name), v.amount))
end
QuestHelper:TextOut(string.format("%s: %f", QuestHelper:HighlightText("poweron"), GetTime() - coroutine_power_up))
end
local last_stack = nil
local yield_ct = 0
local GetTime = GetTime
local unyieldable = 0
function QH_Timeslice_GetUnyieldable()
return unyieldable
end
function QH_Timeslice_PushUnyieldable()
unyieldable = unyieldable + 1
--print(unyieldable)
end
function QH_Timeslice_PopUnyieldable()
unyieldable = unyieldable - 1
--print(unyieldable)
QuestHelper: Assert(unyieldable >= 0)
end
function QH_Timeslice_Yield()
if unyieldable > 0 then return end
if coroutine_running then
-- Check if we've run our alotted time
yield_ct = yield_ct + 1
if GetTime() > coroutine_stop_time then
local sti = debugstack(2, 5, 5) -- string.gsub(debugstack(2, 1, 1), "\n.*", "")
if qh_loud_and_annoying and GetTime() > coroutine_stop_time + 0.0015 then
print(yield_ct, (GetTime() - coroutine_stop_time) * 1000, "took too long", sti, "------ from", last_stack, "------")
end
-- As a safety, reset stop time to 0. If somehow we fail to set it next time,
-- we'll be sure to yield promptly.
coroutine_stop_time = 0
coroutine.yield()
last_stack = sti
yield_ct = 0
end
end
end
function QH_Timeslice_Bonus(quantity)
if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: %d bonus", quantity)) end
coroutine_route_pass = coroutine_route_pass + quantity
end
local prioritize = {
preinit = {101},
init = {100},
criteria = {10},
lzw = {-5},
compress = {-8, 5},
new_routing = {-10},
}
local bumped_priority = {}
function QH_Timeslice_Add(workfunc, name)
QuestHelper: Assert(workfunc)
QuestHelper: Assert(name)
local priority = prioritize[name] and prioritize[name][1] or 0
local sharding = prioritize[name] and prioritize[name][2] or 1
if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: %s added (%s, %d)", name, tostring(workfunc), priority)) end
local ncoro = coroutine.create(workfunc)
QuestHelper: Assert(ncoro)
table.insert(coroutine_list, {priority = priority, sharding = sharding, name = name, coro = ncoro, active = true})
end
function QH_Timeslice_Toggle(name, flag)
--if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: %s toggled to %s", name, tostring(not not flag))) end
for _, v in pairs(coroutine_list) do
if v.name == name then v.active = flag end
end
end
local started = false
function QH_Timeslice_Doneinit()
if not started then
if debug_output then
QuestHelper:TextOut("Done with initialization step")
end
QuestHelper.loading_main = nil
QuestHelper.loading_flightpath = nil
QuestHelper.loading_preroll = nil
collectgarbage("collect") -- fuuuuuck youuuuuuuu
end
started = true
end
function QH_Timeslice_Bump(type, newpri)
bumped_priority[type] = newpri
end
function QH_Timeslice_Bump_Reset(type)
bumped_priority[type] = nil
end
local startacu = GetTime()
local totalacu = 0
local lacu = 0
--[[function qhtacureset()
startacu = GetTime()
totalacu = 0
lacu = 0
end]]
local thrown_away_excess = 0
local total_used = 0
function QH_Timeslice_Work(time_used, time_this_frame, bonus_time, verbose)
-- There's probably a better way to do this, but. Eh. Lua.
QuestHelper: Assert(unyieldable == 0)
local coro = nil
local key = nil
local cpri = nil
for k, v in pairs(coroutine_list) do
if v.active then
--if v.sharding then QuestHelper:TextOut(string.format("%d mod %d is %d, %s", time(), v.sharding, bit.mod(time(), v.sharding), tostring(bit.mod(time(), v.sharding) == 0))) end
local pri = bumped_priority[v.name] or v.priority
if (not v.sharding or bit.mod(time(), v.sharding) == 0) and (not coro or (pri > cpri)) then
coro = v
key = k
cpri = pri
end
end
end
if coro then
--if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: %s running", coro.name)) end
if coroutine.status(coro.coro) == "dead" then -- Someone was claiming to get an infinite loop with this. I don't see how it's possible, but this should at least fix the infinite loop.
coroutine_list[key] = nil
end
QuestHelper: Assert(coroutine.status(coro.coro) ~= "dead")
local slicefactor = (QuestHelper_Pref.hide and 0.01 or (QuestHelper_Pref.perf_scale_2 * math.min(coroutine_route_pass, 5)))
if not started then slicefactor = 5 * QuestHelper_Pref.perfload_scale * math.min(coroutine_route_pass, 5) end -- the init process gets much higher priority so we get done with it faster
local time_to_use = slicefactor * time_this_frame * 0.075 -- We want to use 7.5% of the system CPU
if InCombatLockdown() then time_to_use = time_to_use / 5 end
local coroutine_intended_stop_time = time_to_use
coroutine_stop_time = coroutine_intended_stop_time - coroutine_time_exceeded - time_used + bonus_time
coroutine_route_pass = coroutine_route_pass - 5
if coroutine_route_pass <= 0 then coroutine_route_pass = 1 end
if verbose then
print(string.format("time_to_use %f, time_already_used %f, bonus_time %f, coroutine_time_exceeded %f, total_time_to_use %f", time_to_use, time_used, bonus_time, coroutine_time_exceeded, coroutine_stop_time))
print(string.format("thrown_away_excess %f, used %f, maxi %f", thrown_away_excess, total_used, slicefactor * 0.075 * 5))
end
local start = GetTime()
coroutine_stop_time, coroutine_intended_stop_time = coroutine_stop_time + start, coroutine_intended_stop_time + start
local state, err = true, nil -- default values for "we're fine"
totalacu = totalacu + math.max(0, coroutine_stop_time - start)
--[[if lacu + 0.1 < totalacu then
lacu = totalacu
print(string.format("%f realtime, %f runtime, %f%%", start - startacu, totalacu, (totalacu / (start - startacu)) * 100))
end]]
if start < coroutine_stop_time then -- We don't want to just return on failure because we want to credit the exceeded time properly.
coroutine_running = true
QuestHelper: Assert(unyieldable == 0)
state, err = coroutine.resume(coro.coro)
QuestHelper: Assert(unyieldable == 0, "Unyieldable was " .. unyieldable)
coroutine_running = false
end
local stop = GetTime()
local total = stop - start
local coroutine_this_cycle_exceeded = stop - coroutine_intended_stop_time -- may be either positive or negative
local origcte = coroutine_time_exceeded + coroutine_this_cycle_exceeded
coroutine_time_exceeded = min(origcte, slicefactor * 0.075 * 5) -- honestly, waiting for more than five seconds to recover from a stutter is just dumb
thrown_away_excess = thrown_away_excess + (origcte - coroutine_time_exceeded)
total_used = total_used + total
coroutine_time_used[coro.name] = (coroutine_time_used[coro.name] or 0) + total
if not state then
if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: %s errored", coro.name)) end
QuestHelper_ErrorCatcher_ExplicitError(true, err, "", string.format("(Coroutine error in %s)\n", coro.name))
end
QuestHelper: Assert(coro.coro)
if coroutine.status(coro.coro) == "dead" then
if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: %s complete", coro.name)) end
coroutine_list[key] = nil
end
else
if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: no available tasks")) end
end
end
function QH_Timeslice_Increment(quantity, name)
local an = "(nc) " .. name
coroutine_time_used[an] = (coroutine_time_used[an] or 0) + quantity
end