-
Notifications
You must be signed in to change notification settings - Fork 198
/
parallel.lua
66 lines (59 loc) · 1.54 KB
/
parallel.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
local function create( ... )
local tFns = table.pack(...)
local tCos = {}
for i = 1, tFns.n, 1 do
local fn = tFns[i]
if type( fn ) ~= "function" then
error( "bad argument #" .. i .. " (expected function, got " .. type( fn ) .. ")", 3 )
end
tCos[i] = coroutine.create(fn)
end
return tCos
end
local function runUntilLimit( _routines, _limit )
local count = #_routines
local living = count
local tFilters = {}
local eventData = { n = 0 }
while true do
for n=1,count do
local r = _routines[n]
if r then
if tFilters[r] == nil or tFilters[r] == eventData[1] or eventData[1] == "terminate" then
local ok, param = coroutine.resume( r, table.unpack( eventData, 1, eventData.n ) )
if not ok then
error( param, 0 )
else
tFilters[r] = param
end
if coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
end
end
for n=1,count do
local r = _routines[n]
if r and coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
eventData = table.pack( os.pullEventRaw() )
end
end
function waitForAny( ... )
local routines = create( ... )
return runUntilLimit( routines, #routines - 1 )
end
function waitForAll( ... )
local routines = create( ... )
runUntilLimit( routines, 0 )
end