mirror of
https://github.com/rayaman/multi.git
synced 2026-09-05 07:27:35 -04:00
doing some tests
This commit is contained in:
@@ -1 +0,0 @@
|
||||
require("multi")
|
||||
@@ -1,305 +0,0 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
multi.OnObjectCreated(function(obj)
|
||||
if obj.Type=="loop" then
|
||||
function obj:Act()
|
||||
for i=1,#self.func do
|
||||
self.func[i](self.Parent.clock()-self.Start,self)
|
||||
end
|
||||
end
|
||||
elseif obj.Type=="step" then
|
||||
function obj:Act()
|
||||
if self~=nil then
|
||||
if self.spos==0 then
|
||||
if self.pos==self.start then
|
||||
for fe=1,#self.funcS do
|
||||
self.funcS[fe](self)
|
||||
end
|
||||
end
|
||||
for i=1,#self.func do
|
||||
self.func[i](self.pos,self)
|
||||
end
|
||||
self.pos=self.pos+self.count
|
||||
if self.pos-self.count==self.endAt then
|
||||
self:Pause()
|
||||
for fe=1,#self.funcE do
|
||||
self.funcE[fe](self)
|
||||
end
|
||||
self.pos=self.start
|
||||
end
|
||||
end
|
||||
end
|
||||
self.spos=self.spos+1
|
||||
if self.spos>=self.skip then
|
||||
self.spos=0
|
||||
end
|
||||
end
|
||||
elseif obj.Type=="tstep" then
|
||||
function c:Act()
|
||||
if self.clock()-self.timer>=self.set then
|
||||
self:Reset()
|
||||
if self.pos==self.start then
|
||||
for fe=1,#self.funcS do
|
||||
self.funcS[fe](self)
|
||||
end
|
||||
end
|
||||
for i=1,#self.func do
|
||||
self.func[i](self.pos,self)
|
||||
end
|
||||
self.pos=self.pos+self.count
|
||||
if self.pos-self.count==self.endAt then
|
||||
self:Pause()
|
||||
for fe=1,#self.funcE do
|
||||
self.funcE[fe](self)
|
||||
end
|
||||
self.pos=self.start
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
if thread then
|
||||
function multi:newThreadedLoop(name,func)
|
||||
local c=self:newTBase()
|
||||
c.Type='loopThread'
|
||||
c.Start=os.clock()
|
||||
if func then
|
||||
c.func={func}
|
||||
end
|
||||
function c:tofile(path)
|
||||
local m=bin.new()
|
||||
m:addBlock(self.Type)
|
||||
m:addBlock(self.func)
|
||||
m:addBlock(self.Active)
|
||||
m:tofile(path)
|
||||
end
|
||||
function c:Resume()
|
||||
self.rest=false
|
||||
end
|
||||
function c:Pause()
|
||||
self.rest=true
|
||||
end
|
||||
function c:OnLoop(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
c.rest=false
|
||||
c.updaterate=0
|
||||
c.restRate=.75
|
||||
multi:newThread(name,function(ref)
|
||||
while true do
|
||||
if c.rest then
|
||||
thread.sleep(c.restRate)
|
||||
else
|
||||
for i=1,#c.func do
|
||||
c.func[i](os.clock()-self.Start,c)
|
||||
end
|
||||
thread.sleep(c.updaterate)
|
||||
end
|
||||
end
|
||||
end)
|
||||
self:create(c)
|
||||
return c
|
||||
end
|
||||
function multi:newThreadedStep(name,start,reset,count,skip)
|
||||
local c=self:newTBase()
|
||||
local think=1
|
||||
c.Type='stepThread'
|
||||
c.pos=start or 1
|
||||
c.endAt=reset or math.huge
|
||||
c.skip=skip or 0
|
||||
c.spos=0
|
||||
c.count=count or 1*think
|
||||
c.funcE={}
|
||||
c.funcS={}
|
||||
c.start=start or 1
|
||||
if start~=nil and reset~=nil then
|
||||
if start>reset then
|
||||
think=-1
|
||||
end
|
||||
end
|
||||
function c:tofile(path)
|
||||
local m=bin.new()
|
||||
m:addBlock(self.Type)
|
||||
m:addBlock(self.func)
|
||||
m:addBlock(self.funcE)
|
||||
m:addBlock(self.funcS)
|
||||
m:addBlock({pos=self.pos,endAt=self.endAt,skip=self.skip,spos=self.spos,count=self.count,start=self.start})
|
||||
m:addBlock(self.Active)
|
||||
m:tofile(path)
|
||||
end
|
||||
function c:Resume()
|
||||
self.rest=false
|
||||
end
|
||||
function c:Pause()
|
||||
self.rest=true
|
||||
end
|
||||
c.Reset=c.Resume
|
||||
function c:OnStart(func)
|
||||
table.insert(self.funcS,func)
|
||||
end
|
||||
function c:OnStep(func)
|
||||
table.insert(self.func,1,func)
|
||||
end
|
||||
function c:OnEnd(func)
|
||||
table.insert(self.funcE,func)
|
||||
end
|
||||
function c:Break()
|
||||
self.rest=true
|
||||
end
|
||||
function c:Update(start,reset,count,skip)
|
||||
self.start=start or self.start
|
||||
self.endAt=reset or self.endAt
|
||||
self.skip=skip or self.skip
|
||||
self.count=count or self.count
|
||||
self:Resume()
|
||||
end
|
||||
c.updaterate=0
|
||||
c.restRate=.1
|
||||
multi:newThread(name,function(ref)
|
||||
while true do
|
||||
if c.rest then
|
||||
ref:sleep(c.restRate)
|
||||
else
|
||||
if c~=nil then
|
||||
if c.spos==0 then
|
||||
if c.pos==c.start then
|
||||
for fe=1,#c.funcS do
|
||||
c.funcS[fe](c)
|
||||
end
|
||||
end
|
||||
for i=1,#c.func do
|
||||
c.func[i](c.pos,c)
|
||||
end
|
||||
c.pos=c.pos+c.count
|
||||
if c.pos-c.count==c.endAt then
|
||||
c:Pause()
|
||||
for fe=1,#c.funcE do
|
||||
c.funcE[fe](c)
|
||||
end
|
||||
c.pos=c.start
|
||||
end
|
||||
end
|
||||
end
|
||||
c.spos=c.spos+1
|
||||
if c.spos>=c.skip then
|
||||
c.spos=0
|
||||
end
|
||||
ref:sleep(c.updaterate)
|
||||
end
|
||||
end
|
||||
end)
|
||||
self:create(c)
|
||||
return c
|
||||
end
|
||||
function multi:newThreadedTStep(name,start,reset,count,set)
|
||||
local c=self:newTBase()
|
||||
local think=1
|
||||
c.Type='tstepThread'
|
||||
c.Priority=self.Priority_Low
|
||||
c.start=start or 1
|
||||
local reset = reset or math.huge
|
||||
c.endAt=reset
|
||||
c.pos=start or 1
|
||||
c.skip=skip or 0
|
||||
c.count=count or 1*think
|
||||
c.funcE={}
|
||||
c.timer=os.clock()
|
||||
c.set=set or 1
|
||||
c.funcS={}
|
||||
function c:Update(start,reset,count,set)
|
||||
self.start=start or self.start
|
||||
self.pos=self.start
|
||||
self.endAt=reset or self.endAt
|
||||
self.set=set or self.set
|
||||
self.count=count or self.count or 1
|
||||
self.timer=os.clock()
|
||||
self:Resume()
|
||||
end
|
||||
function c:tofile(path)
|
||||
local m=bin.new()
|
||||
m:addBlock(self.Type)
|
||||
m:addBlock(self.func)
|
||||
m:addBlock(self.funcE)
|
||||
m:addBlock(self.funcS)
|
||||
m:addBlock({pos=self.pos,endAt=self.endAt,skip=self.skip,timer=self.timer,count=self.count,start=self.start,set=self.set})
|
||||
m:addBlock(self.Active)
|
||||
m:tofile(path)
|
||||
end
|
||||
function c:Resume()
|
||||
self.rest=false
|
||||
end
|
||||
function c:Pause()
|
||||
self.rest=true
|
||||
end
|
||||
function c:OnStart(func)
|
||||
table.insert(self.funcS,func)
|
||||
end
|
||||
function c:OnStep(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
function c:OnEnd(func)
|
||||
table.insert(self.funcE,func)
|
||||
end
|
||||
function c:Break()
|
||||
self.Active=nil
|
||||
end
|
||||
function c:Reset(n)
|
||||
if n then self.set=n end
|
||||
self.timer=os.clock()
|
||||
self:Resume()
|
||||
end
|
||||
c.updaterate=0
|
||||
c.restRate=0
|
||||
multi:newThread(name,function(ref)
|
||||
while true do
|
||||
if c.rest then
|
||||
thread.sleep(c.restRate)
|
||||
else
|
||||
if os.clock()-c.timer>=c.set then
|
||||
c:Reset()
|
||||
if c.pos==c.start then
|
||||
for fe=1,#c.funcS do
|
||||
c.funcS[fe](c)
|
||||
end
|
||||
end
|
||||
for i=1,#c.func do
|
||||
c.func[i](c.pos,c)
|
||||
end
|
||||
c.pos=c.pos+c.count
|
||||
if c.pos-c.count==c.endAt then
|
||||
c:Pause()
|
||||
for fe=1,#c.funcE do
|
||||
c.funcE[fe](c)
|
||||
end
|
||||
c.pos=c.start
|
||||
end
|
||||
end
|
||||
thread.skip(c.updaterate)
|
||||
end
|
||||
end
|
||||
end)
|
||||
self:create(c)
|
||||
return c
|
||||
end
|
||||
end
|
||||
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
require("multi")
|
||||
local multi = require("multi")
|
||||
os.sleep=love.timer.sleep
|
||||
multi.drawF={}
|
||||
function multi.dManager()
|
||||
@@ -34,3 +34,4 @@ function multi:onDraw(func,i)
|
||||
i=i or 1
|
||||
table.insert(self.drawF,i,func)
|
||||
end
|
||||
return multi
|
||||
+162
-371
@@ -22,41 +22,38 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
require("bin")
|
||||
multi = {}
|
||||
multi.Version = "1.11.0"
|
||||
multi._VERSION = "1.11.0"
|
||||
multi.stage = "stable"
|
||||
multi.__index = multi
|
||||
multi.Mainloop = {}
|
||||
multi.Tasks = {}
|
||||
multi.Tasks2 = {}
|
||||
multi.Garbage = {}
|
||||
multi.ender = {}
|
||||
multi.Children = {}
|
||||
multi.Paused = {}
|
||||
multi.Active = true
|
||||
multi.fps = 60
|
||||
multi.Id = -1
|
||||
multi.Type = "mainprocess"
|
||||
multi.Rest = 0
|
||||
multi._type = type
|
||||
multi.Jobs = {}
|
||||
multi.queue = {}
|
||||
multi.jobUS = 2
|
||||
multi.clock = os.clock
|
||||
multi.time = os.time
|
||||
multi.LinkedPath = multi
|
||||
multi.isRunning = false
|
||||
local multi = {}
|
||||
multi.Version = "2.0.0"
|
||||
multi._VERSION = "2.0.0"
|
||||
multi.stage = "stable"
|
||||
multi.__index = multi
|
||||
multi.Mainloop = {}
|
||||
multi.Garbage = {}
|
||||
multi.ender = {}
|
||||
multi.Children = {}
|
||||
multi.Active = true
|
||||
multi.fps = 60
|
||||
multi.Id = -1
|
||||
multi.Type = "mainprocess"
|
||||
multi.Rest = 0
|
||||
multi._type = type
|
||||
multi.Jobs = {}
|
||||
multi.queue = {}
|
||||
multi.jobUS = 2
|
||||
multi.clock = os.clock
|
||||
multi.time = os.time
|
||||
multi.LinkedPath = multi
|
||||
multi.isRunning = false
|
||||
--Do not change these ever...Any other number will not work (Unless you are using enablePriority2())
|
||||
multi.Priority_Core = 1
|
||||
multi.Priority_High = 4
|
||||
multi.Priority_Above_Normal = 16
|
||||
multi.Priority_Normal = 64
|
||||
multi.Priority_Below_Normal = 256
|
||||
multi.Priority_Low = 1024
|
||||
multi.Priority_Idle = 4096
|
||||
multi.PStep = 1
|
||||
multi.PList={multi.Priority_Core,multi.Priority_High,multi.Priority_Above_Normal,multi.Priority_Normal,multi.Priority_Below_Normal,multi.Priority_Low,multi.Priority_Idle}
|
||||
multi.Priority_Core = 1
|
||||
multi.Priority_High = 4
|
||||
multi.Priority_Above_Normal = 16
|
||||
multi.Priority_Normal = 64
|
||||
multi.Priority_Below_Normal = 256
|
||||
multi.Priority_Low = 1024
|
||||
multi.Priority_Idle = 4096
|
||||
multi.PStep = 1
|
||||
multi.PList = {multi.Priority_Core,multi.Priority_High,multi.Priority_Above_Normal,multi.Priority_Normal,multi.Priority_Below_Normal,multi.Priority_Low,multi.Priority_Idle}
|
||||
--^^^^
|
||||
multi.PriorityTick=1 -- Between 1, 2 and 4
|
||||
multi.Priority=multi.Priority_Core
|
||||
@@ -204,65 +201,6 @@ function multi.executeFunction(name,...)
|
||||
print('Error: Not a function')
|
||||
end
|
||||
end
|
||||
function multi:waitFor(obj)
|
||||
local value=false
|
||||
self.__waiting=function()
|
||||
value=true
|
||||
end
|
||||
obj:connectFinal(self.__waiting)
|
||||
self:hold(function() return value end)
|
||||
end
|
||||
multi.WaitFor=multi.waitFor
|
||||
function multi:reboot(r)
|
||||
local before=collectgarbage('count')
|
||||
multi.Mainloop={}
|
||||
multi.Tasks={}
|
||||
multi.Tasks2={}
|
||||
multi.Garbage={}
|
||||
multi.ender={}
|
||||
multi.Children={}
|
||||
multi.Paused={}
|
||||
multi.Active=true
|
||||
multi.fps=60
|
||||
multi.Id=-1
|
||||
multi.Type='mainprocess'
|
||||
multi.Rest=0
|
||||
multi._type=type
|
||||
multi.Jobs={}
|
||||
multi.queue={}
|
||||
multi.jobUS=2
|
||||
multi.clock=os.clock
|
||||
multi.time=os.time
|
||||
multi.LinkedPath=multi
|
||||
multi.isRunning=false
|
||||
multi.Priority_Core=1
|
||||
multi.Priority_High=4
|
||||
multi.Priority_Above_Normal=16
|
||||
multi.Priority_Normal=64
|
||||
multi.Priority_Below_Normal=256
|
||||
multi.Priority_Low=1024
|
||||
multi.Priority_Idle=4096
|
||||
multi.PList={multi.Priority_Core,multi.Priority_High,multi.Priority_Above_Normal,multi.Priority_Normal,multi.Priority_Below_Normal,multi.Priority_Low,multi.Priority_Idle}
|
||||
multi.PStep=1
|
||||
multi.PriorityTick=1
|
||||
multi.Priority=multi.Priority_Core
|
||||
multi.threshold=256
|
||||
multi.threstimed=.001
|
||||
if r then
|
||||
for i,v in pairs(_G) do
|
||||
if type(i)=='table' then
|
||||
if i.Parent and i.Id and i.Act then
|
||||
_G[i]={}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
collectgarbage()
|
||||
local after=collectgarbage('count')
|
||||
print([[Before rebooting total Ram used was ]]..before..[[Kb
|
||||
After rebooting total Ram used is ]]..after..[[ Kb
|
||||
A total of ]]..(before-after)..[[Kb was cleaned up]])
|
||||
end
|
||||
function multi:getChildren()
|
||||
return self.Mainloop
|
||||
end
|
||||
@@ -287,62 +225,6 @@ function multi:getError()
|
||||
return self.error
|
||||
end
|
||||
end
|
||||
function multi:Do_Order()
|
||||
local Loop=self.Mainloop
|
||||
_G.ID=0
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if Loop[_D].Active then
|
||||
Loop[_D].Id=_D
|
||||
self.CID=_D
|
||||
Loop[_D]:Act()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function multi:enablePriority()
|
||||
function self:Do_Order()
|
||||
local Loop=self.Mainloop
|
||||
_G.ID=0
|
||||
local PS=self
|
||||
for _D=#Loop,1,-1 do
|
||||
for P=1,7 do
|
||||
if Loop[_D] then
|
||||
if (PS.PList[P])%Loop[_D].Priority==0 then
|
||||
if Loop[_D].Active then
|
||||
Loop[_D].Id=_D
|
||||
self.CID=_D
|
||||
Loop[_D]:Act()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function multi:enablePriority2()
|
||||
function self:Do_Order()
|
||||
local Loop=self.Mainloop
|
||||
_G.ID=0
|
||||
local PS=self
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if (PS.PStep)%Loop[_D].Priority==0 then
|
||||
if Loop[_D].Active then
|
||||
Loop[_D].Id=_D
|
||||
self.CID=_D
|
||||
Loop[_D]:Act()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
PS.PStep=PS.PStep+1
|
||||
if PS.PStep>self.Priority_Idle then
|
||||
PS.PStep=1
|
||||
end
|
||||
end
|
||||
end
|
||||
multi.disablePriority=multi.unProtect
|
||||
function multi:benchMark(sec,p,pt)
|
||||
local temp=self:newLoop(function(self,t)
|
||||
if self.clock()-self.init>self.sec then
|
||||
@@ -390,35 +272,6 @@ end
|
||||
function multi:OnMainConnect(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
function multi:protect()
|
||||
function self:Do_Order()
|
||||
local Loop=self.Mainloop
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D]~=nil then
|
||||
Loop[_D].Id=_D
|
||||
self.CID=_D
|
||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||
if err and not(Loop[_D].error) then
|
||||
Loop[_D].error=err
|
||||
self.OnError:Fire(Loop[_D],err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function multi:unProtect()
|
||||
local Loop=self.Mainloop
|
||||
_G.ID=0
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if Loop[_D].Active then
|
||||
Loop[_D].Id=_D
|
||||
self.CID=_D
|
||||
Loop[_D]:Act()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function multi:reallocate(o,n)
|
||||
n=n or #o.Mainloop+1
|
||||
local int=self.Parent
|
||||
@@ -484,10 +337,6 @@ function multi:getType()
|
||||
return self.Type
|
||||
end
|
||||
multi.GetType=multi.getType
|
||||
function multi:Sleep(n)
|
||||
self:hold(n)
|
||||
end
|
||||
multi.sleep=multi.Sleep
|
||||
-- Advance Timer stuff
|
||||
function multi:SetTime(n)
|
||||
if not n then n=3 end
|
||||
@@ -531,8 +380,6 @@ function multi:Pause()
|
||||
self.Active=false
|
||||
if self.Parent.Mainloop[self.Id]~=nil then
|
||||
table.remove(self.Parent.Mainloop,self.Id)
|
||||
table.insert(self.Parent.Paused,self)
|
||||
self.PId=#self.Parent.Paused
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -545,18 +392,12 @@ function multi:Resume()
|
||||
end
|
||||
else
|
||||
if self:isPaused() then
|
||||
table.remove(self.Parent.Paused,self.PId)
|
||||
table.insert(self.Parent.Mainloop,self)
|
||||
self.Id=#self.Parent.Mainloop
|
||||
self.Active=true
|
||||
end
|
||||
end
|
||||
end
|
||||
function multi:resurrect()
|
||||
table.insert(self.Parent.Mainloop,self)
|
||||
self.Active=true
|
||||
end
|
||||
multi.Resurrect=multi.resurrect
|
||||
function multi:Destroy()
|
||||
if self.Type=='process' or self.Type=='mainprocess' then
|
||||
local c=self:getChildren()
|
||||
@@ -575,69 +416,6 @@ function multi:Destroy()
|
||||
self.Active=false
|
||||
end
|
||||
end
|
||||
|
||||
function multi:hold(task)
|
||||
self:Pause()
|
||||
self.held=true
|
||||
if type(task)=='number' then
|
||||
local timer=multi:newTimer()
|
||||
timer:Start()
|
||||
while timer:Get()<task do
|
||||
if love then
|
||||
if love.thread then
|
||||
self.Parent:Do_Order()
|
||||
else
|
||||
self.Parent:lManager()
|
||||
end
|
||||
else
|
||||
self.Parent:Do_Order()
|
||||
end
|
||||
end
|
||||
self:Resume()
|
||||
self.held=false
|
||||
elseif type(task)=='function' then
|
||||
local env=self.Parent:newEvent(task)
|
||||
env:OnEvent(function(envt) envt:Pause() envt.Active=false end)
|
||||
while env.Active do
|
||||
if love then
|
||||
if love.graphics then
|
||||
self.Parent:lManager()
|
||||
else
|
||||
self.Parent:Do_Order()
|
||||
end
|
||||
else
|
||||
self.Parent:Do_Order()
|
||||
end
|
||||
end
|
||||
env:Destroy()
|
||||
self:Resume()
|
||||
self.held=false
|
||||
else
|
||||
print('Error Data Type!!!')
|
||||
end
|
||||
end
|
||||
multi.Hold=multi.hold
|
||||
function multi:oneTime(func,...)
|
||||
if not(self.Type=='mainprocess' or self.Type=='process') then
|
||||
for _k=1,#self.Parent.Tasks2 do
|
||||
if self.Parent.Tasks2[_k]==func then
|
||||
return false
|
||||
end
|
||||
end
|
||||
table.insert(self.Parent.Tasks2,func)
|
||||
func(...)
|
||||
return true
|
||||
else
|
||||
for _k=1,#self.Tasks2 do
|
||||
if self.Tasks2[_k]==func then
|
||||
return false
|
||||
end
|
||||
end
|
||||
table.insert(self.Tasks2,func)
|
||||
func(...)
|
||||
return true
|
||||
end
|
||||
end
|
||||
function multi:Reset(n)
|
||||
self:Resume()
|
||||
end
|
||||
@@ -664,7 +442,6 @@ function multi:newBase(ins)
|
||||
c.ender={}
|
||||
c.important={}
|
||||
c.Id=0
|
||||
c.PId=0
|
||||
c.Act=function() end
|
||||
c.Parent=self
|
||||
c.held=false
|
||||
@@ -682,21 +459,17 @@ function multi:newProcess(file)
|
||||
c.Parent=self
|
||||
c.Active=true
|
||||
c.func={}
|
||||
c.Id=0
|
||||
c.Type='process'
|
||||
c.Mainloop={}
|
||||
c.Tasks={}
|
||||
c.Tasks2={}
|
||||
c.Garbage={}
|
||||
c.Children={}
|
||||
c.Paused={}
|
||||
c.Active=true
|
||||
c.Id=-1
|
||||
c.Rest=0
|
||||
c.Jobs={}
|
||||
c.queue={}
|
||||
c.jobUS=2
|
||||
c.l=self:newLoop(function(self,dt) c:uManager(dt) end)
|
||||
c.l=self:newLoop(function(self,dt) c:uManager() end)
|
||||
c.l:Pause()
|
||||
function c:getController()
|
||||
return c.l
|
||||
@@ -926,7 +699,6 @@ function multi:newJob(func,name)
|
||||
c.Active=true
|
||||
c.func={}
|
||||
c.Id=0
|
||||
c.PId=0
|
||||
c.Parent=self
|
||||
c.Type='job'
|
||||
c.trigfunc=func or function() end
|
||||
@@ -974,111 +746,142 @@ function multi:newCondition(func)
|
||||
return c
|
||||
end
|
||||
multi.NewCondition=multi.newCondition
|
||||
function multi:mainloop()
|
||||
function multi:mainloop(settings)
|
||||
if not multi.isRunning then
|
||||
multi.isRunning=true
|
||||
for i=1,#self.Tasks do
|
||||
self.Tasks[i](self)
|
||||
local protect = false
|
||||
local priority = false
|
||||
if settings then
|
||||
if settings.preLoop then
|
||||
settings.preLoop(self)
|
||||
end
|
||||
protect = settings.protect
|
||||
priority = settings.priority
|
||||
end
|
||||
multi.isRunning=true
|
||||
rawset(self,'Start',self.clock())
|
||||
while self.Active do
|
||||
self:Do_Order()
|
||||
end
|
||||
else
|
||||
return "Already Running!"
|
||||
end
|
||||
end
|
||||
function multi:protectedMainloop()
|
||||
multi:protect()
|
||||
if not multi.isRunning then
|
||||
multi.isRunning=true
|
||||
for i=1,#self.Tasks do
|
||||
self.Tasks[i](self)
|
||||
end
|
||||
rawset(self,'Start',self.clock())
|
||||
while self.Active do
|
||||
self:Do_Order()
|
||||
end
|
||||
else
|
||||
return "Already Running!"
|
||||
end
|
||||
end
|
||||
function multi:unprotectedMainloop()
|
||||
multi:unProtect()
|
||||
if not multi.isRunning then
|
||||
multi.isRunning=true
|
||||
for i=1,#self.Tasks do
|
||||
self.Tasks[i](self)
|
||||
end
|
||||
rawset(self,'Start',self.clock())
|
||||
while self.Active do
|
||||
local Loop=self.Mainloop
|
||||
_G.ID=0
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if Loop[_D].Active then
|
||||
Loop[_D].Id=_D
|
||||
self.CID=_D
|
||||
Loop[_D]:Act()
|
||||
if priority==1 then
|
||||
local Loop=self.Mainloop
|
||||
local PS=self
|
||||
for _D=#Loop,1,-1 do
|
||||
for P=1,7 do
|
||||
if Loop[_D] then
|
||||
if (PS.PList[P])%Loop[_D].Priority==0 then
|
||||
if Loop[_D].Active then
|
||||
self.CID=_D
|
||||
if not protect then
|
||||
Loop[_D]:Act()
|
||||
else
|
||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||
if err then
|
||||
Loop[_D].error=err
|
||||
self.OnError:Fire(Loop[_D],err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
return "Already Running!"
|
||||
end
|
||||
end
|
||||
function multi:prioritizedMainloop1()
|
||||
multi:enablePriority()
|
||||
if not multi.isRunning then
|
||||
multi.isRunning=true
|
||||
for i=1,#self.Tasks do
|
||||
self.Tasks[i](self)
|
||||
end
|
||||
rawset(self,'Start',self.clock())
|
||||
while self.Active do
|
||||
local Loop=self.Mainloop
|
||||
_G.ID=0
|
||||
local PS=self
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if (PS.PList[PS.PStep])%Loop[_D].Priority==0 then
|
||||
elseif priority==2 then
|
||||
local Loop=self.Mainloop
|
||||
local PS=self
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if (PS.PStep)%Loop[_D].Priority==0 then
|
||||
if Loop[_D].Active then
|
||||
self.CID=_D
|
||||
if not protect then
|
||||
Loop[_D]:Act()
|
||||
else
|
||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||
if err then
|
||||
Loop[_D].error=err
|
||||
self.OnError:Fire(Loop[_D],err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
PS.PStep=PS.PStep+1
|
||||
if PS.PStep>self.Priority_Idle then
|
||||
PS.PStep=1
|
||||
end
|
||||
else
|
||||
local Loop=self.Mainloop
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if Loop[_D].Active then
|
||||
Loop[_D].Id=_D
|
||||
self.CID=_D
|
||||
Loop[_D]:Act()
|
||||
if not protect then
|
||||
Loop[_D]:Act()
|
||||
else
|
||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||
if err then
|
||||
Loop[_D].error=err
|
||||
self.OnError:Fire(Loop[_D],err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
PS.PStep=PS.PStep+1
|
||||
if PS.PStep>7 then
|
||||
PS.PStep=1
|
||||
end
|
||||
end
|
||||
else
|
||||
return "Already Running!"
|
||||
end
|
||||
end
|
||||
function multi:prioritizedMainloop2()
|
||||
multi:enablePriority2()
|
||||
if not multi.isRunning then
|
||||
multi.isRunning=true
|
||||
for i=1,#self.Tasks do
|
||||
self.Tasks[i](self)
|
||||
function multi:uManager(settings)
|
||||
if settings then
|
||||
if settings.preLoop then
|
||||
settings.preLoop(self)
|
||||
end
|
||||
rawset(self,'Start',self.clock())
|
||||
while self.Active do
|
||||
end
|
||||
self.uManager=self.uManagerRef
|
||||
end
|
||||
function multi:uManagerRef(settings)
|
||||
if self.Active then
|
||||
if settings.priority==1 then
|
||||
local Loop=self.Mainloop
|
||||
local PS=self
|
||||
for _D=#Loop,1,-1 do
|
||||
for P=1,7 do
|
||||
if Loop[_D] then
|
||||
if (PS.PList[P])%Loop[_D].Priority==0 then
|
||||
if Loop[_D].Active then
|
||||
self.CID=_D
|
||||
if not settings.protect then
|
||||
Loop[_D]:Act()
|
||||
else
|
||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||
if err then
|
||||
Loop[_D].error=err
|
||||
self.OnError:Fire(Loop[_D],err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif settings.priority==2 then
|
||||
local Loop=self.Mainloop
|
||||
_G.ID=0
|
||||
local PS=self
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if (PS.PStep)%Loop[_D].Priority==0 then
|
||||
if Loop[_D].Active then
|
||||
Loop[_D].Id=_D
|
||||
self.CID=_D
|
||||
Loop[_D]:Act()
|
||||
if not settings.protect then
|
||||
Loop[_D]:Act()
|
||||
else
|
||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||
if err then
|
||||
Loop[_D].error=err
|
||||
self.OnError:Fire(Loop[_D],err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1087,28 +890,25 @@ function multi:prioritizedMainloop2()
|
||||
if PS.PStep>self.Priority_Idle then
|
||||
PS.PStep=1
|
||||
end
|
||||
else
|
||||
local Loop=self.Mainloop
|
||||
for _D=#Loop,1,-1 do
|
||||
if Loop[_D] then
|
||||
if Loop[_D].Active then
|
||||
self.CID=_D
|
||||
if not settings.protect then
|
||||
Loop[_D]:Act()
|
||||
else
|
||||
local status, err=pcall(Loop[_D].Act,Loop[_D])
|
||||
if err then
|
||||
Loop[_D].error=err
|
||||
self.OnError:Fire(Loop[_D],err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
return "Already Running!"
|
||||
end
|
||||
end
|
||||
function multi._tFunc(self,dt)
|
||||
for i=1,#self.Tasks do
|
||||
self.Tasks[i](self)
|
||||
end
|
||||
if dt then
|
||||
self.pump=true
|
||||
end
|
||||
self.pumpvar=dt
|
||||
rawset(self,'Start',self.clock())
|
||||
end
|
||||
function multi:uManager(dt)
|
||||
if self.Active then
|
||||
self:oneTime(self._tFunc,self,dt)
|
||||
function self:uManager(dt)
|
||||
self:Do_Order()
|
||||
end
|
||||
self:Do_Order()
|
||||
end
|
||||
end
|
||||
--Core Actors
|
||||
@@ -1311,9 +1111,6 @@ function multi:newStep(start,reset,count,skip)
|
||||
self:create(c)
|
||||
return c
|
||||
end
|
||||
function multi:newTask(func)
|
||||
table.insert(self.Tasks,func)
|
||||
end
|
||||
function multi:newTLoop(func,set)
|
||||
local c=self:newBase()
|
||||
c.Type='tloop'
|
||||
@@ -1608,7 +1405,6 @@ function multi:newTBase(name)
|
||||
c.func={}
|
||||
c.ender={}
|
||||
c.Id=0
|
||||
c.PId=0
|
||||
c.Parent=self
|
||||
c.important={}
|
||||
c.held=false
|
||||
@@ -2003,7 +1799,6 @@ function multi:newThreadedProcess(name)
|
||||
ct.func={}
|
||||
ct.ender={}
|
||||
ct.Id=0
|
||||
ct.PId=0
|
||||
ct.Act=function() end
|
||||
ct.Parent=self
|
||||
ct.held=false
|
||||
@@ -2017,11 +1812,8 @@ function multi:newThreadedProcess(name)
|
||||
c.Id=0
|
||||
c.Type='process'
|
||||
c.Mainloop={}
|
||||
c.Tasks={}
|
||||
c.Tasks2={}
|
||||
c.Garbage={}
|
||||
c.Children={}
|
||||
c.Paused={}
|
||||
c.Active=true
|
||||
c.Id=-1
|
||||
c.Rest=0
|
||||
@@ -2166,7 +1958,6 @@ function multi:ToString()
|
||||
ender=self.ender,
|
||||
-- IDK if these need to be present...
|
||||
-- Id=self.Id,
|
||||
-- PId=self.PId,
|
||||
held=self.held,
|
||||
}
|
||||
else
|
||||
@@ -2179,7 +1970,6 @@ function multi:ToString()
|
||||
ender=self.ender,
|
||||
-- IDK if these need to be present...
|
||||
-- Id=self.Id,
|
||||
-- PId=self.PId,
|
||||
held=self.held,
|
||||
}
|
||||
end
|
||||
@@ -2399,3 +2189,4 @@ multi.load_updater:OnUpdate(function(self)
|
||||
self.Parent.dStepB = os.clock()
|
||||
end
|
||||
end)
|
||||
return multi
|
||||
@@ -32,7 +32,7 @@ end
|
||||
-- Step 1 get lanes
|
||||
lanes=require("lanes").configure()
|
||||
--~ package.path="lua/?/init.lua;lua/?.lua;"..package.path
|
||||
require("multi") -- get it all and have it on all lanes
|
||||
local multi = require("multi") -- get it all and have it on all lanes
|
||||
isMainThread=true
|
||||
function multi:canSystemThread()
|
||||
return true
|
||||
@@ -40,7 +40,6 @@ end
|
||||
function multi:getPlatform()
|
||||
return "lanes"
|
||||
end
|
||||
local multi=multi
|
||||
-- Step 2 set up the linda objects
|
||||
local __GlobalLinda = lanes.linda() -- handles global stuff
|
||||
local __SleepingLinda = lanes.linda() -- handles sleeping stuff
|
||||
@@ -143,4 +142,4 @@ multi.integration={} -- for module creators
|
||||
multi.integration.GLOBAL=GLOBAL
|
||||
multi.integration.THREAD=THREAD
|
||||
require("multi.integration.shared")
|
||||
return {init=function() return GLOBAL,THREAD end}
|
||||
return {init=function() return GLOBAL, THREAD end}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
require("multi.compat.love2d")
|
||||
local multi = require("multi.compat.love2d")
|
||||
function multi:canSystemThread()
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -35,7 +35,7 @@ local function _INIT(luvitThread,timer)
|
||||
end
|
||||
end
|
||||
-- Step 1 get setup threads on luvit... Sigh how do i even...
|
||||
require("multi")
|
||||
local multi = require("multi")
|
||||
isMainThread=true
|
||||
function multi:canSystemThread()
|
||||
return true
|
||||
@@ -123,5 +123,6 @@ local function _INIT(luvitThread,timer)
|
||||
local interval = timer.setInterval(1, function ()
|
||||
multi:uManager()
|
||||
end)
|
||||
return multi
|
||||
end
|
||||
return {init=function(threadHandle,timerHandle) _INIT(threadHandle,timerHandle) return GLOBAL,THREAD end}
|
||||
return {init=function(threadHandle,timerHandle) local multi = _INIT(threadHandle,timerHandle) return GLOBAL, THREAD end}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
local multi = require("multi")
|
||||
local net = require("net")
|
||||
local nGLOBAL = {}
|
||||
local nTHREAD = {}
|
||||
-- This integration is a bit different than the others! Nodes should include both the system threading integration and the network integration. This is because each node has a "main thread" as well. The examples will make this clear!
|
||||
multi.defaultNetworkPort = 30341 -- This port has a meaning to it... convert to base 36 and see what you get.
|
||||
function multi:setdefaultNetworkPort(port)
|
||||
multi.defaultNetworkPort = port
|
||||
end
|
||||
function multi:newNode(name,settings)
|
||||
-- Here we have to use the net library to broadcast our node across the network
|
||||
local port = multi.defaultNetworkPort
|
||||
math.randomseed(os.time())
|
||||
local name = name or multi.randomString(8)
|
||||
if settings then
|
||||
port = settings.port or port
|
||||
-- When I think of more they will be added here
|
||||
end
|
||||
local node = {}
|
||||
node.server = net:newServer(port) -- hosts the node using the default port
|
||||
node.port = multi.defaultNetworkPort
|
||||
-- Lets tell the network we are alive!
|
||||
node.server:broadcast("NODE_"..name)
|
||||
end
|
||||
function multi:newMaster(name,settings) -- You will be able to have more than one master connecting to a node if that is what you want to do. I want you to be able to have the freedom to code any way that you want to code.
|
||||
local master = {}
|
||||
master.clients = net.ClientCache -- Link to the client cache that is created on the net interface
|
||||
net.OnCastedClientInfo(function(client,name,ip,port)
|
||||
print("Found a new node!")
|
||||
-- Do the handshake and start up stuff here
|
||||
end)
|
||||
net:newCastedClients("NODE_(.+)") -- Searches for nodes and connects to them, the master.clients table will contain them by name
|
||||
end
|
||||
-- For the same reasons that the other integrations have this
|
||||
multi.integration.nGLOBAL=nGLOBAL
|
||||
multi.integration.nTHREAD=nTHREAD
|
||||
return {init=function()
|
||||
return nGLOBAL, nTHREAD
|
||||
end}
|
||||
@@ -21,6 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
multi = require("multi")
|
||||
function multi:newSystemThreadedQueue(name) -- in love2d this will spawn a channel on both ends
|
||||
local c={} -- where we will store our object
|
||||
c.name=name -- set the name this is important for the love2d side
|
||||
@@ -182,8 +183,9 @@ function multi:newSystemThreadedConnection(name,protect)
|
||||
table.remove(data,1)-- Remove the first 3 elements
|
||||
table.remove(data,1)-- Remove the first 3 elements
|
||||
con.obj:Fire(unpack(data))
|
||||
multi:newThread("Clean_UP",function()
|
||||
thread.sleep(con.cleanup)
|
||||
local alarm = multi:newAlarm(con.cleanup)
|
||||
alarm:OnRing(function()
|
||||
alarm:Destroy()
|
||||
local dat = con.queueCall:peek()
|
||||
if not dat then return end
|
||||
table.remove(data,1)-- Remove the first 3 elements
|
||||
@@ -218,7 +220,7 @@ function multi:systemThreadedBenchmark(n,p)
|
||||
if multi:getPlatform()=="love2d" then
|
||||
GLOBAL=_G.GLOBAL
|
||||
sThread=_G.sThread
|
||||
end -- we cannot have upvalues... in love2d globals not locals must be used
|
||||
end -- we cannot have upvalues... in love2d globals, not locals must be used
|
||||
queue=sThread.waitFor("QUEUE"):init() -- always wait for when looking for a variable at the start of the thread!
|
||||
multi:benchMark(sThread.waitFor("__SYSTEMBENCHMARK__")):OnBench(function(self,count)
|
||||
queue:push(count)
|
||||
@@ -266,17 +268,14 @@ function multi:newSystemThreadedConsole(name)
|
||||
cc.stream = sThread.waitFor("__SYSTEM_CONSLOE__"):init()
|
||||
else
|
||||
cc.stream = multi:newSystemThreadedQueue("__SYSTEM_CONSLOE__"):init()
|
||||
multi:newThread("Threaded_Console",function()
|
||||
while true do
|
||||
thread.sleep(.001)
|
||||
local data = cc.stream:pop()
|
||||
if data then
|
||||
local dat = table.remove(data,1)
|
||||
if dat=="w" then
|
||||
io.write(unpack(data))
|
||||
elseif dat=="p" then
|
||||
print(unpack(data))
|
||||
end
|
||||
multi:newLoop(function()
|
||||
local data = cc.stream:pop()
|
||||
if data then
|
||||
local dat = table.remove(data,1)
|
||||
if dat=="w" then
|
||||
io.write(unpack(data))
|
||||
elseif dat=="p" then
|
||||
print(unpack(data))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user