Updated to 1.7.3

Changed how you require the library. It was kinda over the top. Coroutine threads may or may not be added into the core. I am still thinking about it.
This commit is contained in:
Ryan 2017-06-23 12:15:46 -04:00
parent 5209ef20a7
commit f1c32efb8b
13 changed files with 304 additions and 470 deletions

View File

@ -1,4 +1,5 @@
# multi Version: 1.7.2 (Taking multi-tasking to the next level)
# multi Version: 1.7.3 (Restructuring the library, but nothing besides how you require it changes!)
View Changes: https://github.com/rayaman/multi#changes
My multitasking library for lua</br>
To install copy the multi folder into your enviroment and you are good to go</br>
@ -13,12 +14,10 @@ Also I will eventually add an example folder with a lot of examples for how you
For real-time assistance with my libraries! A place where you can ask questions and get help with any of my libraries</br>
https://discord.gg/U8UspuA</br>
View Changes: https://github.com/rayaman/multi#changes
Usage:</br>
```lua
--Basic usage Alarms: Have been moved to the core of the library require("multi") would work as well
require("multi.all") -- gets the entire library
require("multi") -- gets the entire library
alarm=multi:newAlarm(3) -- in seconds can go to .001 uses the built in os.clock()
alarm:OnRing(function(a)
print("3 Seconds have passed!")
@ -44,15 +43,15 @@ Check out the wiki for detailed usage, but here are the objects:</br>
- Timer</br>
- Updater</br>
- Thread*</br>
- Trigger**</br>
- Trigger</br>
- Task</br>
- Job</br>
- Function</br>
- Watcher***</br>
#Both a process and queue act like the multi namespace, but allows for some cool things. Because they use the other objects an example on them will be done last</br>
- Watcher</br>
Note: *Both a process and queue act like the multi namespace, but allows for some cool things. Because they use the other objects an example on them will be done last*</br>
*Uses the built in coroutine features of lua, these have an interesting interaction with the other means of multi-tasking</br>
**Triggers are kind of useless after the creation of the Connection</br>
***Watchers have no real purpose as well I made it just because.</br>
Triggers are kind of useless after the creation of the Connection</br>
Watchers have no real purpose as well I made it just because.</br>
# Examples of each object being used</br>
We already showed alarms in action so lets move on to a Loop object
@ -62,7 +61,7 @@ Throughout these examples I am going to do some strange things in order to show
# LOOPS
```lua
-- Loops: Have been moved to the core of the library require("multi") would work as well
require("multi.all") -- gets the entire library
require("multi") -- gets the entire library
count=0
loop=multi:newLoop(function(self,dt) -- dt is delta time and self is a reference to itself
count=count+1
@ -101,7 +100,7 @@ This library aims to be Async like. In reality everything is still on one thread
```lua
-- Events, these were the first objects introduced into the library. I seldomly use them in their pure form though, but later on you'll see their advance uses!
-- Events on there own don't really do much... We are going to need 2 objects at least to get something going
require("multi.all") -- gets the entire library
require("multi") -- gets the entire library
count=0
-- lets use the loop again to add to count!
loop=multi:newLoop(function(self,dt)
@ -119,7 +118,7 @@ Stopped that loop!
# STEPS
```lua
require("multi.all")
require("multi")
-- Steps, are like for loops but non blocking... You can run a loop to infintity and everything will still run I will combine Steps with Ranges in this example.
step1=multi:newStep(1,10,1,0) -- Some explaining is due. Argument 1 is the Start # Argument 2 is the ResetAt # (inclusive) Argument 3 is the count # (in our case we are counting by +1, this can be -1 but you need to adjust your start and resetAt numbers)
-- The 4th Argument is for skipping. This is useful for timing and for basic priority management. A priority management system is included!
@ -180,7 +179,7 @@ Ok 10!</br>
# TLOOPS
```lua
require("multi.all")
require("multi")
-- TLoops are loops that run ever n second. We will also look at condition objects as well
-- Here we are going to modify the old loop to be a little different
count=0
@ -202,7 +201,7 @@ Count is 101!
These are my favorite objects and you'll see why. They are very useful objects for ASync connections!
```lua
require("multi.all")
require("multi")
-- Lets create the events
yawn={} -- ill just leave that there
OnCustomSafeEvent=multi:newConnection(true) -- lets pcall the calls incase something goes wrong defualt
@ -260,7 +259,7 @@ You may think timers should be bundled with alarms, but they are a bit different
# TIMERS
```lua
-- You see the thing is that all time based objects use timers eg. Alarms, TSteps, and Loops. Timers are more low level!
require("multi.all")
require("multi")
local clock = os.clock
function sleep(n) -- seconds
local t0 = clock()
@ -306,7 +305,7 @@ Note: This will make more sense when you run it for your self</br>
# UPDATER
```lua
-- Updaters: Have been moved to the core of the library require("multi") would work as well
require("multi.all")
require("multi")
updater=multi:newUpdater(5) -- really simple, think of a look with the skip feature of a step
updater:OnUpdate(function(self)
--print("updating...")
@ -379,7 +378,7 @@ Notice: Even though I started each bench at the same time the order that they fi
# Processes
A process allows you to group the Actor objects within a controlable interface
```lua
require("multi.all")
require("multi")
proc=multi:newProcess() -- takes an optional file as an argument, but for this example we aren't going to use that
-- a process works just like the multi object!
b=0
@ -456,6 +455,7 @@ end
# Queuer (WIP)
A queuer works just like a process however objects are processed in order that they were created...
```lua
require("multi")
queue = multi:newQueuer()
queue:newAlarm(3):OnRing(function()
print("Ring ring!!!")
@ -509,6 +509,7 @@ function require(path)
_require(path)
end
require("multi.*") -- now I can use that lovely * symbol to require everything
-- Pointless I know I... Don't look at me like that :P
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")
count=0
@ -572,7 +573,7 @@ Count is 100</br>
If you ever wanted to pause a function then great now you can
The uses of the Function object allows one to have a method that can run free in a sense
```lua
require("multi.all")
require("multi")
func=multi:newFunction(function(self,arg1,arg2,...)
self:Pause()
return arg1
@ -591,7 +592,7 @@ Hello3</br>
```lua
-- Works the same as a regular updater!
require("multi.all")
require("multi")
multi:newThreadedUpdater("Test",10000):OnUpdate(function(self)
print(self.pos)
end)
@ -607,7 +608,7 @@ multi:mainloop()
Triggers were what I used before connections became a thing, also Function objects are a lot like triggers and can be paused as well, while triggers cannot...</br>
They are simple to use, but in most cases you are better off using a connection</br>
```lua
require("multi.trigger")
require("multi")
-- They work like connections but can only have one event binded to them
trig=multi:newTrigger(function(self,a,b,c,...)
print(a,b,c,...)
@ -623,8 +624,7 @@ trig:Fire(1,2,3,"Hello",true)
# Tasks
Tasks allow you to run a block of code before the multi mainloops does it thing. Tasks still have a use, but depending on how you program they aren't needed.</br>
```lua
require("multi.loop")
require("multi.task")
require("multi")
multi:newTask(function()
print("Hi!")
end)
@ -647,7 +647,7 @@ As seen in the example above the tasks were done before anything else in the mai
# Jobs
Jobs were a strange feature that was created for throttling connections! When I was building a irc bot around this library I couldn't have messages posting too fast due to restrictions. Jobs allowed functions to be added to a queue that were executed after a certain amount of time has passed
```lua
require("multi.alarm") -- jobs use alarms I am pondering if alarms should be added to the core or if jobs should use timers instead...
require("multi") -- jobs use alarms I am pondering if alarms should be added to the core or if jobs should use timers instead...
-- jobs are built into the core of the library so no need to require them
print(multi:hasJobs())
multi:setJobSpeed(1) -- set job speed to 1 second
@ -681,8 +681,7 @@ Another job!</br>
# Watchers
Watchers allow you to monitor a variable and trigger an event when the variable has changed!
```lua
require("multi.watcher")
require("multi.tloop")
require("multi")
a=0
watcher=multi:newWatcher(_G,"a") -- watch a in the global enviroment
watcher:OnValueChanged(function(self,old,new)
@ -703,7 +702,7 @@ multi:mainloop()
Timeout management
```lua
-- Note: I used a tloop so I could control the output of the program a bit.
require("multi.tloop")
require("multi")
a=0
inc=1 -- change to 0 to see it not met at all, 1 if you want to see the first condition not met but the second and 2 if you want to see it meet the condition on the first go.
loop=multi:newTLoop(function(self)
@ -749,6 +748,22 @@ Looping...</br>
We did it! 1 2 3</br>
# Changes
Updated from 1.7.2 to 1.7.3</br>
Changed how requiring the library works!
`require("multi.all")` Will still work as expected; however, with the exception of threading, compat, and intergrations everything else has been moved into the core of the library.
```lua
-- This means that these are no longer required and will cause an error if done so
require("multi.loop")
require("multi.alarm")
require("multi.updater")
require("multi.tloop")
require("multi.watcher")
require("multi.tstep")
require("multi.step")
require("multi.task")
-- ^ they are all part of the core now
```
Updated from 1.7.1 to 1.7.2</br>
Moved updaters, loops, and alarms into the init.lua file. I consider them core features and they are referenced in the init.lua file so they need to exist there. Threaded versions are still separate though. Added another example file
@ -772,8 +787,7 @@ sThread.sleep(n) -- sleeps for a bit stopping the entire thread from running</br
sThread.hold(n) -- sleeps until a condition is met</br>
```lua
local GLOBAL,sThread=require("multi.intergration.lanesManager").init()
require("multi.alarm")
require("multi.threading")
require("multi.all")
multi:newAlarm(2):OnRing(function(self)
GLOBAL["NumOfCores"]=sThread.getCores()
end)

View File

@ -1 +0,0 @@
require("multi")

View File

@ -1,18 +1,9 @@
require("multi.alarm")
require("multi.function")
require("multi.loop")
require("multi.tloop")
require("multi.step")
require("multi.task")
require("multi")
require("multi.threading")
require("multi.trigger")
require("multi.tstep")
require("multi.updater")
require("multi.watcher")
require("multi.threading.alarm")
require("multi.threading.event")
require("multi.threading.loop")
require("multi.threading.process")
require("multi.threading.step")
require("multi.threading.tstep")
require("multi.threading.updater")
require("multi.threading.updater")

View File

@ -1,42 +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.
]]
require("multi")
function multi:newFunction(func)
local c={}
c.func=func
mt={
__index=multi,
__call=function(self,...) if self.Active then return self:func(...) end local t={...} return "PAUSED" end
}
c.Parent=self
function c:Pause()
self.Active=false
end
function c:Resume()
self.Active=true
end
setmetatable(c,mt)
self:create(c)
return c
end

View File

@ -1115,3 +1115,263 @@ function multi:newLoop(func)
self:create(c)
return c
end
function multi:newFunction(func)
local c={}
c.func=func
mt={
__index=multi,
__call=function(self,...) if self.Active then return self:func(...) end local t={...} return "PAUSED" end
}
c.Parent=self
function c:Pause()
self.Active=false
end
function c:Resume()
self.Active=true
end
setmetatable(c,mt)
self:create(c)
return c
end
function multi:newStep(start,reset,count,skip)
local c=self:newBase()
think=1
c.Type='step'
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: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,self.pos)
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
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.Active=nil
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
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'
c.set=set or 0
c.timer=self:newTimer()
c.life=0
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:Act()
if self.timer:Get()>=self.set then
self.life=self.life+1
for i=1,#self.func do
self.func[i](self,self.life)
end
self.timer:Reset()
end
end
function c:Resume()
self.Parent.Resume(self)
self.timer:Resume()
end
function c:Pause()
self.timer:Pause()
self.Parent.Pause(self)
end
function c:OnLoop(func)
table.insert(self.func,func)
end
self:create(c)
return c
end
function multi:newTrigger(func)
local c={}
c.Type='trigger'
c.trigfunc=func or function() end
function c:Fire(...)
self:trigfunc(...)
end
function c:tofile(path)
local m=bin.new()
m:addBlock(self.Type)
m:addBlock(self.trigfunc)
m:tofile(path)
end
self:create(c)
return c
end
function multi:newTStep(start,reset,count,set)
local c=self:newBase()
think=1
c.Type='tstep'
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=self.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=self.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: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,self.pos)
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
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=self.clock()
self:Resume()
end
self:create(c)
return c
end
function multi:newWatcher(namespace,name)
local function WatcherObj(ns,n)
if self.Type=='queue' then
print("Cannot create a watcher on a queue! Creating on 'multi' instead!")
self=multi
end
local c=self:newBase()
c.Type='watcher'
c.ns=ns
c.n=n
c.cv=ns[n]
function c:OnValueChanged(func)
table.insert(self.func,func)
end
function c:Act()
if self.cv~=self.ns[self.n] then
for i=1,#self.func do
self.func[i](self,self.cv,self.ns[self.n])
end
self.cv=self.ns[self.n]
end
end
self:create(c)
return c
end
if type(namespace)~='table' and type(namespace)=='string' then
return WatcherObj(_G,namespace)
elseif type(namespace)=='table' and (type(name)=='string' or 'number') then
return WatcherObj(namespace,name)
else
print('Warning, invalid arguments! Nothing returned!')
end
end

View File

@ -1 +0,0 @@
require("multi")

View File

@ -1,100 +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.
]]
require("multi")
function multi:newStep(start,reset,count,skip)
local c=self:newBase()
think=1
c.Type='step'
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: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,self.pos)
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
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.Active=nil
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
self:create(c)
return c
end

View File

@ -1,27 +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.
]]
require("multi")
function multi:newTask(func)
table.insert(self.Tasks,func)
end

View File

@ -1,63 +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.
]]
require("multi")
function multi:newTLoop(func,set)
local c=self:newBase()
c.Type='tloop'
c.set=set or 0
c.timer=self:newTimer()
c.life=0
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:Act()
if self.timer:Get()>=self.set then
self.life=self.life+1
for i=1,#self.func do
self.func[i](self,self.life)
end
self.timer:Reset()
end
end
function c:Resume()
self.Parent.Resume(self)
self.timer:Resume()
end
function c:Pause()
self.timer:Pause()
self.Parent.Pause(self)
end
function c:OnLoop(func)
table.insert(self.func,func)
end
self:create(c)
return c
end

View File

@ -1,40 +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.
]]
require("multi")
function multi:newTrigger(func)
local c={}
c.Type='trigger'
c.trigfunc=func or function() end
function c:Fire(...)
self:trigfunc(...)
end
function c:tofile(path)
local m=bin.new()
m:addBlock(self.Type)
m:addBlock(self.trigfunc)
m:tofile(path)
end
self:create(c)
return c
end

View File

@ -1,99 +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.
]]
require("multi")
function multi:newTStep(start,reset,count,set)
local c=self:newBase()
think=1
c.Type='tstep'
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=self.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=self.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: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,self.pos)
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
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=self.clock()
self:Resume()
end
self:create(c)
return c
end

View File

@ -1 +0,0 @@
require("multi")

View File

@ -1,57 +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.
]]
require("multi")
function multi:newWatcher(namespace,name)
local function WatcherObj(ns,n)
if self.Type=='queue' then
print("Cannot create a watcher on a queue! Creating on 'multi' instead!")
self=multi
end
local c=self:newBase()
c.Type='watcher'
c.ns=ns
c.n=n
c.cv=ns[n]
function c:OnValueChanged(func)
table.insert(self.func,func)
end
function c:Act()
if self.cv~=self.ns[self.n] then
for i=1,#self.func do
self.func[i](self,self.cv,self.ns[self.n])
end
self.cv=self.ns[self.n]
end
end
self:create(c)
return c
end
if type(namespace)~='table' and type(namespace)=='string' then
return WatcherObj(_G,namespace)
elseif type(namespace)=='table' and (type(name)=='string' or 'number') then
return WatcherObj(namespace,name)
else
print('Warning, invalid arguments! Nothing returned!')
end
end