Updated code

This commit is contained in:
Ryan Ward 2021-12-24 22:47:38 -05:00
parent 91d0b5f7be
commit 544aa78d70
2 changed files with 355 additions and 355 deletions

View File

@ -3,6 +3,97 @@ Table of contents
---
[Update 15.1.0 - Hold the thread!](#update-1510---hold-the-thread)</br>[Update 15.0.0 - The art of faking it](#update-1500---the-art-of-faking-it)</br>[Update 14.2.0 - Bloatware Removed](#update-1420---bloatware-removed)</br>[Update 14.1.0 - A whole new world of possibilities](#update-1410---a-whole-new-world-of-possibilities)</br>[Update 14.0.0 - Consistency, Additions and Stability](#update-1400---consistency-additions-and-stability)</br>[Update 13.1.0 - Bug fixes and features added](#update-1310---bug-fixes-and-features-added)</br>[Update 13.0.0 - Added some documentation, and some new features too check it out!](#update-1300---added-some-documentation-and-some-new-features-too-check-it-out)</br>[Update 12.2.2 - Time for some more bug fixes!](#update-1222---time-for-some-more-bug-fixes)</br>[Update 12.2.1 - Time for some bug fixes!](#update-1221---time-for-some-bug-fixes)</br>[Update 12.2.0 - The chains of binding](#update-1220---the-chains-of-binding)</br>[Update 12.1.0 - Threads just can't hold on anymore](#update-1210---threads-just-cant-hold-on-anymore)</br>[Update: 12.0.0 - Big update (Lots of additions some changes)](#update-1200---big-update-lots-of-additions-some-changes)</br>[Update: 1.11.1 - Small Clarification on Love](#update-1111---small-clarification-on-love)</br>[Update: 1.11.0](#update-1110)</br>[Update: 1.10.0](#update-1100)</br>[Update: 1.9.2](#update-192)</br>[Update: 1.9.1 - Threads can now argue](#update-191---threads-can-now-argue)</br>[Update: 1.9.0](#update-190)</br>[Update: 1.8.7](#update-187)</br>[Update: 1.8.6](#update-186)</br>[Update: 1.8.5](#update-185)</br>[Update: 1.8.4](#update-184)</br>[Update: 1.8.3 - Mainloop recieves some needed overhauling](#update-183---mainloop-recieves-some-needed-overhauling)</br>[Update: 1.8.2](#update-182)</br>[Update: 1.8.1](#update-181)</br>[Update: 1.7.6](#update-176)</br>[Update: 1.7.5](#update-175)</br>[Update: 1.7.4](#update-174)</br>[Update: 1.7.3](#update-173)</br>[Update: 1.7.2](#update-172)</br>[Update: 1.7.1 - Bug Fixes Only](#update-171---bug-fixes-only)</br>[Update: 1.7.0 - Threading the systems](#update-170---threading-the-systems)</br>[Update: 1.6.0](#update-160)</br>[Update: 1.5.0](#update-150)</br>[Update: 1.4.1 (4/10/2017) - First Public release of the library](#update-141-4102017---first-public-release-of-the-library)</br>[Update: 1.4.0 (3/20/2017)](#update-140-3202017)</br>[Update: 1.3.0 (1/29/2017)](#update-130-1292017)</br>[Update: 1.2.0 (12.31.2016)](#update-120-12312016)</br>[Update: 1.1.0](#update-110)</br>[Update: 1.0.0](#update-100)</br>[Update: 0.6.3](#update-063)</br>[Update: 0.6.2](#update-062)</br>[Update: 0.6.1-6](#update-061-6)</br>[Update: 0.5.1-6](#update-051-6)</br>[Update: 0.4.1](#update-041)</br>[Update: 0.3.0 - The update that started it all](#update-030---the-update-that-started-it-all)</br>[Update: EventManager 2.0.0](#update-eventmanager-200)</br>[Update: EventManager 1.2.0](#update-eventmanager-120)</br>[Update: EventManager 1.1.0](#update-eventmanager-110)</br>[Update: EventManager 1.0.0 - Error checking](#update-eventmanager-100---error-checking)</br>[Version: EventManager 0.0.1 - In The Beginning things were very different](#version-eventmanager-001---in-the-beginning-things-were-very-different)
# Update 15.2.0 - Upgrade Complete
Full Update Showcase
```lua
```
Added:
---
- multi:newTLoop() member functions
- `Loop:Set(set)` - Sets the time to wait for the TLoop
- multi:newStep() member functions
- `Step:Count(count)` - Sets the amount a step should count by
- multi:newTStep() member functions
- `TStep:Set(set)` - Sets the time to wait for the TStep
Changed:
---
- Connection Objects now pass on the parent object if created on a multiobj. This was to allow chaining to work properly with the new update
```lua
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
multi,thread = require("multi"):init()
loop = multi:newTLoop()
function loop:testing()
print("testing haha")
end
loop:Set(1)
t = loop:OnLoop(function()
print("Looping...")
end):testing()
multi:mainloop()
--[[Returns as expected:
testing haha
Looping...
Looping...
Looping...
...
Looping...
Looping...
Looping...
]]
```
While chaining on the OnSomeEventMethod() wasn't really a used feature, I still wanted to keep it just incase someone was relying on this working. And it does have it uses
- All Multi Objects now use Connection objects
`multiobj:OnSomeEvent(func)` or `multiobj.OnSomeEvent(func)`
- Connection Objects no longer Fire with syntax sugar when attached to an object:
`multiobj:OnSomeEvent(arg1,arg2.arg3)` No longer triggers the Fire event. As part of the update to make all objects use connections internally this little used feature had to be scrapped!
- multi:newTStep now derives it's functionality from multi:newStep (Cut's down on code length a bit)
-
### Developer Note:
Connections are some of the most complex objects that this library has outside of some of the system threaded stuff. I tend to add features to connection objects quite often. Just last update connections can be "added" together creating a temp connection that only triggers when all of the added connections got triggered as well. Thinking about the possibilities this could give developers using the library I had to changed the base classes to use connections.
The best part about this is that connections allow for greater control over an object's events. You can add and remove events that have been connected to as well as a lot of other things. Reference the documentation [here](./Documentation.md#non-actor-connections)
Removed:
---
Fixed:
---
- [Issue](https://github.com/rayaman/multi/issues/30) with Lanes crashing the lua state. Fixed it with pcall
- [Issue](https://github.com/rayaman/multi/issues/29) where System threaded functions not up to date with threaded functions
ToDo:
---
# Update 15.1.0 - Hold the thread!
Full Update Showcase
@ -98,9 +189,11 @@ multi:mainloop()
Added:
---
## multi:newSystemThreadedJobQueue(n) isEmpty()
- returns true if the queue is empty, false if there are items in the queue.
- multi:newSystemThreadedJobQueue(n)
`queue:isEmpty()`
Returns true if the queue is empty, false if there are items in the queue.
**Note:** a queue might be empty, but the job may still be running and not finished yet! Also if a registered function is called directly instead of pushed, it will not reflect inside the queue until the next cycle!
@ -413,6 +506,7 @@ multi:mainloop()
Note:
---
This was supposed to be released over a year ago, but work and other things got in my way. Pesudo Threading now works. The goal of this is so you can write modules that can be scaled up to utilize threading features when available.
Added:
---
- multi:newISOThread(name,func,env)
@ -790,15 +884,18 @@ Added:
-- If the created function encounters an error, it will return nil, the error message!
- special variable multi.NIL was added to allow error handling in threaded functions.
-- multi.NIL can be used in to force a nil value when using thread.hold()
- All functions created in the root of a thread are now converted to threaded functions, which allow for wait and connect features. **Note:** these functions are local to the function! And are only converted if they aren't set as local! Otherwise the function
- All functions created in the root of a thread are now converted to threaded functions, which allow for wait and connect features.
**Note:** these functions are local to the function! And are only converted if they aren't set as local! Otherwise the function is converted into a threaded function
- lanes threads can now have their priority set using: sThread.priority =
-- thread.Priority_Core
-- thread.Priority_High
-- thread.Priority_Above_Normal
-- thread.Priority_Normal
-- thread.Priority_Below_Normal
-- thread.Priority_Low
-- thread.Priority_Idle
- thread.Priority_Core
- thread.Priority_High
- thread.Priority_Above_Normal
- thread.Priority_Normal
- thread.Priority_Below_Normal
- thread.Priority_Low
- thread.Priority_Idle
- thread.hold() and multi.hold() now accept connections as an argument. See example below
```lua
@ -1203,7 +1300,7 @@ L: 6543
I: 1635
~n=n*4
```
P3 Ignores using a basic funceion and instead bases its processing time on the amount of cpu time is there. If cpu-time is low and a process is set at a lower priority it will get its time reduced. There is no formula, at idle almost all process work at the same speed!
P3 Ignores using a basic function and instead bases its processing time on the amount of cpu time is there. If cpu-time is low and a process is set at a lower priority it will get its time reduced. There is no formula, at idle almost all process work at the same speed!
```
C: 2120906
H: 2120906
@ -1218,10 +1315,10 @@ Auto Priority works by seeing what should be set high or low. Due to lua not hav
**Improved:**
- Performance at the base level has been doubled! On my machine benchmark went from ~9mil to ~20 mil steps/s.
Note: If you write slow code this library's improbements wont make much of a difference.
Note: If you write slow code this library's improvements wont make much of a difference.
- Loops have been optimised as well! Being the most used objects I felt they needed to be made as fast as possible
I usually give an example of the changes made, but this time I have an explantion for multi.nextStep(). It's not an entirely new feature since multi:newJob() does something like this, but is completely different. nextStep addes a function that is executed first on the next step. If multiple things are added to next step, then they will be executed in the order that they were added.
I usually give an example of the changes made, but this time I have an explantion for `multi.nextStep()`. It's not an entirely new feature since multi:newJob() does something like this, but is completely different. nextStep adds a function that is executed first on the next step. If multiple things are added to next step, then they will be executed in the order that they were added.
Note:
The upper limit of this libraries performance on my machine is ~39mil. This is simply a while loop counting up from 0 and stops after 1 second. The 20mil that I am currently getting is probably as fast as it can get since its half of the max performance possible, and each layer I have noticed that it doubles complexity. Throughout the years with this library I have seen massive improvements in speed. In the beginning we had only ~2000 steps per second. Fast right? then after some tweaks we went to about 300000 steps per second, then 600000. Some more tweaks brought me to ~1mil steps per second, then to ~4 mil then ~9 mil and now finally ~20 mil... the doubling effect that i have now been seeing means that odds are I have reach the limit. I will aim to add more features and optimize individule objects. If its possible to make the library even faster then I will go for it.
@ -1235,7 +1332,7 @@ Fixed:
Changed:
---
- thread.hold() now returns the arguments that were pass by the event function
- event objexts now contain a copy of what returns were made by the function that called it in a table called returns that exist inside of the object
- event objects now contain a copy of what returns were made by the function that called it in a table called returns that exist inside of the object
```lua
package.path="?/init.lua;?.lua;"..package.path
@ -1935,41 +2032,6 @@ GLOBAL,sThread=require("multi.integration.loveManager").init() -- load the love2
-- Also, each thread has a .1 second delay! This is used to generate a random value for each thread!
require("core.GuiManager")
gui.ff.Color=Color.Black
function multi:newSystemThreadedQueue(name) -- in love2d this will spawn a channel on both ends
local c={}
c.name=name
if love then
if love.thread then
function c:init()
self.chan=love.thread.getChannel(self.name)
function self:push(v)
self.chan:push(v)
end
function self:pop()
return self.chan:pop()
end
GLOBAL[self.name]=self
return self
end
return c
else
error("Make sure you required the love.thread module!")
end
else
c.linda=lanes.linda()
function c:push(v)
self.linda:send("Q",v)
end
function c:pop()
return ({self.linda:receive(0,"Q")})[2]
end
function c:init()
return self
end
GLOBAL[name]=c
end
return c
end
queue=multi:newSystemThreadedQueue("QUEUE"):init()
queue:push("This is a test")
queue:push("This is a test2")
@ -2251,7 +2313,7 @@ Change:
Upcomming:
---
- Threaded objects wrapped in corutines, so you can hold/sleep without problems!
- Threaded objects wrapped in coroutines, so you can hold/sleep without problems!
# Update: 1.4.0 (3/20/2017)
Added:
@ -2325,8 +2387,10 @@ Added:
# Update: 1.2.0 (12.31.2016)
Added:
---
- connectionobj.getConnection(name) — returns a list of an instance (or instances) of a single connect made with connectionobj:connect(func,name) or connectionobj(func,name) if you can orginize data before hand you can route info to certain connections thus saving a lot of cpu time.
- connectionobj.getConnection(name) — returns a list of an instance (or instances) of a single connect made with connectionobj:connect(func,name) or connectionobj(func,name) if you can organize data before hand you can route info to certain connections thus saving a lot of cpu time.
**NOTE:** Only one name per each connection... you can't have 2 of the same names in a dictonary... the last one will be used
Changed:
---
- Started keeping track of dates
@ -2385,6 +2449,7 @@ Changed:
Changed:
---
- Everything, complete restructuring of the library from function based to object based. Resembles the modern version of the library
Added:
---
- Love2d support basic

View File

@ -198,214 +198,7 @@ function multi:getTasksDetails(t)
end
--Helpers
-- Used with ISO Threads
local function isolateFunction(func,env)
local dmp = string.dump(func)
local env = env or {}
if setfenv then
local f = loadstring(dmp,"IsolatedThread_PesudoThreading")
setfenv(f,env)
return f
else
return load(dmp,"IsolatedThread_PesudoThreading","bt",env)
end
end
function multi:Break()
self:Pause()
self.Active=nil
for i=1,#self.ender do
if self.ender[i] then
self.ender[i](self)
end
end
end
function multi:OnBreak(func)
table.insert(self.ender,func)
end
function multi:isPaused()
return not(self.Active)
end
function multi:isActive()
return self.Active
end
function multi:getType()
return self.Type
end
-- Advance Timer stuff
function multi:SetTime(n)
if not n then n=3 end
local c=self:newBase()
c.Type='timemaster'
c.timer=self:newTimer()
c.timer:Start()
c.set=n
c.link=self
self._timer=c.timer
function c:Act()
if self.timer:Get()>=self.set then
self.link:Pause()
for i=1,#self.link.funcTM do
self.link.funcTM[i](self.link)
end
self:Destroy()
end
end
return self
end
function multi:ResolveTimer(...)
self._timer:Pause()
for i=1,#self.funcTMR do
self.funcTMR[i](self,...)
end
self:Pause()
return self
end
function multi:OnTimedOut(func)
self.funcTM[#self.funcTM+1]=func
return self
end
function multi:OnTimerResolved(func)
self.funcTMR[#self.funcTMR+1]=func
return self
end
-- Timer stuff done
multi.PausedObjects = {}
function multi:Pause()
if self.Type=='rootprocess' then
multi.print("You cannot pause the main process. Doing so will stop all methods and freeze your program! However if you still want to use multi:_Pause()")
else
self.Active=false
local loop = self.Parent.Mainloop
for i=1,#loop do
if loop[i] == self then
multi.PausedObjects[self] = true
table.remove(loop,i)
break
end
end
end
return self
end
function multi:Resume()
if self.Type=='process' or self.Type=='rootprocess' then
self.Active=true
local c=self:getChildren()
for i=1,#c do
c[i]:Resume()
end
else
if self.Active==false then
table.insert(self.Parent.Mainloop,self)
multi.PausedObjects[self] = nil
self.Active=true
end
end
return self
end
function multi:Destroy()
if self.Type=='process' or self.Type=='rootprocess' then
local c=self:getChildren()
for i=1,#c do
self.OnObjectDestroyed:Fire(c[i])
c[i]:Destroy()
end
local new = {}
for th,proc in pairs(globalThreads) do
if proc == self then
th:Destroy()
table.remove(globalThreads,th)
else
new[th]=proc
end
end
globalThreads = new
multi.setType(self,multi.DestroyedObj)
else
for i=1,#self.Parent.Mainloop do
if self.Parent.Mainloop[i]==self then
self.Parent.OnObjectDestroyed:Fire(self)
table.remove(self.Parent.Mainloop,i)
self.Destroyed = true
break
end
end
multi.setType(self,multi.DestroyedObj)
end
return self
end
function multi:Reset(n)
self:Resume()
return self
end
function multi:isDone()
return self.Active~=true
end
function multi:create(ref)
multi.OnObjectCreated:Fire(ref,self)
return self
end
function multi:setName(name)
self.Name = name
return self
end
--Constructors [CORE]
local _tid = 0
function multi:newBase(ins)
if not(self.Type=='rootprocess' or self.Type=='process' or self.Type=='queue' or self.Type == 'sandbox') then error('Can only create an object on multi or an interface obj') return false end
local c = {}
if self.Type=='process' or self.Type=='queue' or self.Type=='sandbox' then
setmetatable(c, {__index = multi})
else
setmetatable(c, {__index = multi})
end
c.Active=true
c.func={}
c.funcTM={}
c.funcTMR={}
c.ender={}
c.TID = _tid
c.Act=function() end
c.Parent=self
c.creationTime = os.clock()
if ins then
table.insert(self.Mainloop,ins,c)
else
table.insert(self.Mainloop,c)
end
_tid = _tid + 1
return c
end
function multi:newConnector()
local c = {Type = "connector"}
return c
end
local CRef = {
Fire = function() end
}
local ignoreconn = true
function multi:newConnection(protect,func,kill)
local c={}
c.callback = func
@ -416,7 +209,9 @@ function multi:newConnection(protect,func,kill)
if type(t)=="table" then
for i,v in pairs(t) do
if v==self then
return self:Fire(select(2,...))
local ref = self:connect(select(2,...))
ref.root_link = select(1,...)
return ref
end
end
return self:connect(...)
@ -535,9 +330,23 @@ function multi:newConnection(protect,func,kill)
return self:connect(...)
end
}
setmetatable(temp,{__call=function(s,...)
return self:connect(...)
end})
setmetatable(temp,{
__call=function(s,...)
return self:connect(...)
end,
__index = function(t,k)
if rawget(t,"root_link") then
return t["root_link"][k]
end
return nil
end,
__newindex = function(t,k,v)
if rawget(t,"root_link") then
t["root_link"][k] = v
end
rawset(t,k,v)
end,
})
function temp:Fire(...)
if self.Parent.lock then return end
if self.Parent.protect then
@ -597,6 +406,190 @@ function multi:newConnection(protect,func,kill)
return c
end
-- Used with ISO Threads
local function isolateFunction(func,env)
local dmp = string.dump(func)
local env = env or {}
if setfenv then
local f = loadstring(dmp,"IsolatedThread_PesudoThreading")
setfenv(f,env)
return f
else
return load(dmp,"IsolatedThread_PesudoThreading","bt",env)
end
end
function multi:Break()
self:Pause()
self.Active=nil
self.OnBreak:Fire(self)
end
function multi:isPaused()
return not(self.Active)
end
function multi:isActive()
return self.Active
end
function multi:getType()
return self.Type
end
-- Advance Timer stuff
function multi:SetTime(n)
if not n then n=3 end
local c=self:newBase()
c.Type='timemaster'
c.timer=self:newTimer()
c.timer:Start()
c.set=n
c.link=self
c.OnTimedOut = multi:newConnection()
c.OnTimerResolved = multi:newConnection()
self._timer=c.timer
function c:Act()
if self.timer:Get()>=self.set then
self.link:Pause()
self.OnTimedOut:Fire(self.link)
self:Destroy()
end
end
return self
end
function multi:ResolveTimer(...)
self._timer:Pause()
self.OnTimerResolved:Fire(self,...)
self:Pause()
return self
end
-- Timer stuff done
multi.PausedObjects = {}
function multi:Pause()
if self.Type=='rootprocess' then
multi.print("You cannot pause the main process. Doing so will stop all methods and freeze your program! However if you still want to use multi:_Pause()")
else
self.Active=false
local loop = self.Parent.Mainloop
for i=1,#loop do
if loop[i] == self then
multi.PausedObjects[self] = true
table.remove(loop,i)
break
end
end
end
return self
end
function multi:Resume()
if self.Type=='process' or self.Type=='rootprocess' then
self.Active=true
local c=self:getChildren()
for i=1,#c do
c[i]:Resume()
end
else
if self.Active==false then
table.insert(self.Parent.Mainloop,self)
multi.PausedObjects[self] = nil
self.Active=true
end
end
return self
end
function multi:Destroy()
if self.Type=='process' or self.Type=='rootprocess' then
local c=self:getChildren()
for i=1,#c do
self.OnObjectDestroyed:Fire(c[i])
c[i]:Destroy()
end
local new = {}
for th,proc in pairs(globalThreads) do
if proc == self then
th:Destroy()
table.remove(globalThreads,th)
else
new[th]=proc
end
end
globalThreads = new
multi.setType(self,multi.DestroyedObj)
else
for i=1,#self.Parent.Mainloop do
if self.Parent.Mainloop[i]==self then
self.Parent.OnObjectDestroyed:Fire(self)
table.remove(self.Parent.Mainloop,i)
self.Destroyed = true
break
end
end
multi.setType(self,multi.DestroyedObj)
end
return self
end
function multi:Reset(n)
self:Resume()
return self
end
function multi:isDone()
return self.Active~=true
end
function multi:create(ref)
self.OnObjectCreated:Fire(ref,self)
return self
end
function multi:setName(name)
self.Name = name
return self
end
--Constructors [CORE]
local _tid = 0
function multi:newBase(ins)
if not(self.Type=='rootprocess' or self.Type=='process' or self.Type=='queue' or self.Type == 'sandbox') then error('Can only create an object on multi or an interface obj') return false end
local c = {}
if self.Type=='process' or self.Type=='queue' or self.Type=='sandbox' then
setmetatable(c, {__index = multi})
else
setmetatable(c, {__index = multi})
end
c.Active=true
c.func={}
c.funcTM={}
c.funcTMR={}
c.OnBreak = multi:newConnection()
c.TID = _tid
c.Act=function() end
c.Parent=self
c.creationTime = os.clock()
if ins then
table.insert(self.Mainloop,ins,c)
else
table.insert(self.Mainloop,c)
end
_tid = _tid + 1
return c
end
function multi:newConnector()
local c = {Type = "connector"}
return c
end
local CRef = {
Fire = function() end
}
multi.OnObjectCreated=multi:newConnection()
multi.OnObjectDestroyed=multi:newConnection()
multi.OnLoad = multi:newConnection(nil,nil,true)
@ -643,19 +636,14 @@ function multi:newEvent(task)
if t[1] then
self:Pause()
self.returns = t
for _E=1,#self.func do
self.func[_E](self)
end
c.OnEvent:Fire(self)
end
end
function c:SetTask(func)
self.Task=func
return self
end
function c:OnEvent(func)
table.insert(self.func,func)
return self
end
c.OnEvent = self:newConnection()
self:setPriority("core")
multi:create(c)
return c
@ -668,9 +656,7 @@ function multi:newUpdater(skip)
function c:Act()
if self.pos>=self.skip then
self.pos=0
for i=1,#self.func do
self.func[i](self)
end
self.OnUpdate:Fire(self)
end
self.pos=self.pos+1
end
@ -678,7 +664,7 @@ function multi:newUpdater(skip)
self.skip=n
return self
end
c.OnUpdate=self.OnMainConnect
c.OnUpdate=self:newConnection()
multi:create(c)
return c
end
@ -693,9 +679,7 @@ function multi:newAlarm(set)
if clock()-t>=self.set then
self:Pause()
self.Active=false
for i=1,#self.func do
self.func[i](self)
end
self.OnRing:Fire(self)
t = clock()
end
end
@ -710,10 +694,7 @@ function multi:newAlarm(set)
t = clock()
return self
end
function c:OnRing(func)
table.insert(self.func,func)
return self
end
c.OnRing = self:newConnection()
function c:Pause()
count = clock()
self.Parent.Pause(self)
@ -726,18 +707,12 @@ function multi:newLoop(func)
local c=self:newBase()
c.Type='loop'
local start=clock()
local funcs = {}
if func then
funcs={func}
end
function c:Act()
for i=1,#funcs do
funcs[i](self,clock()-start)
end
self.OnLoop:Fire(self,clock()-start)
end
function c:OnLoop(func)
table.insert(funcs,func)
return self
c.OnLoop = self:newConnection()
if func then
c.OnLoop(func)
end
multi:create(c)
return c
@ -768,6 +743,7 @@ function multi:newFunction(func)
multi:create(c)
return c
end
function multi:newStep(start,reset,count,skip)
local c=self:newBase()
think=1
@ -789,19 +765,13 @@ function multi:newStep(start,reset,count,skip)
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)
self.OnStart:Fire(self)
end
self.OnStep:Fire(self,self.pos)
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.OnEnd:Fire(self)
self.pos=self.start
end
end
@ -812,22 +782,16 @@ function multi:newStep(start,reset,count,skip)
end
end
c.Reset=c.Resume
function c:OnStart(func)
table.insert(self.funcS,func)
return self
end
function c:OnStep(func)
table.insert(self.func,1,func)
return self
end
function c:OnEnd(func)
table.insert(self.funcE,func)
return self
end
c.OnStart = self:newConnection()
c.OnStep = self:newConnection()
c.OnEnd = self:newConnection()
function c:Break()
self.Active=nil
return self
end
function c:Count(count)
self.count = count
end
function c:Update(start,reset,count,skip)
self.start=start or self.start
self.endAt=reset or self.endAt
@ -846,19 +810,16 @@ function multi:newTLoop(func,set)
c.timer=self:newTimer()
c.life=0
c:setPriority("Low")
if func then
c.func={func}
end
function c:Act()
if self.timer:Get()>=self.set then
print("Acting...")
self.life=self.life+1
self.timer:Reset()
for i=1,#self.func do
self.func[i](self,self.life)
end
self.OnLoop:Fire(self,self.life)
end
end
function c:Set(set)
self.set = set
end
function c:Resume()
self.Parent.Resume(self)
self.timer:Resume()
@ -869,9 +830,9 @@ function multi:newTLoop(func,set)
self.Parent.Pause(self)
return self
end
function c:OnLoop(func)
table.insert(self.func,func)
return self
c.OnLoop = self:newConnection()
if func then
c.OnLoop(func)
end
multi:create(c)
return c
@ -880,20 +841,12 @@ function multi:setTimeout(func,t)
multi:newThread(function() thread.sleep(t) func() end)
end
function multi:newTStep(start,reset,count,set)
local c=self:newBase()
think=1
local c=self:newStep(start,reset,count)
c.Type='tstep'
c:setPriority("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=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
@ -908,38 +861,19 @@ function multi:newTStep(start,reset,count,set)
if 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)
self.OnStart:Fire(self)
end
self.OnStep:Fire(self,self.pos)
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.OnEnd:Fire(self)
self.pos=self.start
end
end
end
function c:OnStart(func)
table.insert(self.funcS,func)
return self
end
function c:OnStep(func)
table.insert(self.func,func)
return self
end
function c:OnEnd(func)
table.insert(self.funcE,func)
return self
end
function c:Break()
self.Active=nil
return self
function c:Set(set)
self.set = set
end
function c:Reset(n)
if n then self.set=n end
@ -950,6 +884,7 @@ function multi:newTStep(start,reset,count,set)
multi:create(c)
return c
end
local scheduledjobs = {}
local sthread
function multi:scheduleJob(time,func)