-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtask.lua
147 lines (127 loc) · 3.35 KB
/
task.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
local yield = coroutine.yield
local create = coroutine.create
local resume = coroutine.resume
local timerSimple = timer.Simple
local SysTime = SysTime
local call = hook.Run
local Create, GetTable do
local Run, co, running, start
local pcall, ErrorNoHalt = pcall, ErrorNoHalt
local index, list, names = 0, {}, {}
local rate = 1 / 300 --This is the allowable time for the task to be completed
local wait = 1 / 16 --This is the time between executions
function GetTable() return list, index end
function Create(name, fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
index = index + 1
names[index] = name
list[index] = function()
return pcall(fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
end
if not running then
running = true
timerSimple(wait, Run)
end
return index
end
function Run()
start = SysTime()
local success, breakruntime = resume(co)
if not success or breakruntime then
running = false
else
timerSimple(wait, Run)
end
end
co = create(function()
while true do
local fn, name = list[index], names[index]
index = index - 1
if fn ~= nil then
if SysTime() - start > rate then yield() end
local succ, err = fn()
if not succ then
ErrorNoHalt('Task failed: ', name, '\n\t', err, '\n')
end
end
if index == 0 then yield(true) end
end
end)
end
local NewThread, GetThreadTable do
local format = string.format
local timerCreate = timer.Create
local timerRemove = timer.Remove
local wait = coroutine.wait
local status = coroutine.status
local start = 0
local mt = {counter = 0}
local pool = {}
mt.__index = mt
function mt:Remove()
timerRemove(self.id)
call('ThreadDestroy', self.name)
end
function mt:Destroy()
self.Callback()
timerRemove(self.id)
call('ThreadDestroy', self.name)
end
function mt:SetRemoveCondition(fn)
self.shouldrm = fn
end
function mt:yield(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
yield(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
end
function mt:wait(s)
wait(s)
end
function mt:pause(c)
self.counter = self.counter + 1
if self.counter > c then
self.counter = 0
yield()
end
end
function mt:limit(c)
if SysTime() - start > c then yield() end
end
function mt:status()
return status(self.thread)
end
function mt:wrap(fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
local co = create(fn)
self.Callback = function()
if status(co) == 'dead' or (self.shouldrm and self:shouldrm()) then self:Remove() return end
start = SysTime()
local succ, out1, out2, out3, out4, out5, out6, out7, out8 =
resume(co, self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
if not succ then Error(out1) end
return out1, out2, out3, out4, out5, out6, out7, out8
end
self.thread = co
return self.Callback
end
function mt:GetRuntime()
return SysTime() - self.start
end
function mt:__call()
return self.fn()
end
function NewThread(name, rate, fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
call('ThreadRunning', name)
local id = format('ThreadObject::%s', name)
local obj = setmetatable({name = name, id = id, start = SysTime()}, mt)
timerCreate(id,
rate, 0, obj:wrap(fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8))
return obj
end
function GetThreadTable()
return pool
end
end
task = {
Create = Create,
GetTable = GetTable,
NewThread = NewThread,
GetThreadTable = GetThreadTable
}