1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-05-08 02:14:12 +00:00

Clean up the parallel API

- Store the filter alongside the coroutine rather than in a separate
   table (like we do in multishell).

 - Remove the redudant (I think!) second loop that checks for dead
   coroutines. We already check for dead coroutines in the main loop.

 - Rename some variables to be a bit more consistent. This makes this
   commit look noisier than it is. Sorry!
This commit is contained in:
Jonathan Coates 2025-02-09 16:52:06 +00:00
parent 4360485880
commit 88cb03be6b
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06

View File

@ -40,59 +40,47 @@ the other.
]] ]]
local function create(...) local function create(...)
local tFns = table.pack(...) local functions = table.pack(...)
local tCos = {} local threads = {}
for i = 1, tFns.n, 1 do for i = 1, functions.n, 1 do
local fn = tFns[i] local fn = functions[i]
if type(fn) ~= "function" then if type(fn) ~= "function" then
error("bad argument #" .. i .. " (function expected, got " .. type(fn) .. ")", 3) error("bad argument #" .. i .. " (function expected, got " .. type(fn) .. ")", 3)
end end
tCos[i] = coroutine.create(fn) threads[i] = { co = coroutine.create(fn), filter = nil }
end end
return tCos return threads
end end
local function runUntilLimit(_routines, _limit) local function runUntilLimit(threads, limit)
local count = #_routines local count = #threads
if count < 1 then return 0 end if count < 1 then return 0 end
local living = count local living = count
local tFilters = {} local event = { n = 0 }
local eventData = { n = 0 }
while true do while true do
for n = 1, count do for i = 1, count do
local r = _routines[n] local thread = threads[i]
if r then if thread and (thread.filter == nil or thread.filter == event[1] or event[1] == "terminate") then
if tFilters[r] == nil or tFilters[r] == eventData[1] or eventData[1] == "terminate" then local ok, param = coroutine.resume(thread.co, table.unpack(event, 1, event.n))
local ok, param = coroutine.resume(r, table.unpack(eventData, 1, eventData.n)) if not ok then
if not ok then error(param, 0)
error(param, 0) else
else thread.filter = param
tFilters[r] = param end
end if coroutine.status(thread.co) == "dead" then
if coroutine.status(r) == "dead" then threads[i] = false
_routines[n] = nil living = living - 1
living = living - 1 if living <= limit then
if living <= _limit then return i
return n
end
end end
end end
end end
end end
for n = 1, count do
local r = _routines[n] event = table.pack(os.pullEventRaw())
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
end end
@ -120,8 +108,8 @@ from the [`parallel.waitForAny`] call.
print("Everything done!") print("Everything done!")
]] ]]
function waitForAny(...) function waitForAny(...)
local routines = create(...) local threads = create(...)
return runUntilLimit(routines, #routines - 1) return runUntilLimit(threads, #threads - 1)
end end
--[[- Switches between execution of the functions, until all of them are --[[- Switches between execution of the functions, until all of them are
@ -144,6 +132,6 @@ from the [`parallel.waitForAll`] call.
print("Everything done!") print("Everything done!")
]] ]]
function waitForAll(...) function waitForAll(...)
local routines = create(...) local threads = create(...)
return runUntilLimit(routines, 0) return runUntilLimit(threads, 0)
end end