7 Commits
Author SHA1 Message Date
server 5edea3a6a4 Typos in readme and example file 2017-06-22 11:34:19 -04:00
server f072c2cfde Updated lanes intergration
It is now at a point where I feel okay with documenting.
2017-06-22 11:32:50 -04:00
server bf011646f7 minibug
lua looks at 'dots' as '/' so they were changed to ','
2017-06-20 23:43:08 -04:00
server 091cd90a0d Changed some features!
Updated the ReadMe to reflect said changes
2017-06-20 23:42:45 -04:00
server acbfef10cc added ned version tag
Changed enough that it merited changing the version to 1.6.0
2017-06-20 23:34:06 -04:00
server aad031062f Changed how steps and loops work
Added multi.compat.backwards[ver]
Require this to be able to use features that were changed from that version.
loops callback args are now: self,dt
steps callback args are now: self,pos
If requiring the backwards compat for the previous version do so after requiring all of the modules you are using.
2017-06-20 23:32:57 -04:00
server 3ff72de1e0 Typos and my promise
Fixed a few typos i saw while reading the Read-Me.
Currently looking over my library to see what can be added or optimized.
Due to making backwards support my #1 priority some changes that I want to make to the loop and step objects will be tricky.
The idea is to change the callback method to give the self object first then the position/index for steps and make loops callback to give the self then the time value. To make this work the user would need to import those new object separately. This though opens a new can of worms though... I'll think about it...
2017-06-20 23:08:50 -04:00
11 changed files with 453 additions and 85 deletions
+91 -19
View File
@@ -1,15 +1,87 @@
# multi Version: 1.5.0 # multi Version: 1.7.0 (Taking multi-tasking to the next level)
Updated from 1.4.1 Updated from 1.6.0 to 1.7.0
Modified: multi.intergration.lanesManager.lua
It is now in a stable and simple state Works with the latest lanes version! Tested with version 3.11 I cannot promise that everything will work with eariler versions. Future versions are good though.
Example Usage:
```lua
local GLOBAL,lthread=require("multi.intergration.lanesManager").init()
require("multi.alarm")
require("multi.threading")
multi:newAlarm(2):OnRing(function(self)
GLOBAL["NumOfCores"]=lthread.getCores()
end)
multi:newAlarm(7):OnRing(function(self)
GLOBAL["AnotherTest"]=true
end)
multi:newAlarm(13):OnRing(function(self)
GLOBAL["FinalTest"]=true
end)
multi:newSystemThread("test",function() -- spawns a thread in another lua process
require("multi.all") -- now you can do all of your coding with the multi library! You could even spawn more threads from here with the intergration. You would need to require the interaction again though
print("Waiting for variable: NumOfCores")
print("Got it: ",lthread.waitFor("NumOfCores"))
lthread.hold(function()
return GLOBAL["AnotherTest"] -- note this would hold the entire systemthread. Spawn a coroutine thread using multi:newThread() or multi:newThreaded...
end)
print("Holding works!")
multi:newThread("tests",function()
thread.hold(function()
return GLOBAL["FinalTest"] -- note this will not hold the entire systemthread. As seen with the TLoop constantly going!
end)
print("Final test works!")
os.exit()
end)
local a=0
multi:newTLoop(function()
a=a+1
print(a)
end,.5)
multi:mainloop()
end)
multi:mainloop()
```
Onec I am happy with the intergration and feel it is ready I will document it better
Updated from 1.5.0 to 1.6.0
Changed: steps and loops
```lua
-- Was
step:OnStep(function(pos,self) -- same goes for tsteps as well
print(pos)
end)
multi:newLoop(function(dt,self)
print(dt)
end)
-- Is now
step:OnStep(function(self,pos) -- same goes for tsteps as well
print(pos)
end)
multi:newLoop(function(self,dt)
print(dt)
end)
```
Reasoning I wanted to keep objects consistant, but a lot of my older libraries use the old way of doing things. Therefore I added a backwards module
```lua
require("multi.all")
require("multi.compat.backwards[1,5,0]") -- allows for the use of features that were scrapped/changed in 1.6.0+
```
Updated from 1.4.1 to 1.5.0
Added: Added:
- An easy way to manage timeouts - An easy way to manage timeouts
- Small bug fixes - Small bug fixes
1.4.1 - First Public release of the library
IMPORTANT:
Every update I make aims to make things simpler more efficent and just better, but a lot of old code, which can be really big, uses a lot of older features. I know the pain of having to rewrite everything. My promise to my library users is that I will always have backwards support for older features! New ways may exist that are quicker and eaiser, but the old features/methods will be supported.
Example at end of the readme Example at end of the readme
My multitasking library for lua</br> My multitasking library for lua</br>
To install copy the multi folder into your enviroment and you are good to go</br> To install copy the multi folder into your enviroment and you are good to go</br>
It is a pure lua binding if you ingore the intergrations (WIP)</br> It is a pure lua binding if you ingore the intergrations (Stable!)</br>
If you find any bugs or have any issues please let me know :) If you find any bugs or have any issues please let me know :)
@@ -68,7 +140,7 @@ Throughout these examples I am going to do some strange things in order to show
-- Loops -- Loops
require("multi.all") -- gets the entire library require("multi.all") -- gets the entire library
count=0 count=0
loop=multi:newLoop(function(dt,self) -- dt is delta time and self is a reference to itself loop=multi:newLoop(function(self,dt) -- dt is delta time and self is a reference to itself
count=count+1 count=count+1
if count > 10 then if count > 10 then
self:Break() -- All methods on the multi objects are upper camel case, where as methods on the multi or process/queuer namespace are lower camel case self:Break() -- All methods on the multi objects are upper camel case, where as methods on the multi or process/queuer namespace are lower camel case
@@ -108,7 +180,7 @@ This library aims to be Async like. In reality everything is still on one thread
require("multi.all") -- gets the entire library require("multi.all") -- gets the entire library
count=0 count=0
-- lets use the loop again to add to count! -- lets use the loop again to add to count!
loop=multi:newLoop(function(dt,self) loop=multi:newLoop(function(self,dt)
count=count+1 count=count+1
end) end)
event=multi:newEvent(function() return count==100 end) -- set the event event=multi:newEvent(function() return count==100 end) -- set the event
@@ -131,7 +203,7 @@ step2=multi:newStep(10,1,-1,1) -- a second step, notice the slight changes!
step1:OnStart(function(self) step1:OnStart(function(self)
print("Step Started!") print("Step Started!")
end) end)
step1:OnStep(function(pos,self) step1:OnStep(function(self,pos)
if pos<=10 then -- what what is this? the step only goes to 10!!! if pos<=10 then -- what what is this? the step only goes to 10!!!
print("Stepping... "..pos) print("Stepping... "..pos)
else else
@@ -150,7 +222,7 @@ end)
-- step2 is bored lets give it some love :P -- step2 is bored lets give it some love :P
step2.range=step2:newRange() -- Set up a range object to have a nested step in a sense! Each nest requires a new range step2.range=step2:newRange() -- Set up a range object to have a nested step in a sense! Each nest requires a new range
-- it is in your interest not to share ranges between objects! You can however do it if it suits your needs though -- it is in your interest not to share ranges between objects! You can however do it if it suits your needs though
step2:OnStep(function(pos,self) step2:OnStep(function(self,pos)
-- for 1=1,math.huge do -- for 1=1,math.huge do
-- print("Haha I am holding the code up because I can!!!") -- print("Haha I am holding the code up because I can!!!")
--end --end
@@ -163,7 +235,7 @@ end)
-- TSteps are just like alarms and steps mixed together, the only difference in construction is the 4th Argument. On a TStep that argument controls time. The defualt is 1 -- TSteps are just like alarms and steps mixed together, the only difference in construction is the 4th Argument. On a TStep that argument controls time. The defualt is 1
-- The Reset(n) works just like you would figure! -- The Reset(n) works just like you would figure!
step3=multi:newTStep(1,10,.5,2) -- lets go from 1 to 10 counting by .5 every 2 seconds step3=multi:newTStep(1,10,.5,2) -- lets go from 1 to 10 counting by .5 every 2 seconds
step3:OnStep(function(pos,self) step3:OnStep(function(self,pos)
print("Ok "..pos.."!") print("Ok "..pos.."!")
end) end)
multi:mainloop() multi:mainloop()
@@ -210,7 +282,7 @@ require("multi.all")
-- Lets create the events -- Lets create the events
yawn={} -- ill just leave that there yawn={} -- ill just leave that there
OnCustomSafeEvent=multi:newConnection(true) -- lets pcall the calls incase something goes wrong defualt OnCustomSafeEvent=multi:newConnection(true) -- lets pcall the calls incase something goes wrong defualt
OnCustomEvent=multi:newConnection(false) -- lets pcall the calls incase something goes wrong OnCustomEvent=multi:newConnection(false) -- lets not pcall the calls and let errors happen... We are good at coding though so lets get a speed advantage by not pcalling. Pcalling is useful for plugins and stuff that may have been coded badly and you can ingore those connections if need be.
OnCustomEvent:Bind(yawn) -- create the connection lookup data in yawn OnCustomEvent:Bind(yawn) -- create the connection lookup data in yawn
-- Lets connect to them, a recent update adds a nice syntax to connect to these -- Lets connect to them, a recent update adds a nice syntax to connect to these
@@ -224,7 +296,7 @@ cd3=OnCustomSafeEvent:Connect(function(arg1,arg2,...)
print("CSE3",arg1,arg2,...) print("CSE3",arg1,arg2,...)
end) -- lets not give this connection a name end) -- lets not give this connection a name
-- no need for connect, but I kept that function because of backwards compatibility -- no need for connect, but I kept that function because of backwards compatibility.
OnCustomEvent(function(arg1,arg2,...) OnCustomEvent(function(arg1,arg2,...)
print(arg1,arg2,...) print(arg1,arg2,...)
end) end)
@@ -395,7 +467,7 @@ updater:OnUpdate(function(self)
b=b+1 b=b+1
end) end)
a=0 -- a counter a=0 -- a counter
loop2=proc:newLoop(function(dt,self) loop2=proc:newLoop(function(self,dt)
print("Lets Go!") print("Lets Go!")
self:hold(3) -- this will keep this object from doing anything! Note: You can only have one hold active at a time! Multiple are possible, but results may not be as they seem see * for how hold works self:hold(3) -- this will keep this object from doing anything! Note: You can only have one hold active at a time! Multiple are possible, but results may not be as they seem see * for how hold works
-- Within a process using hold will keep it alive until the hold is satisified! -- Within a process using hold will keep it alive until the hold is satisified!
@@ -463,10 +535,10 @@ queue = multi:newQueuer()
queue:newAlarm(3):OnRing(function() queue:newAlarm(3):OnRing(function()
print("Ring ring!!!") print("Ring ring!!!")
end) end)
queue:newStep(1,10):OnStep(function(pos,self) queue:newStep(1,10):OnStep(function(self,pos)
print(pos) print(pos)
end) end)
queue:newLoop(function(dt,self) queue:newLoop(function(self,dt)
if dt==3 then if dt==3 then
self:Break() self:Break()
print("Done") print("Done")
@@ -515,17 +587,17 @@ require("multi.*") -- now I can use that lovely * symbol to require everything
test=multi:newThreadedProcess("main") -- you can thread processors and all Actors see note for a list of actors you can thread! test=multi:newThreadedProcess("main") -- you can thread processors and all Actors see note for a list of actors you can thread!
test2=multi:newThreadedProcess("main2") test2=multi:newThreadedProcess("main2")
count=0 count=0
test:newLoop(function(dt,self) test:newLoop(function(self,dt)
count=count+1 count=count+1
thread.sleep(.01) thread.sleep(.01)
end) end)
test2:newLoop(function(dt,self) test2:newLoop(function(self,dt)
print("Hello!") print("Hello!")
thread.sleep(1) -- sleep for some time thread.sleep(1) -- sleep for some time
end) end)
-- threads take a name object then the rest as normal -- threads take a name object then the rest as normal
step=multi:newThreadedTStep("step",1,10) step=multi:newThreadedTStep("step",1,10)
step:OnStep(function(p,self) step:OnStep(function(self,p)
print("step",p) print("step",p)
thread.skip(21) -- skip n cycles thread.skip(21) -- skip n cycles
end) end)
@@ -533,11 +605,11 @@ step:OnEnd(function()
print("Killing thread!") print("Killing thread!")
thread.kill() -- kill the thread thread.kill() -- kill the thread
end) end)
loop=multi:newThreadedLoop("loop",function(dt,self) loop=multi:newThreadedLoop("loop",function(self,dt)
print(dt) print(dt)
thread.sleep(1.1) thread.sleep(1.1)
end) end)
loop2=multi:newThreadedLoop("loop",function(dt,self) loop2=multi:newThreadedLoop("loop",function(self,dt)
print(dt) print(dt)
thread.hold(function() return count>=100 end) thread.hold(function() return count>=100 end)
print("Count is "..count) print("Count is "..count)
@@ -631,7 +703,7 @@ require("multi.task")
multi:newTask(function() multi:newTask(function()
print("Hi!") print("Hi!")
end) end)
multi:newLoop(function(dt,self) multi:newLoop(function(self,dt)
print("Which came first the task or the loop?") print("Which came first the task or the loop?")
self:Break() self:Break()
end) end)
+7
View File
@@ -0,0 +1,7 @@
package.path="?/init.lua;"..package.path
require("multi.all")
require("multi.compat.backwards[1,5,0]")
multi:newLoop(function(dt,self)
print(dt)
end)
multi:mainloop() -- start the main runner
+37
View File
@@ -0,0 +1,37 @@
package.path="?/init.lua;?.lua;"..package.path
local GLOBAL,lthread=require("multi.intergration.lanesManager").init()
require("multi.alarm")
require("multi.threading")
for i,v in pairs(lanes.ABOUT) do print(i,v) end
multi:newAlarm(2):OnRing(function(self)
GLOBAL["NumOfCores"]=lthread.getCores()
end)
multi:newAlarm(7):OnRing(function(self)
GLOBAL["AnotherTest"]=true
end)
multi:newAlarm(13):OnRing(function(self)
GLOBAL["FinalTest"]=true
end)
multi:newSystemThread("test",function() -- spawns a thread in another lua process
require("multi.all") -- now you can do all of your coding with the multi library! You could even spawn more threads from here with the intergration. You would need to require the interaction again though
print("Waiting for variable: NumOfCores")
print("Got it: ",lthread.waitFor("NumOfCores"))
lthread.hold(function()
return GLOBAL["AnotherTest"] -- note this would hold the entire systemthread. Spawn a coroutine thread using multi:newThread() or multi:newThreaded...
end)
print("Holding works!")
multi:newThread("tests",function()
thread.hold(function()
return GLOBAL["FinalTest"] -- note this will not hold the entire systemthread. As seen with the TLoop constantly going!
end)
print("Final test works!")
os.exit()
end)
local a=0
multi:newTLoop(function()
a=a+1
print(a)
end,.5)
multi:mainloop()
end)
multi:mainloop()
+282
View File
@@ -0,0 +1,282 @@
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
+1 -1
View File
@@ -22,7 +22,7 @@ function print(...)
end end
end end
multi = {} multi = {}
multi.Version={1,5,0} multi.Version={1,6,1}
multi.stage='stable' multi.stage='stable'
multi.__index = multi multi.__index = multi
multi.Mainloop={} multi.Mainloop={}
+29 -51
View File
@@ -8,7 +8,7 @@ end
-- Step 1 get lanes -- Step 1 get lanes
lanes=require("lanes").configure() lanes=require("lanes").configure()
package.path="lua/?/init.lua;lua/?.lua;"..package.path package.path="lua/?/init.lua;lua/?.lua;"..package.path
require("multi.all") -- get it all and have it on all lanes require("multi.updater") -- get it all and have it on all lanes
local multi=multi local multi=multi
-- Step 2 set up the linda objects -- Step 2 set up the linda objects
local __GlobalLinda = lanes.linda() -- handles global stuff local __GlobalLinda = lanes.linda() -- handles global stuff
@@ -31,8 +31,21 @@ end
function THREAD.get(name) function THREAD.get(name)
__GlobalLinda:get(name) __GlobalLinda:get(name)
end end
local function randomString(n)
local str = ''
local strings = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
for i=1,n do
str = str..''..strings[math.random(1,#strings)]
end
return str
end
function THREAD.waitFor(name) function THREAD.waitFor(name)
-- local function wait()
math.randomseed(os.time())
__SleepingLinda:receive(.001,randomString(12))
end
repeat wait() until __GlobalLinda:get(name)
return __GlobalLinda:get(name)
end end
function THREAD.testFor(name,val,sym) function THREAD.testFor(name,val,sym)
-- --
@@ -45,63 +58,24 @@ if os.getOS()=="windows" then
else else
THREAD.__CORES=tonumber(io.popen("nproc --all"):read("*n")) THREAD.__CORES=tonumber(io.popen("nproc --all"):read("*n"))
end end
-- Step 4 change the coroutine threading methods to work the same, but with lanes TODO when the lanes scheduler is ready!
function THREAD.skip(n)
-- Do Nothing
end
function THREAD.kill() -- trigger the lane destruction function THREAD.kill() -- trigger the lane destruction
-- coroutine.yield({"_kill_",":)"}) -- coroutine.yield({"_kill_",":)"})
end end
--[[ Step 5 We need to get sleeping working so we need a lane to handle timing... We want idle wait not busy wait --[[ Step 4 We need to get sleeping working to handle timing... We want idle wait, not busy wait
Idle wait keeps the CPU running better where busy wait wastes CPU cycles... Lanes does not have a sleep method Idle wait keeps the CPU running better where busy wait wastes CPU cycles... Lanes does not have a sleep method
however, a linda recieve will in fact be a idle wait! So when wait is called we can pack the cmd up and send it to however, a linda recieve will in fact be a idle wait! So we use that and wrap it in a nice package]]
the sleeping thread manager to send the variable for the other thread to consume, sending only after a certain time has passed!
]]
local function randomString(n)
local str = ''
local strings = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
for i=1,n do
str = str..''..strings[math.random(1,#strings)]
end
return str
end
function THREAD.sleep(n) function THREAD.sleep(n)
math.randomseed(os.time()) math.randomseed(os.time())
local randKey=randomString(12) -- generate a random string a-Z and 0-9 __SleepingLinda:receive(n,randomString(12))
__SleepingLinda:send("tired","SLEEP|"..randKey.."|"..tostring(n)) -- send the data that needs to be managed
local dat=__SleepingLinda:receive(randKey)
return dat
end end
function THREAD.hold(n) function THREAD.hold(n)
while not(n()) do local function wait()
-- holding math.randomseed(os.time())
__SleepingLinda:receive(.001,randomString(12))
end end
repeat wait() until n()
end end
-- start the time manager lane -- Step 5 Basic Threads!
--~ lanes.gen("*", function()
--~ local timers={}
--~ while true do -- forever loop!
--~ local data=__SleepingLinda:receive(.001,"tired") -- timeout after .001 seconds and handle the other stuff
--~ if data then -- the .001 is an entarnal timer that keeps this thread from using too much CPU as well!
--~ print(data)
--~ local cmd,key,sec=data:match("(%S-)|(%S-)|(.+)")
--~ if cmd=="SLEEP" then
--~ print("GOT!")
--~ timers[#timers+1]={os.clock()+tonumber(sec),key}
--~ --__SleepingLinda:set()
--~ elseif cmd=="audit" then
--~ --
--~ end
--~ end
--~ for i=1,#timers do
--~ if os.clock()>=timers[i][1] then
--~ __SleepingLinda:send(timers[i][2],true)
--~ table.remove(timers,i)
--~ end
--~ end
--~ end
--~ end)() -- The global timer is now activated, and it works great!
-- Step 6 Basic Threads!
function multi:newSystemThread(name,func) function multi:newSystemThread(name,func)
local c={} local c={}
local __self=c local __self=c
@@ -123,5 +97,9 @@ function multi:newSystemThread(name,func)
end) end)
return c return c
end end
_G["GLOBAL"]=GLOBAL print("Intergrated Lanes!")
_G["__GlobalLinda"]=__GlobalLinda multi.intergration={} -- for module creators
multi.intergration.lanes={} -- for module creators
multi.intergration.lanes.GLOBAL=GLOBAL -- for module creators
multi.intergration.lanes.THREAD=THREAD -- for module creators
return {init=function() return GLOBAL,THREAD end}
+1 -1
View File
@@ -15,7 +15,7 @@ function multi:newLoop(func)
end end
function c:Act() function c:Act()
for i=1,#self.func do for i=1,#self.func do
self.func[i](self.Parent.clock()-self.Start,self) self.func[i](self,self.Parent.clock()-self.Start)
end end
end end
function c:OnLoop(func) function c:OnLoop(func)
+1 -1
View File
@@ -35,7 +35,7 @@ function multi:newStep(start,reset,count,skip)
end end
end end
for i=1,#self.func do for i=1,#self.func do
self.func[i](self.pos,self) self.func[i](self,self.pos)
end end
self.pos=self.pos+self.count self.pos=self.pos+self.count
if self.pos-self.count==self.endAt then if self.pos-self.count==self.endAt then
+1 -1
View File
@@ -42,7 +42,7 @@ function multi:newTStep(start,reset,count,set)
end end
end end
for i=1,#self.func do for i=1,#self.func do
self.func[i](self.pos,self) self.func[i](self,self.pos)
end end
self.pos=self.pos+self.count self.pos=self.pos+self.count
if self.pos-self.count==self.endAt then if self.pos-self.count==self.endAt then
-8
View File
@@ -1,8 +0,0 @@
package.path="?/init.lua;"..package.path
require("multi.all")
process=multi:newProcess() -- this can also load a file, to keep things really organized, I will show a simple example first then show the same thing being done within another file.
process:newTLoop(function(self)
print("Looping every second...")
end,1)
process:Start() -- starts the process
multi:mainloop() -- start the main runner