V15.2.0 #33

Merged
rayaman merged 75 commits from v15.2.0 into master 2022-04-19 18:45:52 -04:00
12 changed files with 319 additions and 371 deletions
Showing only changes of commit 593bfd0d8c - Show all commits

View File

@ -35,6 +35,7 @@ end
multi.Version = "15.2.0" multi.Version = "15.2.0"
multi.Name = "multi.root" multi.Name = "multi.root"
multi.NIL = {Type="NIL"} multi.NIL = {Type="NIL"}
local NIL = multi.NIL
multi.Mainloop = {} multi.Mainloop = {}
multi.Children = {} multi.Children = {}
multi.Active = true multi.Active = true
@ -286,9 +287,6 @@ function multi:newConnection(protect,func,kill)
else else
function c:Fire(...) function c:Fire(...)
for i=#call_funcs,1,-1 do for i=#call_funcs,1,-1 do
if type(call_funcs[i])=="table" then
print(call_funcs[i].Parent.Type)
end
call_funcs[i](...) call_funcs[i](...)
if kill then if kill then
table.remove(call_funcs,i) table.remove(call_funcs,i)
@ -307,9 +305,6 @@ function multi:newConnection(protect,func,kill)
end end
end end
function self:connect(func) function self:connect(func)
if type(func) == "table" then
print(debug.traceback())
end
table.insert(fast,func) table.insert(fast,func)
end end
end end
@ -388,9 +383,6 @@ function multi:newConnection(protect,func,kill)
function c:connect(...)--func,name,num function c:connect(...)--func,name,num
local tab = {...} local tab = {...}
local funcs={} local funcs={}
if type(tab[1])=="table" then
print(debug.traceback())
end
for i=1,#tab do for i=1,#tab do
if type(tab[i])=="function" then if type(tab[i])=="function" then
funcs[#funcs+1] = tab[i] funcs[#funcs+1] = tab[i]
@ -714,12 +706,18 @@ function multi:newAlarm(set)
return c return c
end end
function multi:newLoop(func) function multi:newLoop(func,notime)
local c=self:newBase() local c=self:newBase()
c.Type='loop' c.Type='loop'
local start=clock() local start=clock()
function c:Act() if notime then
self.OnLoop:Fire(self,clock()-start) function c:Act()
self.OnLoop:Fire(self)
end
else
function c:Act()
self.OnLoop:Fire(self,clock()-start)
end
end end
c.OnLoop = self:newConnection() c.OnLoop = self:newConnection()
function c:fastMode() function c:fastMode()
@ -735,7 +733,6 @@ function multi:newLoop(func)
end end
function multi:newStep(start,reset,count,skip) function multi:newStep(start,reset,count,skip)
print(self.Type)
local c=self:newBase() local c=self:newBase()
think=1 think=1
c.Type='step' c.Type='step'
@ -829,7 +826,7 @@ function multi:newTLoop(func,set)
end end
function multi:setTimeout(func,t) function multi:setTimeout(func,t)
multi:newThread(function() thread.sleep(t) func() end) thread:newThread(function() thread.sleep(t) func() end)
end end
function multi:newTStep(start,reset,count,set) function multi:newTStep(start,reset,count,set)
@ -882,7 +879,7 @@ local sthread
function multi:scheduleJob(time,func) function multi:scheduleJob(time,func)
if not sthread then if not sthread then
sthread = multi:newThread("JobScheduler",function() sthread = thread:newThread("JobScheduler",function()
local time = os.date("*t", os.time()) local time = os.date("*t", os.time())
local ready = false local ready = false
while true do while true do
@ -930,7 +927,7 @@ function multi:newProcessor(name,nothread)
c.Type = "process" c.Type = "process"
c.Active = false or nothread c.Active = false or nothread
c.Name = name or "" c.Name = name or ""
c.process = self:newThread(function() c.process = thread:newThread(function()
while true do while true do
thread.hold(function() return c.Active end) thread.hold(function() return c.Active end)
__CurrentProcess = c __CurrentProcess = c
@ -957,8 +954,6 @@ function multi:newProcessor(name,nothread)
function c:Destroy() function c:Destroy()
self.OnObjectDestroyed:Fire(c) self.OnObjectDestroyed:Fire(c)
end end
c:attachScheduler()
c.initThreads()
return c return c
end end
@ -973,7 +968,7 @@ function multi.hold(func,opt)
local proc = multi.getCurrentTask() local proc = multi.getCurrentTask()
proc:Pause() proc:Pause()
if type(func)=="number" then if type(func)=="number" then
self:newThread("Hold_func",function() thread:newThread("Hold_func",function()
thread.hold(func) thread.hold(func)
death = true death = true
end) end)
@ -983,7 +978,7 @@ function multi.hold(func,opt)
proc:Resume() proc:Resume()
else else
local rets local rets
self:newThread("Hold_func",function() thread:newThread("Hold_func",function()
rets = {thread.hold(func,opt)} rets = {thread.hold(func,opt)}
death = true death = true
end) end)
@ -996,7 +991,6 @@ function multi.hold(func,opt)
end end
-- Threading stuff -- Threading stuff
local initT = false
local threadCount = 0 local threadCount = 0
local threadid = 0 local threadid = 0
thread.__threads = {} thread.__threads = {}
@ -1006,6 +1000,7 @@ local dFunc = function() return true end
thread.requests = {} thread.requests = {}
local CMD = {} -- We will compare this special local local CMD = {} -- We will compare this special local
local interval local interval
local resume, status, create, yield, running = coroutine.resume, coroutine.status, coroutine.create, coroutine.yield, coroutine.running
local t_hold, t_sleep, t_holdF, t_skip, t_holdW, t_yield, t_none = 1, 2, 3, 4, 5, 6, 7 local t_hold, t_sleep, t_holdF, t_skip, t_holdW, t_yield, t_none = 1, 2, 3, 4, 5, 6, 7
function thread.request(t,cmd,...) function thread.request(t,cmd,...)
@ -1025,9 +1020,9 @@ function thread.getRunningThread()
end end
function thread._Requests() function thread._Requests()
local t = thread.requests[coroutine.running()] local t = thread.requests[running()]
if t then if t then
thread.requests[coroutine.running()] = nil thread.requests[running()] = nil
local cmd,args = t[1],t[2] local cmd,args = t[1],t[2]
thread[cmd](unpack(args)) thread[cmd](unpack(args))
end end
@ -1036,7 +1031,7 @@ end
function thread.sleep(n) function thread.sleep(n)
thread._Requests() thread._Requests()
thread.getRunningThread().lastSleep = clock() thread.getRunningThread().lastSleep = clock()
return coroutine.yield(CMD, t_sleep, n or 1) return yield(CMD, t_sleep, n or 1)
end end
function thread.hold(n,opt) function thread.hold(n,opt)
@ -1045,27 +1040,27 @@ function thread.hold(n,opt)
if type(opt)=="table" then if type(opt)=="table" then
interval = opt.interval interval = opt.interval
if opt.cycles then if opt.cycles then
return coroutine.yield(CMD, t_holdW, opt.cycles or 1, n or dFunc, interval) return yield(CMD, t_holdW, opt.cycles or 1, n or dFunc, interval)
elseif opt.sleep then elseif opt.sleep then
return coroutine.yield(CMD, t_holdF, opt.sleep, n or dFunc, interval) return yield(CMD, t_holdF, opt.sleep, n or dFunc, interval)
elseif opt.skip then elseif opt.skip then
return coroutine.yield(CMD, t_skip, opt.skip or 1, nil, interval) return yield(CMD, t_skip, opt.skip or 1, nil, interval)
end end
end end
if type(n) == "number" then if type(n) == "number" then
thread.getRunningThread().lastSleep = clock() thread.getRunningThread().lastSleep = clock()
return coroutine.yield(CMD, t_sleep, n or 0, nil, interval) return yield(CMD, t_sleep, n or 0, nil, interval)
elseif type(n) == "table" and n.Type == "connector" then elseif type(n) == "table" and n.Type == "connector" then
local ready = false local ready = false
n(function() n(function()
ready = true ready = true
end) end)
return coroutine.yield(CMD, t_hold, function() return yield(CMD, t_hold, function()
return ready return ready
end) end)
elseif type(n) == "function" then elseif type(n) == "function" then
return coroutine.yield(CMD, t_hold, n or dFunc, nil, interval) return yield(CMD, t_hold, n or dFunc, nil, interval)
else else
error("Invalid argument passed to thread.hold(...)!") error("Invalid argument passed to thread.hold(...)!")
end end
@ -1073,17 +1068,17 @@ end
function thread.holdFor(sec,n) function thread.holdFor(sec,n)
thread._Requests() thread._Requests()
return coroutine.yield(CMD, t_holdF, sec, n or dFunc) return yield(CMD, t_holdF, sec, n or dFunc)
end end
function thread.holdWithin(skip,n) function thread.holdWithin(skip,n)
thread._Requests() thread._Requests()
return coroutine.yield(CMD, t_holdW, skip or 1, n or dFunc) return yield(CMD, t_holdW, skip or 1, n or dFunc)
end end
function thread.skip(n) function thread.skip(n)
thread._Requests() thread._Requests()
return coroutine.yield(CMD, t_skip, n or 1) return yield(CMD, t_skip, n or 1)
end end
function thread.kill() function thread.kill()
@ -1092,15 +1087,15 @@ end
function thread.yield() function thread.yield()
thread._Requests() thread._Requests()
return coroutine.yield(CMD, t_yield) return yield(CMD, t_yield)
end end
function thread.isThread() function thread.isThread()
if _VERSION~="Lua 5.1" then if _VERSION~="Lua 5.1" then
local a,b = coroutine.running() local a,b = running()
return not(b) return not(b)
else else
return coroutine.running()~=nil return running()~=nil
end end
end end
@ -1224,7 +1219,7 @@ end
function thread:newFunction(func,holdme) function thread:newFunction(func,holdme)
return thread:newFunctionBase(function(...) return thread:newFunctionBase(function(...)
return multi.getCurrentProcess():newThread("TempThread",func,...) return thread:newThread("TempThread",func,...)
end,holdme)() end,holdme)()
end end
@ -1235,295 +1230,271 @@ function multi.setEnv(func,env)
return chunk return chunk
end end
function multi:attachScheduler() local threads = {}
local resume, status, create = coroutine.resume, coroutine.status, coroutine.create local startme = {}
local threads = {} local startme_len = 0
local startme = {} function thread:newThread(name,func,...)
local startme_len = 0 multi.OnLoad:Fire() -- This was done incase a threaded function was called before mainloop/uManager was called
function self:newThread(name,func,...) local func = func or name
self.OnLoad:Fire() -- This was done incase a threaded function was called before mainloop/uManager was called if type(name) == "function" then
local func = func or name name = "Thread#"..threadCount
if type(name) == "function" then end
name = "Thread#"..threadCount local c={nil,nil,nil,nil,nil,nil,nil}
end local env = {self=c}
local c={nil,nil,nil,nil,nil,nil,nil} c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
local env = {self=c} c.startArgs = {...}
c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil} c.ref={}
c.startArgs = {...} c.Name=name
c.ref={} c.thread=create(func)
c.Name=name c.sleep=1
c.thread=create(func) c.Type="thread"
c.sleep=1 c.TID = threadid
c.Type="thread" c.firstRunDone=false
c.TID = threadid c._isPaused = false
c.firstRunDone=false c.returns = {}
c._isPaused = false c.isError = false
c.returns = {} c.OnError = multi:newConnection(true,nil,true)
c.isError = false c.OnDeath = multi:newConnection(true,nil,true)
c.OnError = self:newConnection(true,nil,true)
c.OnDeath = self:newConnection(true,nil,true)
function c:isPaused() function c:isPaused()
return self._isPaused return self._isPaused
end end
local resumed = false local resumed = false
function c:Pause() function c:Pause()
if not self._isPaused then if not self._isPaused then
thread.request(self,"exec",function() thread.request(self,"exec",function()
thread.hold(function() thread.hold(function()
return resumed return resumed
end)
resumed = false
self._isPaused = false
end) end)
self._isPaused = true
end
return self
end
function c:Resume()
resumed = true
return self
end
function c:Kill()
thread.request(self,"kill")
return self
end
function c:Sleep(n)
thread.request(self,"exec",function()
thread.sleep(n)
resumed = false resumed = false
self._isPaused = false
end) end)
return self self._isPaused = true
end end
return self
function c:Hold(n,opt)
thread.request(self,"exec",function()
thread.hold(n,opt)
resumed = false
end)
return self
end
c.Destroy = c.Kill
table.insert(threads,c)
table.insert(startme,c)
startme_len = #startme
print("startme:",startme_len)
globalThreads[c] = self
if initT==false then
self.initThreads()
end
threadid = threadid + 1
multi:create(c)
c.creationTime = os.clock()
return c
end end
function self:newISOThread(name,func,_env,...) function c:Resume()
self.OnLoad:Fire() resumed = true
local func = func or name return self
local env = _env or {}
if not env.thread then
env.thread = thread
end
if not env.multi then
env.multi = self
end
if type(name) == "function" then
name = "Thread#"..threadCount
end
local func = isolateFunction(func,env)
return self:newThread(name,func)
end end
function self.initThreads(justThreads) function c:Kill()
initT = true thread.request(self,"kill")
self.scheduler=self:newLoop():setName("multi.thread") return self
self.scheduler.Type="scheduler" end
function self.scheduler:setStep(n)
self.skip=tonumber(n) or 24 function c:Sleep(n)
end thread.request(self,"exec",function()
self.scheduler.skip=0 thread.sleep(n)
local t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 resumed = false
local r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16
local ret,_
local task, thd, ref, ready
--[[
if coroutine.running() ~= threads[i].thread then
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(coreads[i].thread,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
CheckRets(i)
end
]]
-- ipart: t_hold, t_sleep, t_holdF, t_skip, t_holdW, t_yield, t_conn, t_none <-- Order
local switch = {
function(th,co)--hold
if clock() - th.intervalR>=th.interval then
t0,t1,t2,t3,t4,t5,t6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = th.func()
if t0 then
if t0==self.NIL then t0 = nil end
th.task = t_none
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
th.intervalR = clock()
end
end,
function(th,co)--sleep
if clock() - th.time>=th.sec then
th.task = t_none
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
end,
function(th,co)--holdf
if clock() - th.intervalR>=th.interval then
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = th.func()
if t0 then
if t0 then
if t0==self.NIL then t0 = nil end
th.task = t_none
end
th.task = t_none
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
elseif clock() - th.time>=th.sec then
th.task = t_none
t0 = nil
t1 = multi.TIMEOUT
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
th.intervalR = clock()
end
end,
function(th,co)--skip
th.pos = th.pos + 1
if th.count==th.pos then
th.task = t_none
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
end,
function(th,co)--holdw
if clock() - th.intervalR>=th.interval then
th.pos = th.pos + 1
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = th.func()
if t0 then
if t0 then
if t0==self.NIL then t0 = nil end
th.task = t_none
end
th.task = ""
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
elseif th.count==th.pos then
th.task = t_none
t0 = nil
t1 = multi.TIMEOUT
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
th.intervalR = clock()
end
end,
function(th,co)--yield
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end,
function() end--none
}
setmetatable(switch,{__index=function() return function() end end})
local cmds = {-- ipart: t_hold, t_sleep, t_holdF, t_skip, t_holdW, t_yield, t_none <-- Order
function(th,arg1,arg2,arg3)
--print("hold",arg1,arg2,arg3)
--print(_,ret,r1,r2,r3,r4,r5)
th.func = arg1
th.task = t_hold
th.interval = arg3 or 0
th.intervalR = clock()
end,
function(th,arg1,arg2,arg3)
--print("sleep",arg1,arg2,arg3)
th.sec = arg1
th.time = clock()
th.task = t_sleep
end,
function(th,arg1,arg2,arg3)
--print("holdf",arg1,arg2,arg3)
th.sec = arg1
th.func = arg2
th.task = t_holdF
th.time = clock()
th.interval = arg3 or 0
th.intervalR = clock()
end,
function(th,arg1,arg2,arg3)
--print("skip",arg1,arg2,arg3)
th.count = arg1
th.pos = 0
th.task = t_skip
end,
function(th,arg1,arg2,arg3)
--print("holdw",arg1,arg2,arg3)
th.count = arg1
th.pos = 0
th.func = arg2
th.task = t_holdW
th.time = clock()
th.interval = arg3 or 0
th.intervalR = clock()
end,
function() end
}
setmetatable(cmds,{__index=function() return function() end end})
local co_status = {
["suspended"] = function(thd,ref,task)
switch[task](ref,thd)
cmds[r1](ref,r2,r3,r4,r5)
r1=nil r2=nil r3=nil r4=nil r5=nil
end,
["normal"] = function(thd,ref) print("Normal Status") io.read() end, -- Not sure if I will handle this
["running"] = function(thd,ref) print("Running Status") io.read() end,
["dead"] = function(thd,ref,task,i)
if _ then
print("Death")
ref.OnDeath:Fire(ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16)
else
print("Error",ref,ret)
ref.OnError:Fire(ref,ret)
end
if i then
table.remove(threads,i)
else
for i,v in pairs(threads) do
if v.thread==thd then
table.remove(threads,i)
break
end
end
end
_=nil r1=nil r2=nil r3=nil r4=nil r5=nil
--self.setType(ref,self.DestroyedObj)
end,
}
self.scheduler:OnLoop(function(self)
for i=#threads,1,-1 do
-- First time setup for threads
for start = startme_len,1,-1 do
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = resume(startme[start].thread,unpack(startme[start].startArgs))
co_status[status(startme[startme_len].thread)](startme[startme_len].thread,startme[startme_len],t_none) --cmds[r1](startme[start],r2,r3,r4,r5)
startme[startme_len] = nil
startme_len = #startme
end
if threads[i] then
ref = threads[i]
task = ref.task
thd = ref.thread
ready = ref.__ready
co_status[status(thd)](thd,ref,task,i)
end
end
end) end)
return self
end end
function c:Hold(n,opt)
thread.request(self,"exec",function()
thread.hold(n,opt)
resumed = false
end)
return self
end
c.Destroy = c.Kill
table.insert(threads,c)
table.insert(startme,c)
startme_len = #startme
globalThreads[c] = multi
threadid = threadid + 1
multi:create(c)
c.creationTime = os.clock()
return c
end end
function thread:newISOThread(name,func,_env,...)
local func = func or name
local env = _env or {}
if not env.thread then
env.thread = thread
end
if not env.multi then
env.multi = multi
end
if type(name) == "function" then
name = "Thread#"..threadCount
end
local func = isolateFunction(func,env)
return thread:newThread(name,func)
end
multi.newThread = thread.newThread
multi.newISOThread = thread.newISOThread
local t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15
local r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16
local ret,_
local task, thd, ref, ready
local switch = {
function(th,co)--hold
if clock() - th.intervalR>=th.interval then
t0,t1,t2,t3,t4,t5,t6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = th.func()
if t0 then
if t0==NIL then t0 = nil end
th.task = t_none
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
th.intervalR = clock()
end
end,
function(th,co)--sleep
if clock() - th.time>=th.sec then
th.task = t_none
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
end,
function(th,co)--holdf
if clock() - th.intervalR>=th.interval then
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = th.func()
if t0 then
if t0 then
if t0==NIL then t0 = nil end
th.task = t_none
end
th.task = t_none
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
elseif clock() - th.time>=th.sec then
th.task = t_none
t0 = nil
t1 = multi.TIMEOUT
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
th.intervalR = clock()
end
end,
function(th,co)--skip
th.pos = th.pos + 1
if th.count==th.pos then
th.task = t_none
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
end,
function(th,co)--holdw
if clock() - th.intervalR>=th.interval then
th.pos = th.pos + 1
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = th.func()
if t0 then
if t0 then
if t0==NIL then t0 = nil end
th.task = t_none
end
th.task = ""
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
elseif th.count==th.pos then
th.task = t_none
t0 = nil
t1 = multi.TIMEOUT
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end
th.intervalR = clock()
end
end,
function(th,co)--yield
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=resume(co,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
end,
function() end--none
}
setmetatable(switch,{__index=function() return function() end end})
local cmds = {-- ipart: t_hold, t_sleep, t_holdF, t_skip, t_holdW, t_yield, t_none <-- Order
function(th,arg1,arg2,arg3)
th.func = arg1
th.task = t_hold
th.interval = arg3 or 0
th.intervalR = clock()
end,
function(th,arg1,arg2,arg3)
th.sec = arg1
th.time = clock()
th.task = t_sleep
end,
function(th,arg1,arg2,arg3)
th.sec = arg1
th.func = arg2
th.task = t_holdF
th.time = clock()
th.interval = arg3 or 0
th.intervalR = clock()
end,
function(th,arg1,arg2,arg3)
th.count = arg1
th.pos = 0
th.task = t_skip
end,
function(th,arg1,arg2,arg3)
th.count = arg1
th.pos = 0
th.func = arg2
th.task = t_holdW
th.time = clock()
th.interval = arg3 or 0
th.intervalR = clock()
end,
function() end
}
setmetatable(cmds,{__index=function() return function() end end})
local co_status = {
["suspended"] = function(thd,ref,task)
switch[task](ref,thd)
cmds[r1](ref,r2,r3,r4,r5)
r1=nil r2=nil r3=nil r4=nil r5=nil
end,
["normal"] = function(thd,ref) print("Normal Status") io.read() end, -- Not sure if I will handle this
["running"] = function(thd,ref) print("Running Status") io.read() end,
["dead"] = function(thd,ref,task,i)
if _ then
ref.OnDeath:Fire(ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16)
else
ref.OnError:Fire(ref,ret)
end
if i then
table.remove(threads,i)
else
for i,v in pairs(threads) do
if v.thread==thd then
table.remove(threads,i)
break
end
end
end
_=nil r1=nil r2=nil r3=nil r4=nil r5=nil
--self.setType(ref,self.DestroyedObj)
end,
}
local count = 0
local handler = coroutine.wrap(function(self)
while true do
for start = startme_len,1,-1 do
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = resume(startme[start].thread,unpack(startme[start].startArgs))
co_status[status(startme[startme_len].thread)](startme[startme_len].thread,startme[startme_len],t_none) -- Make sure there was no error
startme[startme_len] = nil
startme_len = #startme
yield()
end
for i=#threads,1,-1 do
if threads[i] then
ref = threads[i]
task = ref.task
thd = ref.thread
ready = ref.__ready
co_status[status(thd)](thd,ref,task,i)
end
yield()
end
end
end)
function multi:newService(func) -- Priority managed threads function multi:newService(func) -- Priority managed threads
local c = {} local c = {}
c.Type = "service" c.Type = "service"
@ -1553,7 +1524,7 @@ function multi:newService(func) -- Priority managed threads
task(ap) task(ap)
return c return c
end end
local th = self:newThread(function() local th = thread:newThread(function()
while true do while true do
process() process()
end end
@ -1636,6 +1607,7 @@ local function mainloop(self)
ctask:Act() ctask:Act()
__CurrentProcess = self __CurrentProcess = self
end end
handler()
end end
else else
return nil, "Already Running!" return nil, "Already Running!"
@ -1665,6 +1637,7 @@ local function p_mainloop(self)
end end
end end
end end
handler()
end end
else else
return nil, "Already Running!" return nil, "Already Running!"
@ -1693,6 +1666,7 @@ function multi:uManager()
multi.OnPreLoad:Fire() multi.OnPreLoad:Fire()
self.uManager=self.uManagerRef self.uManager=self.uManagerRef
multi.OnLoad:Fire() multi.OnLoad:Fire()
handler()
end end
end end
@ -1709,6 +1683,7 @@ function multi:uManagerRefP1()
end end
end end
end end
handler()
end end
end end
@ -1721,6 +1696,7 @@ function multi:uManagerRef()
__CurrentTask:Act() __CurrentTask:Act()
__CurrentProcess = self __CurrentProcess = self
end end
handler()
end end
end end
@ -2026,5 +2002,4 @@ else
multi.m.sentinel = newproxy(true) multi.m.sentinel = newproxy(true)
getmetatable(multi.m.sentinel).__gc = multi.m.onexit getmetatable(multi.m.sentinel).__gc = multi.m.onexit
end end
multi:attachScheduler()
return multi return multi

View File

@ -113,7 +113,7 @@ function multi:newSystemThreadedJobQueue(n)
end) end)
end,holup),name end,holup),name
end end
multi:newThread("JobQueueManager",function() thread:newthread("JobQueueManager",function()
while true do while true do
local job = thread.hold(function() local job = thread.hold(function()
return queueReturn:pop() return queueReturn:pop()
@ -129,7 +129,7 @@ function multi:newSystemThreadedJobQueue(n)
local clock = os.clock local clock = os.clock
local ref = 0 local ref = 0
setmetatable(_G,{__index = funcs}) setmetatable(_G,{__index = funcs})
multi:newThread("JobHandler",function() thread:newthread("JobHandler",function()
while true do while true do
local dat = thread.hold(function() local dat = thread.hold(function()
return queueJob:pop() return queueJob:pop()
@ -141,7 +141,7 @@ function multi:newSystemThreadedJobQueue(n)
queueReturn:push{jid, funcs[name](unpack(args)),queue} queueReturn:push{jid, funcs[name](unpack(args)),queue}
end end
end) end)
multi:newThread("DoAllHandler",function() thread:newthread("DoAllHandler",function()
while true do while true do
local dat = thread.hold(function() local dat = thread.hold(function()
return doAll:peek() return doAll:peek()
@ -156,7 +156,7 @@ function multi:newSystemThreadedJobQueue(n)
end end
end end
end) end)
multi:newThread("IdleHandler",function() thread:newthread("IdleHandler",function()
while true do while true do
thread.hold(function() thread.hold(function()
return clock()-idle>3 return clock()-idle>3

View File

@ -105,14 +105,11 @@ function multi.InitSystemThreadErrorHandler()
return return
end end
started = true started = true
multi:newThread("SystemThreadScheduler",function() thread:newthread("SystemThreadScheduler",function()
local threads = multi.SystemThreads local threads = multi.SystemThreads
while true do while true do
thread.sleep(.005) -- switching states often takes a huge hit on performance. half a second to tell me there is an error is good enough. thread.sleep(.005) -- switching states often takes a huge hit on performance. half a second to tell me there is an error is good enough.
local _,data = __ConsoleLinda:receive(0, "Q") local _,data = __ConsoleLinda:receive(0, "Q")
if data then
print(unpack(data))
end
for i = #threads, 1, -1 do for i = #threads, 1, -1 do
local status = threads[i].thread.status local status = threads[i].thread.status
local temp = threads[i] local temp = threads[i]
@ -147,8 +144,6 @@ function multi.InitSystemThreadErrorHandler()
end end
end end
end end
end).OnError(function(...)
print(...)
end) end)
end end

View File

@ -131,7 +131,7 @@ function multi:newSystemThreadedJobQueue(n)
end) end)
end,holup),name end,holup),name
end end
multi:newThread("jobManager",function() thread:newthread("jobManager",function()
while true do while true do
thread.yield() thread.yield()
local dat = c.queueReturn:pop() local dat = c.queueReturn:pop()
@ -155,7 +155,7 @@ function multi:newSystemThreadedJobQueue(n)
local queueAll = love.thread.getChannel("__JobQueue_"..jqc.."_queueAll") local queueAll = love.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
local registry = {} local registry = {}
setmetatable(_G,{__index = funcs}) setmetatable(_G,{__index = funcs})
multi:newThread("startUp",function() thread:newthread("startUp",function()
while true do while true do
thread.yield() thread.yield()
local all = queueAll:peek() local all = queueAll:peek()
@ -165,7 +165,7 @@ function multi:newSystemThreadedJobQueue(n)
end end
end end
end) end)
multi:newThread("runner",function() thread:newthread("runner",function()
thread.sleep(.1) thread.sleep(.1)
while true do while true do
thread.yield() thread.yield()
@ -187,7 +187,7 @@ function multi:newSystemThreadedJobQueue(n)
end):OnError(function(...) end):OnError(function(...)
error(...) error(...)
end) end)
multi:newThread("Idler",function() thread:newthread("Idler",function()
while true do while true do
thread.yield() thread.yield()
if clock()-lastProc> 2 then if clock()-lastProc> 2 then

View File

@ -122,7 +122,7 @@ function multi:newSystemThread(name,func,...)
GLOBAL["__THREAD_"..c.ID] = {ID=c.ID,Name=c.name,Thread=c.thread} GLOBAL["__THREAD_"..c.ID] = {ID=c.ID,Name=c.name,Thread=c.thread}
GLOBAL["__THREAD_COUNT"] = THREAD_ID GLOBAL["__THREAD_COUNT"] = THREAD_ID
THREAD_ID=THREAD_ID+1 THREAD_ID=THREAD_ID+1
multi:newThread(function() thread:newthread(function()
while true do while true do
thread.yield() thread.yield()
if c.stab["returns"] then if c.stab["returns"] then

View File

@ -167,7 +167,7 @@ if not ISTHREAD then
local clock = os.clock local clock = os.clock
local lastproc = clock() local lastproc = clock()
local queue = love.thread.getChannel("__CONSOLE__") local queue = love.thread.getChannel("__CONSOLE__")
multi:newThread("consoleManager",function() thread:newthread("consoleManager",function()
while true do while true do
thread.yield() thread.yield()
dat = queue:pop() dat = queue:pop()

View File

@ -129,7 +129,7 @@ function multi:newSystemThreadedJobQueue(n)
end) end)
end,holup),name end,holup),name
end end
multi:newThread("jobManager",function() thread:newthread("jobManager",function()
while true do while true do
thread.yield() thread.yield()
local dat = c.queueReturn:pop() local dat = c.queueReturn:pop()
@ -153,7 +153,7 @@ function multi:newSystemThreadedJobQueue(n)
local queueAll = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueAll") local queueAll = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
local registry = {} local registry = {}
setmetatable(_G,{__index = funcs}) setmetatable(_G,{__index = funcs})
multi:newThread("startUp",function() thread:newthread("startUp",function()
while true do while true do
thread.yield() thread.yield()
local all = queueAll:peek() local all = queueAll:peek()
@ -163,7 +163,7 @@ function multi:newSystemThreadedJobQueue(n)
end end
end end
end) end)
multi:newThread("runner",function() thread:newthread("runner",function()
thread.sleep(.1) thread.sleep(.1)
while true do while true do
thread.yield() thread.yield()
@ -185,7 +185,7 @@ function multi:newSystemThreadedJobQueue(n)
end):OnError(function(...) end):OnError(function(...)
error(...) error(...)
end) end)
multi:newThread("Idler",function() thread:newthread("Idler",function()
while true do while true do
thread.yield() thread.yield()
if clock()-lastProc> 2 then if clock()-lastProc> 2 then

View File

@ -168,7 +168,7 @@ if not ISTHREAD then
local clock = os.clock local clock = os.clock
local lastproc = clock() local lastproc = clock()
local queue = lovr.thread.getChannel("__CONSOLE__") local queue = lovr.thread.getChannel("__CONSOLE__")
multi:newThread("consoleManager",function() thread:newthread("consoleManager",function()
while true do while true do
thread.yield() thread.yield()
dat = queue:pop() dat = queue:pop()

View File

@ -72,7 +72,7 @@ function master:newNetworkThread(nodeName,func,...)
local ret local ret
local nID = netID local nID = netID
local conn = multi:newConnection() local conn = multi:newConnection()
multi:newThread(function() thread:newthread(function()
dat:addBlock{ dat:addBlock{
args = args, args = args,
func = func, func = func,
@ -143,7 +143,7 @@ function multi:newMasterNode(cd)
else else
c:getNodesFromBroadcast() c:getNodesFromBroadcast()
end end
multi:newThread("CMDQueueProcessor",function() thread:newthread("CMDQueueProcessor",function()
while true do while true do
thread.skip(128) thread.skip(128)
local data = table.remove(c._queue,1) local data = table.remove(c._queue,1)

View File

@ -125,7 +125,7 @@ function multi:newSystemThreadedJobQueue(n)
end,holup),name end,holup),name
end end
for i=1,c.cores do for i=1,c.cores do
multi:newThread("PesudoThreadedJobQueue_"..i,function() thread:newthread("PesudoThreadedJobQueue_"..i,function()
while true do while true do
thread.yield() thread.yield()
if #jobs>0 then if #jobs>0 then

View File

@ -70,7 +70,7 @@ function multi:newSystemThread(name,func,...)
env[tab[i]] = _G[tab[i]] env[tab[i]] = _G[tab[i]]
end end
--setmetatable(env,{__index=env}) --setmetatable(env,{__index=env})
multi:newISOThread(name,func,env,...).OnError(function(self,msg) thread:newISOThread(name,func,env,...).OnError(function(self,msg)
print("ERROR:",msg) print("ERROR:",msg)
end) end)
id = id + 1 id = id + 1

View File

@ -4,42 +4,20 @@ local multi,thread = require("multi"):init()
Before AVG: 522386 Before AVG: 522386
Test 1 AVG: Test 1 AVG:
]] ]]
local sleep_for = 5 local sleep_for = 1
local conn = multi:newConnection() local conn = multi:newConnection()
local test = {}
local function bench(_,steps) local function bench(_,steps)
print("Steps/5s: "..steps) print("Steps/1s: "..steps)
os.exit() os.exit()
end end
local ready = false for i = 1,400 do
multi:newAlarm(3):OnRing(function() thread:newThread(function()
conn:Fire() while true do
ready = true thread.sleep(.1)
end) end
multi:benchMark(sleep_for,multi.Priority_Core,"Core:"):OnBench(bench)
multi:newThread("Thread 1",function()
while true do
thread.sleep(1)
print("Test 1")
thread.hold(conn)
print("Conn sleep test")
error("hi")
end
end).OnError(print)
multi:newThread("Thread 2",function()
print("Thread 2")
return "it worked"
end):OnDeath(print):OnError(error)
multi:newThread("Thread 3",function()
thread.hold(function()
return ready
end) end)
print("Function test") end
return "Yay we did it" multi:benchMark(sleep_for,multi.Priority_Core,"Core:"):OnBench(bench)
end).OnDeath(print)
-- multi.OnExit(function()
-- print("Total: ".. a)
-- end)
multi:mainloop() multi:mainloop()