1 QuestHelper_File
["timeslice.lua"] = "Development Version"
3 -- Any non-local item here is part of an available public interface.
5 local coroutine_running
= false
6 local coroutine_stop_time
= 0
7 local coroutine_list
= {}
8 local coroutine_route_pass
= 1
10 local coroutine_verbose
= false
12 local coroutine_time_used
= {}
13 local coroutine_power_up
= GetTime()
15 function QH_Timeslice_DumpPerf()
17 for k
, v
in pairs(coroutine_time_used
) do
18 table.insert(sortable
, {name
= k
, amount
= v
})
20 table.sort(sortable
, function(a
, b
) return a
.name
< b
.name
end)
21 for _
, v
in pairs(sortable
) do
22 QuestHelper
:TextOut(string.format("%s: %f", QuestHelper
:HighlightText(v
.name
), v
.amount
))
24 QuestHelper
:TextOut(string.format("%s: %f", QuestHelper
:HighlightText("poweron"), GetTime() - coroutine_power_up
))
27 function QH_Timeslice_Yield()
28 if coroutine_running
then
29 -- Check if we've run our alotted time
30 if GetTime() > coroutine_stop_time
then
31 -- As a safety, reset stop time to 0. If somehow we fail to set it next time,
32 -- we'll be sure to yield promptly.
33 coroutine_stop_time
= 0
39 function QH_Timeslice_Bonus(quantity
)
40 if coroutine_verbose
then QuestHelper
:TextOut(string.format("timeslice: %d bonus", quantity
)) end
41 coroutine_route_pass
= coroutine_route_pass
+ quantity
44 function QH_Timeslice_Add(workfunc
, priority
, name
)
45 if coroutine_verbose
then QuestHelper
:TextOut(string.format("timeslice: %s added (%s, %d)", name
, tostring(workfunc
), priority
)) end
46 local ncoro
= coroutine
.create(workfunc
)
47 QuestHelper
: Assert(ncoro
)
48 table.insert(coroutine_list
, {priority
= priority
, name
= name
, coro
= ncoro
, active
= true})
51 function QH_Timeslice_Toggle(name
, flag
)
52 --if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: %s toggled to %s", name, tostring(not not flag))) end
53 for _
, v
in pairs(coroutine_list
) do
54 if v
.name
== name
then v
.active
= flag
end
58 function QH_Timeslice_Work()
59 -- There's probably a better way to do this, but. Eh. Lua.
62 for k
, v
in pairs(coroutine_list
) do
63 if v
.active
and (not coro
or v
.priority
> coro
.priority
) then coro
= v
; key
= k
end
67 --if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: %s running", coro.name)) end
69 QuestHelper
: Assert(coroutine
.status(coro
.coro
) ~= "dead")
70 coroutine_stop_time
= GetTime() + 4e-3 * QuestHelper_Pref
.perf_scale
* math
.min(coroutine_route_pass
, 5)
71 coroutine_route_pass
= coroutine_route_pass
- 5
72 if coroutine_route_pass
<= 0 then coroutine_route_pass
= 1 end
74 local start
= GetTime()
75 coroutine_running
= true
76 local state
, err
= coroutine
.resume(coro
.coro
)
77 coroutine_running
= false
78 local total
= GetTime() - start
80 coroutine_time_used
[coro
.name
] = (coroutine_time_used
[coro
.name
] or 0) + total
83 if coroutine_verbose
then QuestHelper
:TextOut(string.format("timeslice: %s errored", coro
.name
)) end
84 QuestHelper_ErrorCatcher_ExplicitError(err
, "", string.format("(Coroutine error in %s)\n", coro
.name
))
87 QuestHelper
: Assert(coro
.coro
)
88 if coroutine
.status(coro
.coro
) == "dead" then
89 if coroutine_verbose
then QuestHelper
:TextOut(string.format("timeslice: %s complete", coro
.name
)) end
90 coroutine_list
[key
] = nil
93 if coroutine_verbose
then QuestHelper
:TextOut(string.format("timeslice: no available tasks")) end