diff --git a/changes.md b/changes.md index ec270c6..7f654b1 100644 --- a/changes.md +++ b/changes.md @@ -71,22 +71,23 @@ Changed: - multi:newTStep now derives it's functionality from multi:newStep (Cut's down on code length a bit) -- +- Fixed the getTaskDetails to handle the new format for threads ### 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. +Connections are one 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: --- -Nothing + +- Calling Fire on a connection no longer returns anything! Now that internal features use connections, I noticed how slow connections are and have increased their speed quite a bit. From 50,000 Steps per seconds to almost 7 Million. All other features should work just fine. Only returning values has been 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/30) with Lanes crashing the lua state. Issue seems to be related to my filesystem - [Issue](https://github.com/rayaman/multi/issues/29) where System threaded functions not up to date with threaded functions ToDo: diff --git a/multi/init.lua b/multi/init.lua index 5e87891..8065d13 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -201,6 +201,7 @@ end local ignoreconn = true function multi:newConnection(protect,func,kill) local c={} + local call_funcs = {} c.callback = func c.Parent=self c.lock = false @@ -245,8 +246,8 @@ function multi:newConnection(protect,func,kill) c.Type='connector' c.func={} c.ID=0 - c.protect=protect or true - c.connections={} + c.protect=protect or false + local connections={} c.FC=0 function c:holdUT(n) local n=n or 0 @@ -267,9 +268,9 @@ function multi:newConnection(protect,func,kill) c.HoldUT=c.holdUT function c:getConnection(name,ignore) if ignore then - return self.connections[name] or CRef + return connections[name] or CRef else - return self.connections[name] or self + return connections[name] or self end end function c:Lock() @@ -280,51 +281,58 @@ function multi:newConnection(protect,func,kill) c.lock = false return self end - function c:Fire(...) - local ret={} - if self.lock then return end - for i=#self.func,1,-1 do - if self.protect then - if not self.func[i] then return end - local temp={pcall(self.func[i][1],...)} - if temp[1] then - table.remove(temp,1) - table.insert(ret,temp) - else - multi.print(temp[2]) + if c.protect then + function c:Fire(...) + if self.lock then return end + for i=#call_funcs,1,-1 do + if not call_funcs[i] then return end + pcall(call_funcs[i],...) + if kill then + table.remove(call_funcs,i) end - else - if not self.func[i] then return end - table.insert(ret,{self.func[i][1](...)}) - end - if kill then - table.remove(self.func,i) end end - return ret + else + function c:Fire(...) + for i=#call_funcs,1,-1 do + call_funcs[i](...) + if kill then + table.remove(call_funcs,i) + end + end + end + end + local fast = {} + function c:fastMode() + function self:Fire(...) + for i=1,#fast do + fast[i](...) + end + end + function self:connect(func) + table.insert(fast,func) + end end function c:Bind(t) - local temp = self.func - self.func=t + local temp = call_funcs + call_funcs=t return temp end function c:Remove() - local temp = self.func - self.func={} + local temp = call_funcs + call_funcs={} return temp end local function conn_helper(self,func,name,num) self.ID=self.ID+1 if num then - table.insert(self.func,num,{func,self.ID}) + table.insert(call_funcs,num,func) else - table.insert(self.func,1,{func,self.ID}) + table.insert(call_funcs,1,func) end local temp = { - Link=self.func, func=func, Type="connector_link", - ID=self.ID, Parent=self, connect = function(s,...) return self:connect(...) @@ -350,29 +358,27 @@ function multi:newConnection(protect,func,kill) function temp:Fire(...) if self.Parent.lock then return end if self.Parent.protect then - local t=pcall(self.func,...) + local t=pcall(call_funcs,...) if t then return t end else - return self.func(...) + return call_funcs(...) end end function temp:Destroy() - for i=1,#self.Link do - if self.Link[i][2]~=nil then - if self.Link[i][2]==self.ID then - table.remove(self.Link,i) + for i=1,#call_funcs do + if call_funcs[i]~=nil then + if call_funcs[i]==self.func then + table.remove(call_funcs,i) self.remove=function() end - self.Link=nil - self.ID=nil multi.setType(temp,multi.DestroyedObj) end end end end if name then - self.connections[name]=temp + connections[name]=temp end if self.callback then self.callback(temp) @@ -396,7 +402,6 @@ function multi:newConnection(protect,func,kill) else return conn_helper(self,tab[1],tab[2],tab[3]) end - end c.Connect=c.connect c.GetConnection=c.getConnection @@ -711,9 +716,14 @@ function multi:newLoop(func) self.OnLoop:Fire(self,clock()-start) end c.OnLoop = self:newConnection() + function c:fastMode() + self.OnLoop:fastMode() + end + if func then c.OnLoop(func) end + multi:create(c) return c end @@ -978,9 +988,9 @@ function thread.getRunningThread() local threads = globalThreads local t = coroutine.running() if t then - for i,v in pairs(threads) do - if t==i.thread then - return v + for th,process in pairs(threads) do + if t==th.thread then + return th end end end @@ -1204,16 +1214,16 @@ function thread:newFunctionBase(generator,holdme) return wait() end local temp = { - OnStatus = multi:newConnection(), - OnError = multi:newConnection(), - OnReturn = multi:newConnection(), + OnStatus = multi:newConnection(true), + OnError = multi:newConnection(true), + OnReturn = multi:newConnection(true), isTFunc = true, wait = wait, getReturns = function() return unpack(rets) end, connect = function(f) - local tempConn = multi:newConnection() + local tempConn = multi:newConnection(true) t.OnDeath(function(self,status,...) if f then f(...) else tempConn:Fire(...) end end) t.OnError(function(self,err) if f then f(nil,err) else tempConn:Fire(nil,err) end end) return tempConn @@ -2291,17 +2301,14 @@ function multi:benchMark(sec,p,pt) if pt then multi.print(pt.." "..c.." Steps in "..sec.." second(s)!") end - self.tt(sec,c) + self.OnBench:Fire(sec,c) self:Destroy() else c=c+1 end end) + temp.OnBench = multi:newConnection() temp:setPriority(p or 1) - function temp:OnBench(func) - self.tt=func - end - self.tt=function() end return temp end diff --git a/multi/integration/lanesManager/init.lua b/multi/integration/lanesManager/init.lua index 01afe62..ae43fb8 100644 --- a/multi/integration/lanesManager/init.lua +++ b/multi/integration/lanesManager/init.lua @@ -21,6 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] + package.path = "?/init.lua;?.lua;" .. package.path multi, thread = require("multi"):init() -- get it all and have it on all lanes if multi.integration then -- This allows us to call the lanes manager from supporting modules without a hassle @@ -31,7 +32,7 @@ if multi.integration then -- This allows us to call the lanes manager from suppo } end -- Step 1 get lanes -lanes = require("lanes").configure({allocator="protected",verbose_errors=""}) +lanes = require("lanes").configure() multi.SystemThreads = {} multi.isMainThread = true @@ -47,12 +48,6 @@ end local __GlobalLinda = lanes.linda() -- handles global stuff local __SleepingLinda = lanes.linda() -- handles sleeping stuff local __ConsoleLinda = lanes.linda() -- handles console stuff -multi:newLoop(function() - local _,data = __ConsoleLinda:receive(0, "Q") - if data then - print(unpack(data)) - end -end) local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda,__SleepingLinda) local count = 1 local started = false @@ -65,6 +60,7 @@ function THREAD:newFunction(func,holdme) end function multi:newSystemThread(name, func, ...) + print("Creating a thread") multi.InitSystemThreadErrorHandler() local rand = math.random(1, 10000000) local return_linda = lanes.linda() @@ -106,6 +102,7 @@ function multi:newSystemThread(name, func, ...) return c end function multi.InitSystemThreadErrorHandler() + print("Thread Created!") if started == true then return end @@ -113,7 +110,11 @@ function multi.InitSystemThreadErrorHandler() multi:newThread("SystemThreadScheduler",function() local threads = multi.SystemThreads while true do - thread.sleep(.01) -- switching states often takes a huge hit on performance. half a second to tell me there is an error is good enough. + thread.sleep(.005) -- switching states often takes a huge hit on performance. half a second to tell me there is an error is good enough. + local _,data = __ConsoleLinda:receive(0, "Q") + if data then + print(unpack(data)) + end for i = #threads, 1, -1 do local status = threads[i].thread.status local temp = threads[i] @@ -153,6 +154,7 @@ function multi.InitSystemThreadErrorHandler() print(...) end) end + multi.print("Integrated Lanes!") multi.integration = {} -- for module creators multi.integration.GLOBAL = GLOBAL diff --git a/test3.lua b/test3.lua index 13315a6..4118ce6 100644 --- a/test3.lua +++ b/test3.lua @@ -1,19 +1,28 @@ package.path = "./?/init.lua;"..package.path local multi,thread = require("multi"):init() -local GLOBAL,THREAD = require("multi.integration.threading"):init() +local GLOBAL,THREAD = require("multi.integration.lanesManager"):init() -function sleep(n) - if n > 0 then os.execute("ping -n " .. tonumber(n+1) .. " localhost > NUL") end -end +-- func = THREAD:newFunction(function(a,b,c) +-- print("Hello Thread!",a,b,c) +-- return 1,2,3 +-- end) -func = THREAD:newFunction(function(a,b,c) - print("Hello Thread!",a,b,c) - return 1,2,3 +-- func2 = THREAD:newFunction(function(a,b,c) +-- print("Hello Thread2!",a,b,c) +-- THREAD.sleep(1) +-- return 10,11,12 +-- end) + +-- multi:newThread("Test thread",function() +-- handler = func(4,5,6) +-- handler2 = func2(7,8,9) +-- thread.hold(handler.OnReturn + handler2.OnReturn) +-- print("Function Done",handler.getReturns()) +-- print("Function Done",handler2.getReturns()) +-- end) +multi:benchMark(1):OnBench(function(sec,steps) + print("Steps:",steps) + os.exit() end) -multi:newThread("Test thread",function() - handler = func(4,5,6) - thread.hold(handler.OnReturn) - print("Function Done",handler.getReturns()) -end) multi:mainloop() \ No newline at end of file