98 lines
2.2 KiB
Lua
98 lines
2.2 KiB
Lua
|
if component then
|
||
|
function log(...)
|
||
|
for k,v in ipairs({...}) do
|
||
|
component.invoke(component.list("ocemu")(),"log",v)
|
||
|
end
|
||
|
end
|
||
|
print=log
|
||
|
else log = print
|
||
|
end
|
||
|
do -- so local works
|
||
|
-- task format:
|
||
|
-- {
|
||
|
-- ["n"] = "name",
|
||
|
-- ["c"] = coroutine of task,
|
||
|
-- ["e"] = { table, of, environment, variables },
|
||
|
-- ["p"] = parent pid,
|
||
|
-- ["u"] = user ID,
|
||
|
-- ["ep"]= event queue pointer
|
||
|
-- }
|
||
|
local tT,nP,rg,eq,p = {},1,_G,{},1 -- taskTable,nextPid,real _G,event queue
|
||
|
_G.cT,sbt,C,T = 0,{},coroutine,table -- currentTask,sandboxTable
|
||
|
function _G.spawn(n,f,e)
|
||
|
tT[nP] = {}
|
||
|
sbt[nP] = {}
|
||
|
setmetatable(sbt[nP],{__index=_G})
|
||
|
_ENV = sbt[nP]
|
||
|
tT[nP].c = coroutine.create(f)
|
||
|
_ENV = rg
|
||
|
tT[nP].n = n
|
||
|
tT[nP].p = cT or -1
|
||
|
if tT[cT] then
|
||
|
tT[nP].u,tT[nP].ep,tT[nP].e = tT[cT].u,tT[cT].ep,e or tT[cT].e or {}
|
||
|
else
|
||
|
tT[nP].u,tT[nP].ep,tT[nP].e = 0,1,{}
|
||
|
end
|
||
|
nP = nP + 1
|
||
|
end
|
||
|
function _G.sched()
|
||
|
_G.sched = nil
|
||
|
while #tT > 0 do
|
||
|
eq[#eq+1]={computer.pullSignal(p)} -- add the latest event to the eq
|
||
|
if #eq > 16 then
|
||
|
table.remove(eq,1) -- remove the earliest if the eq is full
|
||
|
for pid,proc in ipairs(tT) do
|
||
|
if proc.ep > 1 then
|
||
|
proc.ep = proc.ep - 1 -- decrement pointers for tasks to keep them on the same ones
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
for pid,proc in ipairs(tT) do
|
||
|
if coroutine.status(proc.c) == "dead" then
|
||
|
tT[pid] = nil
|
||
|
else
|
||
|
cT=pid
|
||
|
sbt[pid].ev = eq[#eq] -- make an ev for MultICE compat
|
||
|
coroutine.resume(proc.c)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
_G.event = {}
|
||
|
function event.get() -- get the next event in the queue, or nil
|
||
|
if eq[tT[cT].ep] then
|
||
|
tT[cT].ep = tT[cT].ep + 1
|
||
|
if tT[cT].ep > 17 then
|
||
|
tT[cT].ep = 17
|
||
|
end
|
||
|
return eq[tT[cT].ep - 1]
|
||
|
end
|
||
|
end
|
||
|
function event.pull(t) -- return or wait for the next event, optionally with the first param matching t
|
||
|
while true do
|
||
|
local e = event.get()
|
||
|
if e then
|
||
|
if t then
|
||
|
if e[1] == t then
|
||
|
return table.unpack(e)
|
||
|
end
|
||
|
else
|
||
|
return table.unpack(e)
|
||
|
end
|
||
|
end
|
||
|
coroutine.yield()
|
||
|
end
|
||
|
end
|
||
|
event.push = computer.pushSignal
|
||
|
function os.getenv(k)
|
||
|
if tT[cT] then
|
||
|
return tT[cT].e[k]
|
||
|
end
|
||
|
end
|
||
|
function os.setenv(k,v)
|
||
|
if tT[cT] then
|
||
|
tT[cT].e[k] = v
|
||
|
end
|
||
|
end
|
||
|
end
|