update changes
[QuestHelper.git] / timeslice.lua
blobce2e4b5cff043966299dfba0ad7f645a83c9a7c2
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()
16 local sortable = {}
17 for k, v in pairs(coroutine_time_used) do
18 table.insert(sortable, {name = k, amount = v})
19 end
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))
23 end
24 QuestHelper:TextOut(string.format("%s: %f", QuestHelper:HighlightText("poweron"), GetTime() - coroutine_power_up))
25 end
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
34 coroutine.yield()
35 end
36 end
37 end
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
42 end
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})
49 end
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
55 end
56 end
58 function QH_Timeslice_Work()
59 -- There's probably a better way to do this, but. Eh. Lua.
60 coro = nil
61 key = nil
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
64 end
66 if coro then
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
82 if not state then
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))
85 end
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
91 end
92 else
93 if coroutine_verbose then QuestHelper:TextOut(string.format("timeslice: no available tasks")) end
94 end
95 end