5 Commits
Author SHA1 Message Date
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
7 changed files with 335 additions and 28 deletions
+43 -17
View File
@@ -1,9 +1,35 @@
# multi Version: 1.5.0 # multi Version: 1.6.0
Updated from 1.5.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 Updated from 1.4.1
Added: Added:
- An easy way to manage timeouts - An easy way to manage timeouts
- Small bug fixes - Small bug fixes
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>
@@ -68,7 +94,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 +134,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 +157,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 +176,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 +189,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 +236,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 +250,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 +421,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 +489,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 +541,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 +559,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 +657,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)
+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,0}
multi.stage='stable' multi.stage='stable'
multi.__index = multi multi.__index = multi
multi.Mainloop={} multi.Mainloop={}
+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)
+2 -2
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
@@ -74,4 +74,4 @@ function multi:newStep(start,reset,count,skip)
end end
self:create(c) self:create(c)
return c return c
end end
+2 -2
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
@@ -73,4 +73,4 @@ function multi:newTStep(start,reset,count,set)
end end
self:create(c) self:create(c)
return c return c
end end
+4 -5
View File
@@ -1,8 +1,7 @@
package.path="?/init.lua;"..package.path package.path="?/init.lua;"..package.path
require("multi.all") 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. require("multi.compat.backwards[1,5,0]")
process:newTLoop(function(self) multi:newLoop(function(dt,self)
print("Looping every second...") print(dt)
end,1) end)
process:Start() -- starts the process
multi:mainloop() -- start the main runner multi:mainloop() -- start the main runner