Changelog/Documentation updated. Processors added
This commit is contained in:
parent
8c24bcbbb0
commit
bdc657771d
@ -20,6 +20,34 @@ Current Multi Version: 15.0.0
|
|||||||
</br>`multi:threadloop([TABLE settings])` — This runs the mainloop by having its own internal while loop running, but prioritizes threads over multi-objects
|
</br>`multi:threadloop([TABLE settings])` — This runs the mainloop by having its own internal while loop running, but prioritizes threads over multi-objects
|
||||||
</br>`multi:uManager([TABLE settings])` — This runs the mainloop, but does not have its own while loop and thus needs to be within a loop of some kind.
|
</br>`multi:uManager([TABLE settings])` — This runs the mainloop, but does not have its own while loop and thus needs to be within a loop of some kind.
|
||||||
|
|
||||||
|
# Global Methods
|
||||||
|
|
||||||
|
`multi:init()` — Uesd to initiate the library, should only be called once
|
||||||
|
`multi.getCurrentProcess()` — Returns currently running Process
|
||||||
|
`multi.`
|
||||||
|
|
||||||
|
# Processor Methods
|
||||||
|
|
||||||
|
These methods can be called either on the multi namespace or a process returned by `multi:newProcessor()`
|
||||||
|
|
||||||
|
`proc.Stop()` — Stops the main process/child process. **Note:** If the main process is stopped all child processes are stopped as well
|
||||||
|
`proc:getTasksDetails([STRING: displaytype])` — Gets a table or string of all the running tasks
|
||||||
|
|
||||||
|
Processor Attributes
|
||||||
|
---
|
||||||
|
|
||||||
|
| Attribute | Type | Returns | Description |
|
||||||
|
---|---|---|---
|
||||||
|
Start|Method()|self| Starts the process
|
||||||
|
Stop|Method()|self| Stops the process
|
||||||
|
OnError|Connection|connection| Allows connection to the process error handler
|
||||||
|
Type|Member:`string`|"process"| Contains the type of object
|
||||||
|
Active|Member:`boolean`|variable| If false the process is not active
|
||||||
|
Name|Member:`string`|variable| The name set at process creation
|
||||||
|
process|Thread|thread| A handle to a multi thread object
|
||||||
|
|
||||||
|
[Refer to the objects for more methods](#non-actors)
|
||||||
|
|
||||||
# Multi Settings
|
# Multi Settings
|
||||||
|
|
||||||
**Note:** Most settings have been fined tuned to be at the peak of performance already, however preLoop, protect (Which drastically lowers preformance), and stopOnError should be used freely to fit your needs.
|
**Note:** Most settings have been fined tuned to be at the peak of performance already, however preLoop, protect (Which drastically lowers preformance), and stopOnError should be used freely to fit your needs.
|
||||||
|
|||||||
81
changes.md
81
changes.md
@ -28,11 +28,90 @@ multi:newThread("testing",function()
|
|||||||
end).OnError(function(...)
|
end).OnError(function(...)
|
||||||
print(...)
|
print(...)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
sandbox = multi:newProcessor()
|
||||||
|
sandbox:newTLoop(function()
|
||||||
|
print("testing...")
|
||||||
|
end,1)
|
||||||
|
|
||||||
|
test2 = multi:newTLoop(function()
|
||||||
|
print("testing2...")
|
||||||
|
end,1)
|
||||||
|
|
||||||
|
sandbox:newThread("Test Thread",function()
|
||||||
|
local a = 0
|
||||||
|
while true do
|
||||||
|
thread.sleep(1)
|
||||||
|
a = a + 1
|
||||||
|
print("Thread Test: ".. multi.getCurrentProcess().Name)
|
||||||
|
if a == 10 then
|
||||||
|
sandbox.Stop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end).OnError(function(...)
|
||||||
|
print(...)
|
||||||
|
end)
|
||||||
|
multi:newThread("Test Thread",function()
|
||||||
|
while true do
|
||||||
|
thread.sleep(1)
|
||||||
|
print("Thread Test: ".. multi.getCurrentProcess().Name)
|
||||||
|
end
|
||||||
|
end).OnError(function(...)
|
||||||
|
print(...)
|
||||||
|
end)
|
||||||
|
|
||||||
|
sandbox.Start()
|
||||||
|
|
||||||
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
Added:
|
Added:
|
||||||
---
|
---
|
||||||
- N/A
|
|
||||||
|
## multi:newProcessor(name)
|
||||||
|
|
||||||
|
```lua
|
||||||
|
package.path = "./?/init.lua;"..package.path
|
||||||
|
multi,thread = require("multi"):init()
|
||||||
|
|
||||||
|
sandbox = multi:newProcessor()
|
||||||
|
|
||||||
|
sandbox:newTLoop(function()
|
||||||
|
print("testing...")
|
||||||
|
end,1)
|
||||||
|
|
||||||
|
sandbox:newThread("Test Thread",function()
|
||||||
|
local a = 0
|
||||||
|
while true do
|
||||||
|
thread.sleep(1)
|
||||||
|
a = a + 1
|
||||||
|
print("Thread Test: ".. multi.getCurrentProcess().Name)
|
||||||
|
if a == 10 then
|
||||||
|
sandbox.Stop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end).OnError(function(...)
|
||||||
|
print(...)
|
||||||
|
end)
|
||||||
|
|
||||||
|
sandbox.Start() -- Start the process
|
||||||
|
|
||||||
|
multi:mainloop()
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Returns | Description |
|
||||||
|
---|---|---|---
|
||||||
|
Start|Method()|self| Starts the process
|
||||||
|
Stop|Method()|self| Stops the process
|
||||||
|
OnError|Connection|connection| Allows connection to the process error handler
|
||||||
|
Type|Member:`string`|"process"| Contains the type of object
|
||||||
|
Active|Member:`boolean`|variable| If false the process is not active
|
||||||
|
Name|Member:`string`|variable| The name set at process creation
|
||||||
|
process|Thread|thread| A handle to a multi thread object
|
||||||
|
|
||||||
|
**Note:** All tasks/threads created on a process are linked to that process. If a process is stopped all tasks/threads will be halted until the process is started back up.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Changed:
|
Changed:
|
||||||
---
|
---
|
||||||
|
|||||||
681
multi/init.lua
681
multi/init.lua
@ -120,7 +120,7 @@ function multi:getTasksDetails(t)
|
|||||||
dat2 = dat2.."<SystemThread: "..multi.SystemThreads[i].Name.." | "..os.clock()-multi.SystemThreads[i].creationTime..">\n"
|
dat2 = dat2.."<SystemThread: "..multi.SystemThreads[i].Name.." | "..os.clock()-multi.SystemThreads[i].creationTime..">\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local load, steps = multi:getLoad()
|
local load, steps = self:getLoad()
|
||||||
if thread.__threads then
|
if thread.__threads then
|
||||||
for i=1,#thread.__threads do
|
for i=1,#thread.__threads do
|
||||||
dat = dat .. "<THREAD: "..thread.__threads[i].Name.." | "..os.clock()-thread.__threads[i].creationTime..">\n"
|
dat = dat .. "<THREAD: "..thread.__threads[i].Name.." | "..os.clock()-thread.__threads[i].creationTime..">\n"
|
||||||
@ -130,7 +130,7 @@ function multi:getTasksDetails(t)
|
|||||||
return "Load on "..ProcessName[self.Type=="process"].."<"..(self.Name or "Unnamed")..">"..": "..multi.Round(load,2).."%\nCycles Per Second Per Task: "..steps.."\n\nMemory Usage: "..math.ceil(collectgarbage("count")).." KB\nThreads Running: 0\nPriority Scheme: "..priorityTable[multi.defaultSettings.priority or 0].."\n\n"..s..dat2
|
return "Load on "..ProcessName[self.Type=="process"].."<"..(self.Name or "Unnamed")..">"..": "..multi.Round(load,2).."%\nCycles Per Second Per Task: "..steps.."\n\nMemory Usage: "..math.ceil(collectgarbage("count")).." KB\nThreads Running: 0\nPriority Scheme: "..priorityTable[multi.defaultSettings.priority or 0].."\n\n"..s..dat2
|
||||||
end
|
end
|
||||||
elseif t == "t" or t == "table" then
|
elseif t == "t" or t == "table" then
|
||||||
local load,steps = multi:getLoad()
|
local load,steps = self:getLoad()
|
||||||
str = {
|
str = {
|
||||||
ProcessName = (self.Name or "Unnamed"),
|
ProcessName = (self.Name or "Unnamed"),
|
||||||
ThreadCount = #thread.__threads,
|
ThreadCount = #thread.__threads,
|
||||||
@ -206,9 +206,9 @@ end
|
|||||||
-- Advance Timer stuff
|
-- Advance Timer stuff
|
||||||
function multi:SetTime(n)
|
function multi:SetTime(n)
|
||||||
if not n then n=3 end
|
if not n then n=3 end
|
||||||
local c=multi:newBase()
|
local c=self:newBase()
|
||||||
c.Type='timemaster'
|
c.Type='timemaster'
|
||||||
c.timer=multi:newTimer()
|
c.timer=self:newTimer()
|
||||||
c.timer:Start()
|
c.timer:Start()
|
||||||
c.set=n
|
c.set=n
|
||||||
c.link=self
|
c.link=self
|
||||||
@ -552,7 +552,7 @@ function multi:newTimer()
|
|||||||
time=os.clock()-time
|
time=os.clock()-time
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -580,7 +580,7 @@ function multi:newEvent(task)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
self:setPriority("core")
|
self:setPriority("core")
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newUpdater(skip)
|
function multi:newUpdater(skip)
|
||||||
@ -602,7 +602,7 @@ function multi:newUpdater(skip)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
c.OnUpdate=self.OnMainConnect
|
c.OnUpdate=self.OnMainConnect
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newAlarm(set)
|
function multi:newAlarm(set)
|
||||||
@ -642,7 +642,7 @@ function multi:newAlarm(set)
|
|||||||
self.Parent.Pause(self)
|
self.Parent.Pause(self)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newLoop(func)
|
function multi:newLoop(func)
|
||||||
@ -662,7 +662,7 @@ function multi:newLoop(func)
|
|||||||
table.insert(funcs,func)
|
table.insert(funcs,func)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newFunction(func)
|
function multi:newFunction(func)
|
||||||
@ -688,7 +688,7 @@ function multi:newFunction(func)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
setmetatable(c,mt)
|
setmetatable(c,mt)
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newStep(start,reset,count,skip)
|
function multi:newStep(start,reset,count,skip)
|
||||||
@ -759,7 +759,7 @@ function multi:newStep(start,reset,count,skip)
|
|||||||
self:Resume()
|
self:Resume()
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newTLoop(func,set)
|
function multi:newTLoop(func,set)
|
||||||
@ -795,7 +795,7 @@ function multi:newTLoop(func,set)
|
|||||||
table.insert(self.func,func)
|
table.insert(self.func,func)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:setTimeout(func,t)
|
function multi:setTimeout(func,t)
|
||||||
@ -869,7 +869,7 @@ function multi:newTStep(start,reset,count,set)
|
|||||||
self:Resume()
|
self:Resume()
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
self:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
local scheduledjobs = {}
|
local scheduledjobs = {}
|
||||||
@ -902,6 +902,48 @@ function multi:scheduleJob(time,func)
|
|||||||
table.insert(scheduledjobs,{time, func,false})
|
table.insert(scheduledjobs,{time, func,false})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local __CurrentProcess = multi
|
||||||
|
function multi.getCurrentProcess()
|
||||||
|
return __CurrentProcess
|
||||||
|
end
|
||||||
|
|
||||||
|
local globalThreads = {}
|
||||||
|
|
||||||
|
local sandcount = 0
|
||||||
|
function multi:newProcessor(name)
|
||||||
|
local c = {}
|
||||||
|
setmetatable(c,{__index = self})
|
||||||
|
local multi,thread = require("multi"):init() -- We need to capture the t in thread
|
||||||
|
local name = name or "Processor_"..sandcount
|
||||||
|
sandcount = sandcount + 1
|
||||||
|
c.Mainloop = {}
|
||||||
|
c.Type = "process"
|
||||||
|
c.Active = false
|
||||||
|
c.Name = "multi.process<".. (name or "") .. ">"
|
||||||
|
c.process = self:newThread(c.Name,function()
|
||||||
|
while true do
|
||||||
|
thread.hold(function()
|
||||||
|
return c.Active
|
||||||
|
end)
|
||||||
|
__CurrentProcess = c
|
||||||
|
c:uManager()
|
||||||
|
__CurrentProcess = self
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
c.OnError = c.process.OnError
|
||||||
|
function c.Start()
|
||||||
|
c.Active = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
function c.Stop()
|
||||||
|
c.Active = false
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
c:attachScheduler()
|
||||||
|
c.initThreads()
|
||||||
|
return c
|
||||||
|
end
|
||||||
|
|
||||||
-- Threading stuff
|
-- Threading stuff
|
||||||
local initT = false
|
local initT = false
|
||||||
local threadCount = 0
|
local threadCount = 0
|
||||||
@ -917,6 +959,7 @@ function thread.request(t,cmd,...)
|
|||||||
thread.requests[t.thread] = {cmd,{...}}
|
thread.requests[t.thread] = {cmd,{...}}
|
||||||
end
|
end
|
||||||
function thread.getRunningThread()
|
function thread.getRunningThread()
|
||||||
|
local threads = globalThreads
|
||||||
local t = coroutine.running()
|
local t = coroutine.running()
|
||||||
if t then
|
if t then
|
||||||
for i,v in pairs(threads) do
|
for i,v in pairs(threads) do
|
||||||
@ -1036,7 +1079,7 @@ function multi.hold(func,no)
|
|||||||
end
|
end
|
||||||
local death = false
|
local death = false
|
||||||
if type(func)=="number" then
|
if type(func)=="number" then
|
||||||
multi:newThread("Hold_func",function()
|
self:newThread("Hold_func",function()
|
||||||
thread.sleep(func)
|
thread.sleep(func)
|
||||||
death = true
|
death = true
|
||||||
end)
|
end)
|
||||||
@ -1045,7 +1088,7 @@ function multi.hold(func,no)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
local rets
|
local rets
|
||||||
multi:newThread("Hold_func",function()
|
self:newThread("Hold_func",function()
|
||||||
rets = {thread.hold(func)}
|
rets = {thread.hold(func)}
|
||||||
death = true
|
death = true
|
||||||
end)
|
end)
|
||||||
@ -1057,11 +1100,11 @@ function multi.hold(func,no)
|
|||||||
end
|
end
|
||||||
function multi.holdFor(n,func)
|
function multi.holdFor(n,func)
|
||||||
local temp
|
local temp
|
||||||
multi:newThread(function()
|
multi.getCurrentProcess():newThread(function()
|
||||||
thread.sleep(n)
|
thread.sleep(n)
|
||||||
temp = true
|
temp = true
|
||||||
end)
|
end)
|
||||||
return multi.hold(function()
|
return multi.getCurrentProcess().hold(function()
|
||||||
if func() then
|
if func() then
|
||||||
return func()
|
return func()
|
||||||
elseif temp then
|
elseif temp then
|
||||||
@ -1103,7 +1146,7 @@ function thread:newFunction(func,holdme)
|
|||||||
return cleanReturns(rets[1],rets[2],rets[3],rets[4],rets[5],rets[6],rets[7],rets[8],rets[9],rets[10],rets[11],rets[12],rets[13],rets[14],rets[15],rets[16])
|
return cleanReturns(rets[1],rets[2],rets[3],rets[4],rets[5],rets[6],rets[7],rets[8],rets[9],rets[10],rets[11],rets[12],rets[13],rets[14],rets[15],rets[16])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local t = multi:newThread("TempThread",func,...)
|
local t = multi.getCurrentProcess():newThread("TempThread",func,...)
|
||||||
t.OnDeath(function(self,status,...) rets = {...} end)
|
t.OnDeath(function(self,status,...) rets = {...} end)
|
||||||
t.OnError(function(self,e) err = e end)
|
t.OnError(function(self,e) err = e end)
|
||||||
if holdme then
|
if holdme then
|
||||||
@ -1127,308 +1170,313 @@ function multi.setEnv(func,env)
|
|||||||
return chunk
|
return chunk
|
||||||
end
|
end
|
||||||
|
|
||||||
function multi:newThread(name,func,...)
|
function multi:attachScheduler()
|
||||||
multi.OnLoad:Fire()
|
local threads = {}
|
||||||
local func = func or name
|
self.threadsRef = threads
|
||||||
if type(name) == "function" then
|
function self:newThread(name,func,...)
|
||||||
name = "Thread#"..threadCount
|
self.OnLoad:Fire()
|
||||||
end
|
local func = func or name
|
||||||
local c={}
|
if type(name) == "function" then
|
||||||
local env = {self=c}
|
name = "Thread#"..threadCount
|
||||||
c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
end
|
||||||
c.startArgs = {...}
|
local c={}
|
||||||
c.ref={}
|
local env = {self=c}
|
||||||
c.Name=name
|
c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
||||||
c.thread=coroutine.create(func)
|
c.startArgs = {...}
|
||||||
c.sleep=1
|
c.ref={}
|
||||||
c.Type="thread"
|
c.Name=name
|
||||||
c.TID = threadid
|
c.thread=coroutine.create(func)
|
||||||
c.firstRunDone=false
|
c.sleep=1
|
||||||
c.timer=multi:newTimer()
|
c.Type="thread"
|
||||||
c._isPaused = false
|
c.TID = threadid
|
||||||
c.returns = {}
|
c.firstRunDone=false
|
||||||
c.isError = false
|
c.timer=self:newTimer()
|
||||||
c.OnError = multi:newConnection(true,nil,true)
|
c._isPaused = false
|
||||||
c.OnDeath = multi:newConnection(true,nil,true)
|
c.returns = {}
|
||||||
function c:isPaused()
|
c.isError = false
|
||||||
return self._isPaused
|
c.OnError = self:newConnection(true,nil,true)
|
||||||
end
|
c.OnDeath = self:newConnection(true,nil,true)
|
||||||
local resumed = false
|
function c:isPaused()
|
||||||
function c:Pause()
|
return self._isPaused
|
||||||
if not self._isPaused then
|
end
|
||||||
thread.request(self,"exec",function()
|
local resumed = false
|
||||||
thread.hold(function()
|
function c:Pause()
|
||||||
return resumed
|
if not self._isPaused then
|
||||||
|
thread.request(self,"exec",function()
|
||||||
|
thread.hold(function()
|
||||||
|
return resumed
|
||||||
|
end)
|
||||||
|
resumed = false
|
||||||
|
self._isPaused = false
|
||||||
end)
|
end)
|
||||||
resumed = false
|
self._isPaused = true
|
||||||
self._isPaused = false
|
|
||||||
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
|
|
||||||
c.Destroy = c.Kill
|
|
||||||
function c.ref:send(name,val)
|
|
||||||
ret=coroutine.yield({Name=name,Value=val})
|
|
||||||
end
|
|
||||||
function c.ref:get(name)
|
|
||||||
return self.Globals[name]
|
|
||||||
end
|
|
||||||
function c.ref:kill()
|
|
||||||
dRef[1] = "_kill_"
|
|
||||||
dRef[2] = "I Was killed by You!"
|
|
||||||
err = coroutine.yield(dRef)
|
|
||||||
if err then
|
|
||||||
error("Failed to kill a thread! Exiting...")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function c.ref:sleep(n)
|
|
||||||
if type(n)=="function" then
|
|
||||||
ret=thread.hold(n)
|
|
||||||
elseif type(n)=="number" then
|
|
||||||
ret=thread.sleep(tonumber(n) or 0)
|
|
||||||
else
|
|
||||||
error("Invalid Type for sleep!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function c.ref:syncGlobals(v)
|
|
||||||
self.Globals=v
|
|
||||||
end
|
|
||||||
table.insert(threads,c)
|
|
||||||
if initT==false then
|
|
||||||
multi.initThreads()
|
|
||||||
end
|
|
||||||
c.creationTime = os.clock()
|
|
||||||
threadid = threadid + 1
|
|
||||||
self:create(c)
|
|
||||||
return c
|
|
||||||
end
|
|
||||||
function multi:newISOThread(name,func,_env,...)
|
|
||||||
multi.OnLoad:Fire()
|
|
||||||
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 self:newThread(name,func)
|
|
||||||
end
|
|
||||||
function multi.initThreads(justThreads)
|
|
||||||
initT = true
|
|
||||||
multi.scheduler=multi:newLoop():setName("multi.thread")
|
|
||||||
multi.scheduler.Type="scheduler"
|
|
||||||
function multi.scheduler:setStep(n)
|
|
||||||
self.skip=tonumber(n) or 24
|
|
||||||
end
|
|
||||||
multi.scheduler.skip=0
|
|
||||||
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 function CheckRets(i)
|
|
||||||
if threads[i] and not(threads[i].isError) then
|
|
||||||
if not _ then
|
|
||||||
threads[i].isError = true
|
|
||||||
threads[i].TempRets[1] = ret
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
if ret or r1 or r2 or r3 or r4 or r5 or r6 or r7 or r8 or r9 or r10 or r11 or r12 or r13 or r14 or r15 or r16 then
|
return self
|
||||||
threads[i].TempRets[1] = ret
|
end
|
||||||
threads[i].TempRets[2] = r1
|
function c:Resume()
|
||||||
threads[i].TempRets[3] = r2
|
resumed = true
|
||||||
threads[i].TempRets[4] = r3
|
return self
|
||||||
threads[i].TempRets[5] = r4
|
end
|
||||||
threads[i].TempRets[6] = r5
|
function c:Kill()
|
||||||
threads[i].TempRets[7] = r6
|
thread.request(self,"kill")
|
||||||
threads[i].TempRets[8] = r7
|
return self
|
||||||
threads[i].TempRets[9] = r8
|
end
|
||||||
threads[i].TempRets[10] = r9
|
c.Destroy = c.Kill
|
||||||
threads[i].TempRets[11] = r10
|
function c.ref:send(name,val)
|
||||||
threads[i].TempRets[12] = r11
|
ret=coroutine.yield({Name=name,Value=val})
|
||||||
threads[i].TempRets[13] = r12
|
end
|
||||||
threads[i].TempRets[14] = r13
|
function c.ref:get(name)
|
||||||
threads[i].TempRets[15] = r14
|
return self.Globals[name]
|
||||||
threads[i].TempRets[16] = r15
|
end
|
||||||
threads[i].TempRets[17] = r16
|
function c.ref:kill()
|
||||||
|
dRef[1] = "_kill_"
|
||||||
|
dRef[2] = "I Was killed by You!"
|
||||||
|
err = coroutine.yield(dRef)
|
||||||
|
if err then
|
||||||
|
error("Failed to kill a thread! Exiting...")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function c.ref:sleep(n)
|
||||||
|
if type(n)=="function" then
|
||||||
|
ret=thread.hold(n)
|
||||||
|
elseif type(n)=="number" then
|
||||||
|
ret=thread.sleep(tonumber(n) or 0)
|
||||||
|
else
|
||||||
|
error("Invalid Type for sleep!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function c.ref:syncGlobals(v)
|
||||||
|
self.Globals=v
|
||||||
|
end
|
||||||
|
table.insert(threads,c)
|
||||||
|
table.insert(globalThreads,c)
|
||||||
|
if initT==false then
|
||||||
|
self.initThreads()
|
||||||
|
end
|
||||||
|
c.creationTime = os.clock()
|
||||||
|
threadid = threadid + 1
|
||||||
|
multi:create(c)
|
||||||
|
return c
|
||||||
end
|
end
|
||||||
local function holdconn(n)
|
function self:newISOThread(name,func,_env,...)
|
||||||
if type(ret[n])=="table" and ret[n].Type=='connector' then
|
self.OnLoad:Fire()
|
||||||
local letsgo
|
local func = func or name
|
||||||
ret[n](function(...) letsgo = {...} end)
|
local env = _env or {}
|
||||||
ret[n] = function()
|
if not env.thread then
|
||||||
if letsgo then
|
env.thread = thread
|
||||||
return unpack(letsgo)
|
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
|
||||||
|
function self.initThreads(justThreads)
|
||||||
|
initT = true
|
||||||
|
self.scheduler=self:newLoop():setName("multi.thread")
|
||||||
|
self.scheduler.Type="scheduler"
|
||||||
|
function self.scheduler:setStep(n)
|
||||||
|
self.skip=tonumber(n) or 24
|
||||||
|
end
|
||||||
|
self.scheduler.skip=0
|
||||||
|
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 function CheckRets(i)
|
||||||
|
if threads[i] and not(threads[i].isError) then
|
||||||
|
if not _ then
|
||||||
|
threads[i].isError = true
|
||||||
|
threads[i].TempRets[1] = ret
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if ret or r1 or r2 or r3 or r4 or r5 or r6 or r7 or r8 or r9 or r10 or r11 or r12 or r13 or r14 or r15 or r16 then
|
||||||
|
threads[i].TempRets[1] = ret
|
||||||
|
threads[i].TempRets[2] = r1
|
||||||
|
threads[i].TempRets[3] = r2
|
||||||
|
threads[i].TempRets[4] = r3
|
||||||
|
threads[i].TempRets[5] = r4
|
||||||
|
threads[i].TempRets[6] = r5
|
||||||
|
threads[i].TempRets[7] = r6
|
||||||
|
threads[i].TempRets[8] = r7
|
||||||
|
threads[i].TempRets[9] = r8
|
||||||
|
threads[i].TempRets[10] = r9
|
||||||
|
threads[i].TempRets[11] = r10
|
||||||
|
threads[i].TempRets[12] = r11
|
||||||
|
threads[i].TempRets[13] = r12
|
||||||
|
threads[i].TempRets[14] = r13
|
||||||
|
threads[i].TempRets[15] = r14
|
||||||
|
threads[i].TempRets[16] = r15
|
||||||
|
threads[i].TempRets[17] = r16
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
local function holdconn(n)
|
||||||
local function helper(i)
|
if type(ret[n])=="table" and ret[n].Type=='connector' then
|
||||||
if type(ret)=="table" then
|
local letsgo
|
||||||
if ret[1]=="_kill_" then
|
ret[n](function(...) letsgo = {...} end)
|
||||||
threads[i].OnDeath:Fire(threads[i],"killed",ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16)
|
ret[n] = function()
|
||||||
multi.setType(threads[i],multi.DestroyedObj)
|
if letsgo then
|
||||||
table.remove(threads,i)
|
return unpack(letsgo)
|
||||||
ret = nil
|
end
|
||||||
elseif ret[1]=="_sleep_" then
|
end
|
||||||
threads[i].sec = ret[2]
|
|
||||||
threads[i].time = clock()
|
|
||||||
threads[i].task = "sleep"
|
|
||||||
threads[i].__ready = false
|
|
||||||
ret = nil
|
|
||||||
elseif ret[1]=="_skip_" then
|
|
||||||
threads[i].count = ret[2]
|
|
||||||
threads[i].pos = 0
|
|
||||||
threads[i].task = "skip"
|
|
||||||
threads[i].__ready = false
|
|
||||||
ret = nil
|
|
||||||
elseif ret[1]=="_hold_" then
|
|
||||||
holdconn(2)
|
|
||||||
threads[i].func = ret[2]
|
|
||||||
threads[i].task = "hold"
|
|
||||||
threads[i].__ready = false
|
|
||||||
threads[i].interval = ret[4] or 0
|
|
||||||
threads[i].intervalR = clock()
|
|
||||||
ret = nil
|
|
||||||
elseif ret[1]=="_holdF_" then
|
|
||||||
holdconn(3)
|
|
||||||
threads[i].sec = ret[2]
|
|
||||||
threads[i].func = ret[3]
|
|
||||||
threads[i].task = "holdF"
|
|
||||||
threads[i].time = clock()
|
|
||||||
threads[i].__ready = false
|
|
||||||
threads[i].interval = ret[4] or 0
|
|
||||||
threads[i].intervalR = clock()
|
|
||||||
ret = nil
|
|
||||||
elseif ret[1]=="_holdW_" then
|
|
||||||
holdconn(3)
|
|
||||||
threads[i].count = ret[2]
|
|
||||||
threads[i].pos = 0
|
|
||||||
threads[i].func = ret[3]
|
|
||||||
threads[i].task = "holdW"
|
|
||||||
threads[i].time = clock()
|
|
||||||
threads[i].__ready = false
|
|
||||||
threads[i].interval = ret[4] or 0
|
|
||||||
threads[i].intervalR = clock()
|
|
||||||
ret = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
CheckRets(i)
|
local function helper(i)
|
||||||
end
|
if type(ret)=="table" then
|
||||||
multi.scheduler:OnLoop(function(self)
|
if ret[1]=="_kill_" then
|
||||||
for i=#threads,1,-1 do
|
threads[i].OnDeath:Fire(threads[i],"killed",ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16)
|
||||||
if threads[i].isError then
|
self.setType(threads[i],self.DestroyedObj)
|
||||||
if coroutine.status(threads[i].thread)=="dead" then
|
|
||||||
threads[i].OnError:Fire(threads[i],unpack(threads[i].TempRets))
|
|
||||||
multi.setType(threads[i],multi.DestroyedObj)
|
|
||||||
table.remove(threads,i)
|
table.remove(threads,i)
|
||||||
|
ret = nil
|
||||||
|
elseif ret[1]=="_sleep_" then
|
||||||
|
threads[i].sec = ret[2]
|
||||||
|
threads[i].time = clock()
|
||||||
|
threads[i].task = "sleep"
|
||||||
|
threads[i].__ready = false
|
||||||
|
ret = nil
|
||||||
|
elseif ret[1]=="_skip_" then
|
||||||
|
threads[i].count = ret[2]
|
||||||
|
threads[i].pos = 0
|
||||||
|
threads[i].task = "skip"
|
||||||
|
threads[i].__ready = false
|
||||||
|
ret = nil
|
||||||
|
elseif ret[1]=="_hold_" then
|
||||||
|
holdconn(2)
|
||||||
|
threads[i].func = ret[2]
|
||||||
|
threads[i].task = "hold"
|
||||||
|
threads[i].__ready = false
|
||||||
|
threads[i].interval = ret[4] or 0
|
||||||
|
threads[i].intervalR = clock()
|
||||||
|
ret = nil
|
||||||
|
elseif ret[1]=="_holdF_" then
|
||||||
|
holdconn(3)
|
||||||
|
threads[i].sec = ret[2]
|
||||||
|
threads[i].func = ret[3]
|
||||||
|
threads[i].task = "holdF"
|
||||||
|
threads[i].time = clock()
|
||||||
|
threads[i].__ready = false
|
||||||
|
threads[i].interval = ret[4] or 0
|
||||||
|
threads[i].intervalR = clock()
|
||||||
|
ret = nil
|
||||||
|
elseif ret[1]=="_holdW_" then
|
||||||
|
holdconn(3)
|
||||||
|
threads[i].count = ret[2]
|
||||||
|
threads[i].pos = 0
|
||||||
|
threads[i].func = ret[3]
|
||||||
|
threads[i].task = "holdW"
|
||||||
|
threads[i].time = clock()
|
||||||
|
threads[i].__ready = false
|
||||||
|
threads[i].interval = ret[4] or 0
|
||||||
|
threads[i].intervalR = clock()
|
||||||
|
ret = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if threads[i] and not threads[i].__started then
|
CheckRets(i)
|
||||||
if coroutine.running() ~= threads[i].thread then
|
end
|
||||||
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=coroutine.resume(threads[i].thread,unpack(threads[i].startArgs))
|
self.scheduler:OnLoop(function(self)
|
||||||
|
for i=#threads,1,-1 do
|
||||||
|
if threads[i].isError then
|
||||||
|
if coroutine.status(threads[i].thread)=="dead" then
|
||||||
|
threads[i].OnError:Fire(threads[i],unpack(threads[i].TempRets))
|
||||||
|
self.setType(threads[i],self.DestroyedObj)
|
||||||
|
table.remove(threads,i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if threads[i] and not threads[i].__started then
|
||||||
|
if coroutine.running() ~= threads[i].thread then
|
||||||
|
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=coroutine.resume(threads[i].thread,unpack(threads[i].startArgs))
|
||||||
|
end
|
||||||
|
threads[i].__started = true
|
||||||
|
helper(i)
|
||||||
|
end
|
||||||
|
if threads[i] and not _ then
|
||||||
|
threads[i].OnError:Fire(threads[i],unpack(threads[i].TempRets))
|
||||||
|
threads[i].isError = true
|
||||||
|
end
|
||||||
|
if threads[i] and coroutine.status(threads[i].thread)=="dead" then
|
||||||
|
local t = threads[i].TempRets or {}
|
||||||
|
threads[i].OnDeath:Fire(threads[i],"ended",t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15],t[16])
|
||||||
|
self.setType(threads[i],self.DestroyedObj)
|
||||||
|
table.remove(threads,i)
|
||||||
|
elseif threads[i] and threads[i].task == "skip" then
|
||||||
|
threads[i].pos = threads[i].pos + 1
|
||||||
|
if threads[i].count==threads[i].pos then
|
||||||
|
threads[i].task = ""
|
||||||
|
threads[i].__ready = true
|
||||||
|
end
|
||||||
|
elseif threads[i] and threads[i].task == "hold" then
|
||||||
|
if clock() - threads[i].intervalR>=threads[i].interval then
|
||||||
|
t0,t1,t2,t3,t4,t5,t6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = threads[i].func()
|
||||||
|
if t0 then
|
||||||
|
if t0==self.NIL then
|
||||||
|
t0 = nil
|
||||||
|
end
|
||||||
|
threads[i].task = ""
|
||||||
|
threads[i].__ready = true
|
||||||
|
end
|
||||||
|
threads[i].intervalR = clock()
|
||||||
|
end
|
||||||
|
elseif threads[i] and threads[i].task == "sleep" then
|
||||||
|
if clock() - threads[i].time>=threads[i].sec then
|
||||||
|
threads[i].task = ""
|
||||||
|
threads[i].__ready = true
|
||||||
|
end
|
||||||
|
elseif threads[i] and threads[i].task == "holdF" then
|
||||||
|
if clock() - threads[i].intervalR>=threads[i].interval then
|
||||||
|
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = threads[i].func()
|
||||||
|
if t0 then
|
||||||
|
threads[i].task = ""
|
||||||
|
threads[i].__ready = true
|
||||||
|
elseif clock() - threads[i].time>=threads[i].sec then
|
||||||
|
threads[i].task = ""
|
||||||
|
threads[i].__ready = true
|
||||||
|
t0 = nil
|
||||||
|
t1 = "TIMEOUT"
|
||||||
|
end
|
||||||
|
threads[i].intervalR = clock()
|
||||||
|
end
|
||||||
|
elseif threads[i] and threads[i].task == "holdW" then
|
||||||
|
if clock() - threads[i].intervalR>=threads[i].interval then
|
||||||
|
threads[i].pos = threads[i].pos + 1
|
||||||
|
print(threads[i].pos,threads[i].count)
|
||||||
|
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = threads[i].func()
|
||||||
|
if t0 then
|
||||||
|
threads[i].task = ""
|
||||||
|
threads[i].__ready = true
|
||||||
|
elseif threads[i].count==threads[i].pos then
|
||||||
|
threads[i].task = ""
|
||||||
|
threads[i].__ready = true
|
||||||
|
t0 = nil
|
||||||
|
t1 = "TIMEOUT"
|
||||||
|
end
|
||||||
|
threads[i].intervalR = clock()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if threads[i] and threads[i].__ready then
|
||||||
|
threads[i].__ready = false
|
||||||
|
if coroutine.running() ~= threads[i].thread then
|
||||||
|
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=coroutine.resume(threads[i].thread,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
|
||||||
|
CheckRets(i)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
threads[i].__started = true
|
|
||||||
helper(i)
|
helper(i)
|
||||||
end
|
end
|
||||||
if threads[i] and not _ then
|
end)
|
||||||
threads[i].OnError:Fire(threads[i],unpack(threads[i].TempRets))
|
if justThreads then
|
||||||
threads[i].isError = true
|
while true do
|
||||||
|
self.scheduler:Act()
|
||||||
end
|
end
|
||||||
if threads[i] and coroutine.status(threads[i].thread)=="dead" then
|
|
||||||
local t = threads[i].TempRets or {}
|
|
||||||
threads[i].OnDeath:Fire(threads[i],"ended",t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15],t[16])
|
|
||||||
multi.setType(threads[i],multi.DestroyedObj)
|
|
||||||
table.remove(threads,i)
|
|
||||||
elseif threads[i] and threads[i].task == "skip" then
|
|
||||||
threads[i].pos = threads[i].pos + 1
|
|
||||||
if threads[i].count==threads[i].pos then
|
|
||||||
threads[i].task = ""
|
|
||||||
threads[i].__ready = true
|
|
||||||
end
|
|
||||||
elseif threads[i] and threads[i].task == "hold" then
|
|
||||||
if clock() - threads[i].intervalR>=threads[i].interval then
|
|
||||||
t0,t1,t2,t3,t4,t5,t6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = threads[i].func()
|
|
||||||
if t0 then
|
|
||||||
if t0==multi.NIL then
|
|
||||||
t0 = nil
|
|
||||||
end
|
|
||||||
threads[i].task = ""
|
|
||||||
threads[i].__ready = true
|
|
||||||
end
|
|
||||||
threads[i].intervalR = clock()
|
|
||||||
end
|
|
||||||
elseif threads[i] and threads[i].task == "sleep" then
|
|
||||||
if clock() - threads[i].time>=threads[i].sec then
|
|
||||||
threads[i].task = ""
|
|
||||||
threads[i].__ready = true
|
|
||||||
end
|
|
||||||
elseif threads[i] and threads[i].task == "holdF" then
|
|
||||||
if clock() - threads[i].intervalR>=threads[i].interval then
|
|
||||||
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = threads[i].func()
|
|
||||||
if t0 then
|
|
||||||
threads[i].task = ""
|
|
||||||
threads[i].__ready = true
|
|
||||||
elseif clock() - threads[i].time>=threads[i].sec then
|
|
||||||
threads[i].task = ""
|
|
||||||
threads[i].__ready = true
|
|
||||||
t0 = nil
|
|
||||||
t1 = "TIMEOUT"
|
|
||||||
end
|
|
||||||
threads[i].intervalR = clock()
|
|
||||||
end
|
|
||||||
elseif threads[i] and threads[i].task == "holdW" then
|
|
||||||
if clock() - threads[i].intervalR>=threads[i].interval then
|
|
||||||
threads[i].pos = threads[i].pos + 1
|
|
||||||
print(threads[i].pos,threads[i].count)
|
|
||||||
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = threads[i].func()
|
|
||||||
if t0 then
|
|
||||||
threads[i].task = ""
|
|
||||||
threads[i].__ready = true
|
|
||||||
elseif threads[i].count==threads[i].pos then
|
|
||||||
threads[i].task = ""
|
|
||||||
threads[i].__ready = true
|
|
||||||
t0 = nil
|
|
||||||
t1 = "TIMEOUT"
|
|
||||||
end
|
|
||||||
threads[i].intervalR = clock()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if threads[i] and threads[i].__ready then
|
|
||||||
threads[i].__ready = false
|
|
||||||
if coroutine.running() ~= threads[i].thread then
|
|
||||||
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=coroutine.resume(threads[i].thread,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
|
|
||||||
CheckRets(i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
helper(i)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
if justThreads then
|
|
||||||
while true do
|
|
||||||
multi.scheduler:Act()
|
|
||||||
end
|
end
|
||||||
end
|
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"
|
||||||
c.OnStopped = multi:newConnection()
|
c.OnStopped = self:newConnection()
|
||||||
c.OnStarted = multi:newConnection()
|
c.OnStarted = self:newConnection()
|
||||||
local Service_Data = {}
|
local Service_Data = {}
|
||||||
local active
|
local active
|
||||||
local time
|
local time
|
||||||
@ -1438,7 +1486,7 @@ function multi:newService(func) -- Priority managed threads
|
|||||||
local scheme = 1
|
local scheme = 1
|
||||||
function c.Start()
|
function c.Start()
|
||||||
if not active then
|
if not active then
|
||||||
time = multi:newTimer()
|
time = self:newTimer()
|
||||||
time:Start()
|
time:Start()
|
||||||
active = true
|
active = true
|
||||||
c:OnStarted(c,Service_Data)
|
c:OnStarted(c,Service_Data)
|
||||||
@ -1453,7 +1501,7 @@ function multi:newService(func) -- Priority managed threads
|
|||||||
task(ap)
|
task(ap)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
local th = multi:newThread(function()
|
local th = self:newThread(function()
|
||||||
while true do
|
while true do
|
||||||
process()
|
process()
|
||||||
end
|
end
|
||||||
@ -1537,6 +1585,7 @@ function multi:lightloop(settings)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
function multi:mainloop(settings)
|
function multi:mainloop(settings)
|
||||||
|
__CurrentProcess = self
|
||||||
multi.OnPreLoad:Fire()
|
multi.OnPreLoad:Fire()
|
||||||
multi.defaultSettings = settings or multi.defaultSettings
|
multi.defaultSettings = settings or multi.defaultSettings
|
||||||
self.uManager=self.uManagerRef
|
self.uManager=self.uManagerRef
|
||||||
@ -1591,8 +1640,10 @@ function multi:mainloop(settings)
|
|||||||
self.CID=_D
|
self.CID=_D
|
||||||
if not protect then
|
if not protect then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
else
|
else
|
||||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
if err then
|
if err then
|
||||||
Loop[_D].error=err
|
Loop[_D].error=err
|
||||||
self.OnError:Fire(Loop[_D],err)
|
self.OnError:Fire(Loop[_D],err)
|
||||||
@ -1614,8 +1665,10 @@ function multi:mainloop(settings)
|
|||||||
self.CID=_D
|
self.CID=_D
|
||||||
if not protect then
|
if not protect then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
else
|
else
|
||||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
if err then
|
if err then
|
||||||
Loop[_D].error=err
|
Loop[_D].error=err
|
||||||
self.OnError:Fire(Loop[_D],err)
|
self.OnError:Fire(Loop[_D],err)
|
||||||
@ -1646,8 +1699,10 @@ function multi:mainloop(settings)
|
|||||||
self.CID=_D
|
self.CID=_D
|
||||||
if not protect then
|
if not protect then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
else
|
else
|
||||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
if err then
|
if err then
|
||||||
Loop[_D].error=err
|
Loop[_D].error=err
|
||||||
self.OnError:Fire(Loop[_D],err)
|
self.OnError:Fire(Loop[_D],err)
|
||||||
@ -1670,6 +1725,7 @@ function multi:mainloop(settings)
|
|||||||
if not protect then
|
if not protect then
|
||||||
if sRef.solid then
|
if sRef.solid then
|
||||||
sRef:Act()
|
sRef:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
solid = true
|
solid = true
|
||||||
else
|
else
|
||||||
time = multi.timer(sRef.Act,sRef)
|
time = multi.timer(sRef.Act,sRef)
|
||||||
@ -1686,9 +1742,11 @@ function multi:mainloop(settings)
|
|||||||
else
|
else
|
||||||
if Loop[_D].solid then
|
if Loop[_D].solid then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
solid = true
|
solid = true
|
||||||
else
|
else
|
||||||
time, status, err=multi.timer(pcall,Loop[_D].Act,Loop[_D])
|
time, status, err=multi.timer(pcall,Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
Loop[_D].solid = true
|
Loop[_D].solid = true
|
||||||
solid = false
|
solid = false
|
||||||
end
|
end
|
||||||
@ -1728,8 +1786,10 @@ function multi:mainloop(settings)
|
|||||||
self.CID=_D
|
self.CID=_D
|
||||||
if not protect then
|
if not protect then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
else
|
else
|
||||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
if err then
|
if err then
|
||||||
Loop[_D].error=err
|
Loop[_D].error=err
|
||||||
self.OnError:Fire(Loop[_D],err)
|
self.OnError:Fire(Loop[_D],err)
|
||||||
@ -1748,6 +1808,7 @@ function multi:mainloop(settings)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
function multi:uManager(settings)
|
function multi:uManager(settings)
|
||||||
|
__CurrentProcess = self
|
||||||
multi.OnPreLoad:Fire()
|
multi.OnPreLoad:Fire()
|
||||||
multi.defaultSettings = settings or multi.defaultSettings
|
multi.defaultSettings = settings or multi.defaultSettings
|
||||||
self.t,self.tt = clock(),0
|
self.t,self.tt = clock(),0
|
||||||
@ -1786,8 +1847,10 @@ function multi:uManagerRef(settings)
|
|||||||
self.CID=_D
|
self.CID=_D
|
||||||
if not multi.defaultSettings.protect then
|
if not multi.defaultSettings.protect then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
else
|
else
|
||||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
if err then
|
if err then
|
||||||
Loop[_D].error=err
|
Loop[_D].error=err
|
||||||
self.OnError:Fire(Loop[_D],err)
|
self.OnError:Fire(Loop[_D],err)
|
||||||
@ -1809,8 +1872,10 @@ function multi:uManagerRef(settings)
|
|||||||
self.CID=_D
|
self.CID=_D
|
||||||
if not multi.defaultSettings.protect then
|
if not multi.defaultSettings.protect then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
else
|
else
|
||||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
if err then
|
if err then
|
||||||
Loop[_D].error=err
|
Loop[_D].error=err
|
||||||
self.OnError:Fire(Loop[_D],err)
|
self.OnError:Fire(Loop[_D],err)
|
||||||
@ -1837,8 +1902,10 @@ function multi:uManagerRef(settings)
|
|||||||
self.CID=_D
|
self.CID=_D
|
||||||
if not protect then
|
if not protect then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
else
|
else
|
||||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
if err then
|
if err then
|
||||||
Loop[_D].error=err
|
Loop[_D].error=err
|
||||||
self.OnError:Fire(Loop[_D],err)
|
self.OnError:Fire(Loop[_D],err)
|
||||||
@ -1861,6 +1928,7 @@ function multi:uManagerRef(settings)
|
|||||||
if not protect then
|
if not protect then
|
||||||
if sRef.solid then
|
if sRef.solid then
|
||||||
sRef:Act()
|
sRef:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
solid = true
|
solid = true
|
||||||
else
|
else
|
||||||
time = multi.timer(sRef.Act,sRef)
|
time = multi.timer(sRef.Act,sRef)
|
||||||
@ -1877,9 +1945,11 @@ function multi:uManagerRef(settings)
|
|||||||
else
|
else
|
||||||
if Loop[_D].solid then
|
if Loop[_D].solid then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
solid = true
|
solid = true
|
||||||
else
|
else
|
||||||
time, status, err=multi.timer(pcall,Loop[_D].Act,Loop[_D])
|
time, status, err=multi.timer(pcall,Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
Loop[_D].solid = true
|
Loop[_D].solid = true
|
||||||
solid = false
|
solid = false
|
||||||
end
|
end
|
||||||
@ -1919,8 +1989,10 @@ function multi:uManagerRef(settings)
|
|||||||
self.CID=_D
|
self.CID=_D
|
||||||
if not multi.defaultSettings.protect then
|
if not multi.defaultSettings.protect then
|
||||||
Loop[_D]:Act()
|
Loop[_D]:Act()
|
||||||
|
__CurrentProcess = self
|
||||||
else
|
else
|
||||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||||
|
__CurrentProcess = self
|
||||||
if err then
|
if err then
|
||||||
Loop[_D].error=err
|
Loop[_D].error=err
|
||||||
self.OnError:Fire(Loop[_D],err)
|
self.OnError:Fire(Loop[_D],err)
|
||||||
@ -1987,7 +2059,7 @@ multi.defaultSettings = {
|
|||||||
function multi:enableLoadDetection()
|
function multi:enableLoadDetection()
|
||||||
if multi.maxSpd then return end
|
if multi.maxSpd then return end
|
||||||
-- here we are going to run a quick benchMark solo
|
-- here we are going to run a quick benchMark solo
|
||||||
local temp = multi:newProcessor()
|
local temp = self:newProcessor()
|
||||||
temp:Start()
|
temp:Start()
|
||||||
local t = os.clock()
|
local t = os.clock()
|
||||||
local stop = false
|
local stop = false
|
||||||
@ -2006,12 +2078,12 @@ local lastVal = 0
|
|||||||
local bb = 0
|
local bb = 0
|
||||||
|
|
||||||
function multi:getLoad()
|
function multi:getLoad()
|
||||||
if not multi.maxSpd then multi:enableLoadDetection() end
|
if not multi.maxSpd then self:enableLoadDetection() end
|
||||||
if busy then return lastVal end
|
if busy then return lastVal end
|
||||||
local val = nil
|
local val = nil
|
||||||
if thread.isThread() then
|
if thread.isThread() then
|
||||||
local bench
|
local bench
|
||||||
multi:benchMark(.01):OnBench(function(time,steps)
|
self:benchMark(.01):OnBench(function(time,steps)
|
||||||
bench = steps
|
bench = steps
|
||||||
bb = steps
|
bb = steps
|
||||||
end)
|
end)
|
||||||
@ -2023,12 +2095,12 @@ function multi:getLoad()
|
|||||||
else
|
else
|
||||||
busy = true
|
busy = true
|
||||||
local bench
|
local bench
|
||||||
multi:benchMark(.01):OnBench(function(time,steps)
|
self:benchMark(.01):OnBench(function(time,steps)
|
||||||
bench = steps
|
bench = steps
|
||||||
bb = steps
|
bb = steps
|
||||||
end)
|
end)
|
||||||
while not bench do
|
while not bench do
|
||||||
multi:uManager()
|
self:uManager()
|
||||||
end
|
end
|
||||||
bench = bench^1.5
|
bench = bench^1.5
|
||||||
val = math.ceil((1-(bench/(multi.maxSpd/2.2)))*100)
|
val = math.ceil((1-(bench/(multi.maxSpd/2.2)))*100)
|
||||||
@ -2276,4 +2348,5 @@ 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
|
||||||
|
|||||||
75
test.lua
75
test.lua
@ -21,50 +21,41 @@ end).OnError(function(...)
|
|||||||
print(...)
|
print(...)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- local sandcount = 0
|
sandbox = multi:newProcessor()
|
||||||
-- function multi:newProcessor(name)
|
for i,v in pairs(sandbox.process) do
|
||||||
-- local c = {}
|
print(i,v)
|
||||||
-- setmetatable(c,{__index = self})
|
end
|
||||||
-- local multi,thread = require("multi"):init() -- We need to capture the t in thread
|
io.read()
|
||||||
-- local name = name or "Processor_"..sandcount
|
sandbox:newTLoop(function()
|
||||||
-- sandcount = sandcount + 1
|
print("testing...")
|
||||||
-- c.Mainloop = {}
|
end,1)
|
||||||
-- c.Type = "process"
|
|
||||||
-- c.Active = false
|
|
||||||
-- c.OnError = multi:newConnection()
|
|
||||||
-- c.process = self:newThread(name,function()
|
|
||||||
-- while true do
|
|
||||||
-- thread.hold(function()
|
|
||||||
-- return sandbox.Active
|
|
||||||
-- end)
|
|
||||||
-- c:uManager()
|
|
||||||
-- end
|
|
||||||
-- end).OnError(c.OnError)
|
|
||||||
-- function c.Start()
|
|
||||||
-- c.Active = true
|
|
||||||
-- end
|
|
||||||
-- function c.Stop()
|
|
||||||
-- c.Active = false
|
|
||||||
-- end
|
|
||||||
-- return c
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- sandbox = multi:newProcessor()
|
test2 = multi:newTLoop(function()
|
||||||
-- sandbox:newTLoop(function()
|
print("testing2...")
|
||||||
-- print("testing...")
|
end,1)
|
||||||
-- end,1)
|
|
||||||
|
|
||||||
-- test2 = multi:newTLoop(function()
|
sandbox:newThread("Test Thread",function()
|
||||||
-- print("testing2...")
|
local a = 0
|
||||||
-- end,1)
|
while true do
|
||||||
|
thread.sleep(1)
|
||||||
|
a = a + 1
|
||||||
|
print("Thread Test: ".. multi.getCurrentProcess().Name)
|
||||||
|
if a == 10 then
|
||||||
|
sandbox.Stop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end).OnError(function(...)
|
||||||
|
print(...)
|
||||||
|
end)
|
||||||
|
multi:newThread("Test Thread",function()
|
||||||
|
while true do
|
||||||
|
thread.sleep(1)
|
||||||
|
print("Thread Test: ".. multi.getCurrentProcess().Name)
|
||||||
|
end
|
||||||
|
end).OnError(function(...)
|
||||||
|
print(...)
|
||||||
|
end)
|
||||||
|
|
||||||
-- sandbox:newThread("Test Thread",function()
|
sandbox.Start()
|
||||||
-- while true do
|
|
||||||
-- thread.sleep(1)
|
|
||||||
-- print("Thread Test...")
|
|
||||||
-- end
|
|
||||||
-- end)
|
|
||||||
|
|
||||||
-- sandbox.Start()
|
|
||||||
|
|
||||||
multi:mainloop()
|
multi:mainloop()
|
||||||
Loading…
x
Reference in New Issue
Block a user