Working on 16.0.0 #53

Merged
rayaman merged 120 commits from v16.0.0 into master 2024-02-25 00:00:51 -05:00
9 changed files with 239 additions and 97 deletions
Showing only changes of commit 160c72d2f3 - Show all commits

View File

@ -237,6 +237,7 @@ Added
Changed Changed
--- ---
- multi:newUpdater(skip, func) -- Now accepts func as the second argument. So you don't need to call OnUpdate(func) after creation.
- multi errors now internally call `multi.error` instead of `multi.print` - multi errors now internally call `multi.error` instead of `multi.print`
- Actors Act() method now returns true when the main event is fired. Steps/Loops always return true. Nil is returned otherwise. - Actors Act() method now returns true when the main event is fired. Steps/Loops always return true. Nil is returned otherwise.
- Connection:Connect(func, name) Now you can supply a name and name the connection. - Connection:Connect(func, name) Now you can supply a name and name the connection.
@ -296,7 +297,7 @@ Fixed
ToDo ToDo
--- ---
- N/A - Network Manager, I know I said it will be in this release, but I'm still planning it out.
# Update 15.3.1 - Bug fix # Update 15.3.1 - Bug fix
Fixed Fixed

147
init.lua
View File

@ -32,6 +32,51 @@ local find_optimization = false
local threadManager local threadManager
local __CurrentConnectionThread local __CurrentConnectionThread
-- Types
multi.DestroyedObj = {
Type = "DESTROYED",
}
local function uni()
return multi.DestroyedObj
end
local function uniN() end
function multi.setType(obj,t)
if t == multi.DestroyedObj then
for i,v in pairs(obj) do
obj[i] = nil
end
setmetatable(obj, {
__index = function(t,k)
return setmetatable({},{__index = uni,__newindex = uni,__call = uni,__metatable = multi.DestroyedObj,__tostring = function() return "destroyed" end,__unm = uni,__add = uni,__sub = uni,__mul = uni,__div = uni,__mod = uni,__pow = uni,__concat = uni})
end,__newindex = uni,__call = uni,__metatable = multi.DestroyedObj,__tostring = function() return "destroyed" end,__unm = uni,__add = uni,__sub = uni,__mul = uni,__div = uni,__mod = uni,__pow = uni,__concat = uni
})
end
end
setmetatable(multi.DestroyedObj, {
__index = function(t,k)
return setmetatable({},{__index = uni,__newindex = uni,__call = uni,__metatable = multi.DestroyedObj,__tostring = function() return "destroyed" end,__unm = uni,__add = uni,__sub = uni,__mul = uni,__div = uni,__mod = uni,__pow = uni,__concat = uni})
end,__newindex = uni,__call = uni,__metatable = multi.DestroyedObj,__tostring = function() return "destroyed" end,__unm = uni,__add = uni,__sub = uni,__mul = uni,__div = uni,__mod = uni,__pow = uni,__concat = uni
})
multi.DESTROYED = multi.DestroyedObj
multi.ROOTPROCESS = "rootprocess"
multi.CONNECTOR = "connector"
multi.TIMEMASTER = "timemaster"
multi.PROCESS = "process"
multi.TIMER = "timer"
multi.EVENT = "event"
multi.UPDATER = "updater"
multi.ALARM = "alarm"
multi.LOOP = "loop"
multi.TLOOP = "tloop"
multi.STEP = "step"
multi.TSTEP = "tstep"
multi.THREAD = "thread"
multi.SERVICE = "service"
if not _G["$multi"] then if not _G["$multi"] then
_G["$multi"] = {multi = multi, thread = thread} _G["$multi"] = {multi = multi, thread = thread}
end end
@ -43,7 +88,7 @@ local NIL = multi.NIL
multi.Mainloop = {} multi.Mainloop = {}
multi.Children = {} multi.Children = {}
multi.Active = true multi.Active = true
multi.Type = "rootprocess" multi.Type = multi.ROOTPROCESS
multi.LinkedPath = multi multi.LinkedPath = multi
multi.TIMEOUT = "TIMEOUT" multi.TIMEOUT = "TIMEOUT"
multi.TID = 0 multi.TID = 0
@ -87,24 +132,6 @@ local function pack(...)
return {...} return {...}
end end
-- Types
multi.DESTROYED = multi.DestroyedObj
multi.ROOTPROCESS = "rootprocess"
multi.CONNECTOR = "connector"
multi.CONNECTOR_LINK = "connector_link"
multi.TIMEMASTER = "timemaster"
multi.PROCESS = "process"
multi.TIMER = "timer"
multi.EVENT = "event"
multi.UPDATER = "updater"
multi.ALARM = "alarm"
multi.LOOP = "loop"
multi.TLOOP = "tloop"
multi.STEP = "step"
multi.TSTEP = "tstep"
multi.THREAD = "thread"
multi.SERVICE = "service"
--Processor --Processor
local priorityTable = {[false]="Disabled",[true]="Enabled"} local priorityTable = {[false]="Disabled",[true]="Enabled"}
local ProcessName = {"SubProcessor","MainProcessor"} local ProcessName = {"SubProcessor","MainProcessor"}
@ -273,7 +300,7 @@ function multi:newConnection(protect,func,kill)
return cn return cn
end}) end})
c.Type='connector' c.Type=multi.CONNECTOR
c.func={} c.func={}
c.ID=0 c.ID=0
local protect=protect or false local protect=protect or false
@ -504,7 +531,7 @@ end
function multi:SetTime(n) function multi:SetTime(n)
if not n then n=3 end if not n then n=3 end
local c=self:newBase() local c=self:newBase()
c.Type='timemaster' c.Type=multi.TIMEMASTER
c.timer=self:newTimer() c.timer=self:newTimer()
c.timer:Start() c.timer:Start()
c.set=n c.set=n
@ -533,7 +560,7 @@ end
-- Timer stuff done -- Timer stuff done
multi.PausedObjects = {} multi.PausedObjects = {}
function multi:Pause() function multi:Pause()
if self.Type=='rootprocess' then if self.Type==multi.ROOTPROCESS then
multi.print("You cannot pause the main process. Doing so will stop all methods and freeze your program! However if you still want to use multi:_Pause()") multi.print("You cannot pause the main process. Doing so will stop all methods and freeze your program! However if you still want to use multi:_Pause()")
else else
self.Active=false self.Active=false
@ -550,7 +577,7 @@ function multi:Pause()
end end
function multi:Resume() function multi:Resume()
if self.Type=='process' or self.Type=='rootprocess' then if self.Type==multi.PROCESS or self.Type==multi.ROOTPROCESS then
self.Active=true self.Active=true
local c=self:getChildren() local c=self:getChildren()
for i=1,#c do for i=1,#c do
@ -567,7 +594,7 @@ function multi:Resume()
end end
function multi:Destroy() function multi:Destroy()
if self.Type=='process' or self.Type=='rootprocess' then if self.Type==multi.PROCESS or self.Type==multi.ROOTPROCESS then
local c=self:getChildren() local c=self:getChildren()
for i=1,#c do for i=1,#c do
self.OnObjectDestroyed:Fire(c[i]) self.OnObjectDestroyed:Fire(c[i])
@ -620,9 +647,9 @@ end
--Constructors [CORE] --Constructors [CORE]
local _tid = 0 local _tid = 0
function multi:newBase(ins) function multi:newBase(ins)
if not(self.Type=='rootprocess' or self.Type=='process') then multi.error('Can only create an object on multi or an interface obj') return false end if not(self.Type==multi.ROOTPROCESS or self.Type==multi.PROCESS) then multi.error('Can only create an object on multi or an interface obj') return false end
local c = {} local c = {}
if self.Type=='process' then if self.Type==multi.PROCESS then
setmetatable(c, {__index = multi}) setmetatable(c, {__index = multi})
else else
setmetatable(c, {__index = multi}) setmetatable(c, {__index = multi})
@ -646,18 +673,13 @@ function multi:newBase(ins)
return c return c
end end
function multi:newConnector()
local c = {Type = "connector"}
return c
end
multi.OnObjectCreated=multi:newConnection() multi.OnObjectCreated=multi:newConnection()
multi.OnObjectDestroyed=multi:newConnection() multi.OnObjectDestroyed=multi:newConnection()
multi.OnLoad = multi:newConnection(nil,nil,true) multi.OnLoad = multi:newConnection(nil,nil,true)
ignoreconn = false ignoreconn = false
function multi:newTimer() function multi:newTimer()
local c={} local c={}
c.Type='timer' c.Type=multi.TIMER
local time=0 local time=0
local count=0 local count=0
local paused=false local paused=false
@ -690,7 +712,7 @@ end
--Core Actors --Core Actors
function multi:newEvent(task) function multi:newEvent(task)
local c=self:newBase() local c=self:newBase()
c.Type='event' c.Type=multi.EVENT
local task = task or function() end local task = task or function() end
function c:Act() function c:Act()
local t = task(self) local t = task(self)
@ -712,9 +734,9 @@ function multi:newEvent(task)
return c return c
end end
function multi:newUpdater(skip) function multi:newUpdater(skip, func)
local c=self:newBase() local c=self:newBase()
c.Type='updater' c.Type=multi.UPDATER
local pos = 1 local pos = 1
local skip = skip or 1 local skip = skip or 1
function c:Act() function c:Act()
@ -731,13 +753,16 @@ function multi:newUpdater(skip)
end end
c.OnUpdate = self:newConnection():fastMode() c.OnUpdate = self:newConnection():fastMode()
c:setName(c.Type) c:setName(c.Type)
if func then
c.OnUpdate(func)
end
self:create(c) self:create(c)
return c return c
end end
function multi:newAlarm(set) function multi:newAlarm(set)
local c=self:newBase() local c=self:newBase()
c.Type='alarm' c.Type=multi.ALARM
c:setPriority("Low") c:setPriority("Low")
c.set=set or 0 c.set=set or 0
local count = 0 local count = 0
@ -773,9 +798,9 @@ function multi:newAlarm(set)
return c return c
end end
function multi:newLoop(func,notime) function multi:newLoop(func, notime)
local c=self:newBase() local c=self:newBase()
c.Type='loop' c.Type=multi.LOOP
local start=clock() local start=clock()
if notime then if notime then
function c:Act() function c:Act()
@ -802,7 +827,7 @@ end
function multi:newStep(start,reset,count,skip) function multi:newStep(start,reset,count,skip)
local c=self:newBase() local c=self:newBase()
think=1 think=1
c.Type='step' c.Type=multi.STEP
c.pos=start or 1 c.pos=start or 1
c.endAt=reset or math.huge c.endAt=reset or math.huge
c.skip=skip or 0 c.skip=skip or 0
@ -861,7 +886,7 @@ end
function multi:newTLoop(func,set) function multi:newTLoop(func,set)
local c=self:newBase() local c=self:newBase()
c.Type='tloop' c.Type=multi.TLOOP
c.set=set or 0 c.set=set or 0
c.timer=self:newTimer() c.timer=self:newTimer()
c.life=0 c.life=0
@ -902,7 +927,7 @@ end
function multi:newTStep(start,reset,count,set) function multi:newTStep(start,reset,count,set)
local c=self:newStep(start,reset,count) local c=self:newStep(start,reset,count)
c.Type='tstep' c.Type=multi.TSTEP
c:setPriority("Low") c:setPriority("Low")
local reset = reset or math.huge local reset = reset or math.huge
c.timer=clock() c.timer=clock()
@ -1034,7 +1059,7 @@ function multi:newProcessor(name, nothread)
local name = name or "Processor_" .. sandcount local name = name or "Processor_" .. sandcount
sandcount = sandcount + 1 sandcount = sandcount + 1
c.Mainloop = {} c.Mainloop = {}
c.Type = "process" c.Type = multi.PROCESS
local Active = nothread or false local Active = nothread or false
c.Name = name or "" c.Name = name or ""
c.threads = {} c.threads = {}
@ -1248,7 +1273,7 @@ function thread.hold(n,opt)
if type(n) == "number" then if type(n) == "number" then
thread.getRunningThread().lastSleep = clock() thread.getRunningThread().lastSleep = clock()
return 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 == multi.CONNECTOR then
return yield(CMD, t_hold, conn_test(n), nil, interval) return yield(CMD, t_hold, conn_test(n), nil, interval)
elseif type(n) == "function" then elseif type(n) == "function" then
return yield(CMD, t_hold, n or dFunc, nil, interval) return yield(CMD, t_hold, n or dFunc, nil, interval)
@ -1499,7 +1524,7 @@ function thread:newThread(name, func, ...)
c.Name=name c.Name=name
c.thread=create(func) c.thread=create(func)
c.sleep=1 c.sleep=1
c.Type = "thread" c.Type = multi.THREAD
c.TID = threadid c.TID = threadid
c.firstRunDone=false c.firstRunDone=false
c._isPaused = false c._isPaused = false
@ -1561,7 +1586,7 @@ function thread:newThread(name, func, ...)
c.Destroy = c.Kill c.Destroy = c.Kill
if thread.isThread() then if thread.isThread() then
multi:newLoop(function(loop) multi:newLoop(function(loop)
if self.Type == "process" then if self.Type == multi.PROCESS then
table.insert(self.startme, c) table.insert(self.startme, c)
else else
table.insert(threadManager.startme, c) table.insert(threadManager.startme, c)
@ -1569,7 +1594,7 @@ function thread:newThread(name, func, ...)
loop:Break() loop:Break()
end) end)
else else
if self.Type == "process" then if self.Type == multi.PROCESS then
table.insert(self.startme, c) table.insert(self.startme, c)
else else
table.insert(threadManager.startme, c) table.insert(threadManager.startme, c)
@ -1782,7 +1807,7 @@ end
function multi:newService(func) -- Priority managed threads function multi:newService(func) -- Priority managed threads
local c = {} local c = {}
c.Type = "service" c.Type = multi.SERVICE
c.OnStopped = self:newConnection() c.OnStopped = self:newConnection()
c.OnStarted = self:newConnection() c.OnStarted = self:newConnection()
local Service_Data = {} local Service_Data = {}
@ -1957,7 +1982,7 @@ local function doOpt()
if type(n) == "number" then if type(n) == "number" then
thread.getRunningThread().lastSleep = clock() thread.getRunningThread().lastSleep = clock()
return 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 == multi.CONNECTOR then
local rdy = function() local rdy = function()
return false return false
end end
@ -2074,32 +2099,6 @@ if table.unpack and not unpack then
unpack=table.unpack unpack=table.unpack
end end
multi.DestroyedObj = {
Type = "destroyed",
}
local function uni()
return multi.DestroyedObj
end
local function uniN() end
function multi.setType(obj,t)
if t == multi.DestroyedObj then
for i,v in pairs(obj) do
obj[i] = nil
end
setmetatable(obj, {
__index = function(t,k)
return setmetatable({},{__index = uni,__newindex = uni,__call = uni,__metatable = multi.DestroyedObj,__tostring = function() return "destroyed" end,__unm = uni,__add = uni,__sub = uni,__mul = uni,__div = uni,__mod = uni,__pow = uni,__concat = uni})
end,__newindex = uni,__call = uni,__metatable = multi.DestroyedObj,__tostring = function() return "destroyed" end,__unm = uni,__add = uni,__sub = uni,__mul = uni,__div = uni,__mod = uni,__pow = uni,__concat = uni
})
end
end
setmetatable(multi.DestroyedObj, {
__index = function(t,k)
return setmetatable({},{__index = uni,__newindex = uni,__call = uni,__metatable = multi.DestroyedObj,__tostring = function() return "destroyed" end,__unm = uni,__add = uni,__sub = uni,__mul = uni,__div = uni,__mod = uni,__pow = uni,__concat = uni})
end,__newindex = uni,__call = uni,__metatable = multi.DestroyedObj,__tostring = function() return "destroyed" end,__unm = uni,__add = uni,__sub = uni,__mul = uni,__div = uni,__mod = uni,__pow = uni,__concat = uni
})
math.randomseed(os.time()) math.randomseed(os.time())
function multi:enableLoadDetection() function multi:enableLoadDetection()

View File

@ -22,8 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
if not (GLOBAL and THREAD) then if not (GLOBAL and THREAD) then
local GLOBAL, THREAD = multi.integration.GLOBAL,multi.integration.THREAD GLOBAL, THREAD = multi.integration.GLOBAL,multi.integration.THREAD
else else
lanes = require("lanes") lanes = require("lanes")
end end
@ -54,17 +55,24 @@ function multi:newSystemThreadedTable(name)
local c = {} local c = {}
c.link = lanes.linda() c.link = lanes.linda()
c.Name = name c.Name = name
setmetatable(c,{
-- function c:getIndex()
-- return c.link:dump()
-- end
function c:init()
return self
end
setmetatable(c,{
__index = function(t,k) __index = function(t,k)
return c.link:get(k) return c.link:get(k)
end, end,
__newindex = function(t,k,v) __newindex = function(t,k,v)
c.link:set(k,v) c.link:set(k, v)
end end
}) })
function c:init()
return self
end
GLOBAL[name or "_"] = c GLOBAL[name or "_"] = c
return c return c
end end
@ -134,7 +142,7 @@ function multi:newSystemThreadedJobQueue(n)
end) end)
for i=1,c.cores do for i=1,c.cores do
multi:newSystemThread("SystemThreadedJobQueue",function(queue) multi:newSystemThread("SystemThreadedJobQueue",function(queue)
local multi,thread = require("multi"):init() local multi, thread = require("multi"):init()
local idle = os.clock() local idle = os.clock()
local clock = os.clock local clock = os.clock
local ref = 0 local ref = 0
@ -145,12 +153,14 @@ function multi:newSystemThreadedJobQueue(n)
return queueJob:pop() return queueJob:pop()
end) end)
idle = clock() idle = clock()
local name = table.remove(dat,1) thread:newThread("test",function()
local jid = table.remove(dat,1) local name = table.remove(dat, 1)
local args = table.remove(dat,1) local jid = table.remove(dat, 1)
queueReturn:push{jid, funcs[name](unpack(args)),queue} local args = table.remove(dat, 1)
queueReturn:push{jid, funcs[name](unpack(args)), queue}
end)
end end
end) end).OnError(multi.error)
thread:newThread("DoAllHandler",function() thread:newThread("DoAllHandler",function()
while true do while true do
local dat = thread.hold(function() local dat = thread.hold(function()

View File

@ -97,6 +97,7 @@ function multi:newSystemThread(name, func, ...)
},function(...) },function(...)
multi, thread = require("multi"):init(multi_settings) multi, thread = require("multi"):init(multi_settings)
require("multi.integration.lanesManager.extensions") require("multi.integration.lanesManager.extensions")
require("multi.integration.sharedExtensions")
local has_error = true local has_error = true
returns = {pcall(func, ...)} returns = {pcall(func, ...)}
return_linda:set("returns", returns) return_linda:set("returns", returns)
@ -179,6 +180,7 @@ multi.integration = {} -- for module creators
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
require("multi.integration.lanesManager.extensions") require("multi.integration.lanesManager.extensions")
require("multi.integration.sharedExtensions")
return { return {
init = function() init = function()
return GLOBAL, THREAD return GLOBAL, THREAD

View File

@ -122,13 +122,11 @@ local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda, __Console)
}) })
function THREAD.setENV(env, name) function THREAD.setENV(env, name)
name = name or "__env" GLOBAL[name or "__env"] = env
GLOBAL[name] = env
end end
function THREAD.getENV(name) function THREAD.getENV(name)
name = name or "__env" return GLOBAL[name or "__env"]
return GLOBAL[name]
end end
function THREAD.exposeENV(name) function THREAD.exposeENV(name)

View File

@ -184,12 +184,14 @@ function multi:newSystemThreadedJobQueue(n)
end end
local dat = queue:performAtomic(atomic) local dat = queue:performAtomic(atomic)
if dat then if dat then
lastProc = os.clock() multi:newThread("Test",function()
local name = table.remove(dat,1) lastProc = os.clock()
local id = table.remove(dat,1) local name = table.remove(dat,1)
local tab = {funcs[name](unpack(dat))} local id = table.remove(dat,1)
table.insert(tab,1,id) local tab = {funcs[name](unpack(dat))}
queueReturn:push(tab) table.insert(tab,1,id)
queueReturn:push(tab)
end)
end end
end end
end):OnError(function(...) end):OnError(function(...)

View File

@ -53,6 +53,7 @@ multi.integration={}
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
pcall(require,"multi.integration.loveManager.extensions") pcall(require,"multi.integration.loveManager.extensions")
pcall(require,"multi.integration.sharedExtensions")
stab["returns"] = {THREAD.loadDump(__FUNC__)(unpack(__IMPORTS))} stab["returns"] = {THREAD.loadDump(__FUNC__)(unpack(__IMPORTS))}
]] ]]
@ -121,5 +122,6 @@ end
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
require("multi.integration.loveManager.extensions") require("multi.integration.loveManager.extensions")
require("multi.integration.sharedExtensions")
multi.print("Integrated Love Threading!") multi.print("Integrated Love Threading!")
return {init = function() return GLOBAL, THREAD end} return {init = function() return GLOBAL, THREAD end}

View File

@ -110,6 +110,7 @@ multi.integration = {} -- for module creators
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
require("multi.integration.pseudoManager.extensions") require("multi.integration.pseudoManager.extensions")
require("multi.integration.sharedExtensions")
return { return {
init = function() init = function()
return GLOBAL, THREAD return GLOBAL, THREAD

View File

@ -0,0 +1,127 @@
local multi, thread = require("multi"):init()
-- Returns a handler that allows a user to interact with an object on another thread!
-- Create on the thread that you want to interact with, send over the handle
function multi:newProxy(obj)
local c = {
__index = function()
--
end,
__newindex = function()
--
end,
__call = function()
--
end
}
c.name = multi.randomString(12)
function c:init()
if not multi.isMainThread then
c.send = multi:newSystemThreadedQueue(self.name.."_S"):init()
c.recv = multi:newSystemThreadedQueue(self.name.."_R"):init()
c.ref = obj
else
GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD
c.send = THREAD.waitFor(self.name.."_S")
c.recv = THREAD.waitFor(self.name.."_R")
end
end
return c
end
function multi:newSystemThreadedProcessor(name, cores)
local name = name or "STP_"multi.randomString(4) -- set a random name if none was given.
local autoscale = autoscale or false -- Will scale up the number of cores that the process uses.
local c = {}
setmetatable(c,{__index = multi})
c.cores = cores or 8
c.Name = name
c.Mainloop = {}
c.__count = 0
c.processors = {}
c.proc_list = {}
c.OnObjectCreated = multi:newConnection()
c.parent = self
c.jobqueue = multi:newSystemThreadedJobQueue(c.cores)
c.jobqueue:registerFunction("__spawnThread__", function(name, func, ...)
local multi, thread = require("multi"):init()
thread:newThread(name, func, ...)
return true
end)
c.jobqueue:registerFunction("__spawnTask__", function(obj, ...)
local multi, thread = require("multi"):init()
multi[obj](multi, func)
return true
end)
c.OnObjectCreated(function(proc, obj)
if obj.Type == multi.UPDATER then
local func = obj.OnUpdate:Remove()[1]
c.jobqueue:pushJob("__spawnTask__", "newUpdater", func)
elseif obj.Type == multi.LOOP then
local func = obj.OnLoop:Remove()[1]
c.jobqueue:pushJob("__spawnTask__", "newLoop", func)
else
return multi.error("Invalid type!")
end
end)
function c:getHandler()
-- Not needed
end
function c:getThreads()
-- We might want to keep track of the number of threads we have
end
function c:getFullName()
return self.parent:getFullName() .. "." .. c.Name
end
function c:getName()
return self.Name
end
function c:newThread(name, func, ...)
c.jobqueue:pushJob("__spawnThread__", name, func, ...)
end
function c:newFunction(func, holdme)
return c.jobqueue:newFunction(func, holdme)
end
function c.run()
-- Not needed
end
function c.isActive()
--
end
function c.Start()
--
end
function c.Stop()
--
end
function c:Destroy()
--
end
return c
end