diff --git a/README.md b/README.md index b1abc29..131db6a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Multi Version: 15.3.0 +# Multi Version: 15.3.0 Connecting the dots **Key Changes** - @@ -16,8 +16,9 @@ Progress is being made in [v15.3.0](https://github.com/rayaman/multi/tree/v15.3. INSTALLING ---------- Link to optional dependencies: -[lanes](https://github.com/LuaLanes/lanes) -[love2d](https://love2d.org/) +- [lanes](https://github.com/LuaLanes/lanes) + +- [love2d](https://love2d.org/) To install copy the multi folder into your environment and you are good to go
If you want to use the system threads, then you'll need to install lanes or love2d game engine! diff --git a/changes.md b/changes.md index 77368e5..7457dfe 100644 --- a/changes.md +++ b/changes.md @@ -3,6 +3,37 @@ Table of contents --- [Update 15.2.0 - Upgrade Complete](#update-1520---upgrade-complete)
[Update 15.1.0 - Hold the thread!](#update-1510---hold-the-thread)
[Update 15.0.0 - The art of faking it](#update-1500---the-art-of-faking-it)
[Update 14.2.0 - Bloatware Removed](#update-1420---bloatware-removed)
[Update 14.1.0 - A whole new world of possibilities](#update-1410---a-whole-new-world-of-possibilities)
[Update 14.0.0 - Consistency, Additions and Stability](#update-1400---consistency-additions-and-stability)
[Update 13.1.0 - Bug fixes and features added](#update-1310---bug-fixes-and-features-added)
[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)
[Update 12.2.2 - Time for some more bug fixes!](#update-1222---time-for-some-more-bug-fixes)
[Update 12.2.1 - Time for some bug fixes!](#update-1221---time-for-some-bug-fixes)
[Update 12.2.0 - The chains of binding](#update-1220---the-chains-of-binding)
[Update 12.1.0 - Threads just can't hold on anymore](#update-1210---threads-just-cant-hold-on-anymore)
[Update: 12.0.0 - Big update (Lots of additions some changes)](#update-1200---big-update-lots-of-additions-some-changes)
[Update: 1.11.1 - Small Clarification on Love](#update-1111---small-clarification-on-love)
[Update: 1.11.0](#update-1110)
[Update: 1.10.0](#update-1100)
[Update: 1.9.2](#update-192)
[Update: 1.9.1 - Threads can now argue](#update-191---threads-can-now-argue)
[Update: 1.9.0](#update-190)
[Update: 1.8.7](#update-187)
[Update: 1.8.6](#update-186)
[Update: 1.8.5](#update-185)
[Update: 1.8.4](#update-184)
[Update: 1.8.3 - Mainloop recieves some needed overhauling](#update-183---mainloop-recieves-some-needed-overhauling)
[Update: 1.8.2](#update-182)
[Update: 1.8.1](#update-181)
[Update: 1.7.6](#update-176)
[Update: 1.7.5](#update-175)
[Update: 1.7.4](#update-174)
[Update: 1.7.3](#update-173)
[Update: 1.7.2](#update-172)
[Update: 1.7.1 - Bug Fixes Only](#update-171---bug-fixes-only)
[Update: 1.7.0 - Threading the systems](#update-170---threading-the-systems)
[Update: 1.6.0](#update-160)
[Update: 1.5.0](#update-150)
[Update: 1.4.1 (4/10/2017) - First Public release of the library](#update-141-4102017---first-public-release-of-the-library)
[Update: 1.4.0 (3/20/2017)](#update-140-3202017)
[Update: 1.3.0 (1/29/2017)](#update-130-1292017)
[Update: 1.2.0 (12.31.2016)](#update-120-12312016)
[Update: 1.1.0](#update-110)
[Update: 1.0.0](#update-100)
[Update: 0.6.3](#update-063)
[Update: 0.6.2](#update-062)
[Update: 0.6.1-6](#update-061-6)
[Update: 0.5.1-6](#update-051-6)
[Update: 0.4.1](#update-041)
[Update: 0.3.0 - The update that started it all](#update-030---the-update-that-started-it-all)
[Update: EventManager 2.0.0](#update-eventmanager-200)
[Update: EventManager 1.2.0](#update-eventmanager-120)
[Update: EventManager 1.1.0](#update-eventmanager-110)
[Update: EventManager 1.0.0 - Error checking](#update-eventmanager-100---error-checking)
[Version: EventManager 0.0.1 - In The Beginning things were very different](#version-eventmanager-001---in-the-beginning-things-were-very-different) +# Update 15.3.0 - A world of connection + +Full Update Showcase + +Added +--- +- `multi:newSystemThreadedConnection()` + + Allows one to trigger connection events across threads. +- `multi:newConnection():SetHelper(func)` + + Sets the helper function that the connection object uses when creating connection links. + +Changed +--- +- `Connection:[connect, hasConnections, getConnection]` changed to be `Connection:[Connect, HasConnections, getConnections]`. This was done in an attempt to follow a consistent naming scheme. The old methods still will work to prevent old code breaking. + +Removed +--- +- Connection objects methods removed: + - holdUT(), HoldUT() -- With the way `thread.hold(conn)` interacts with connections this method was no longer needed. To emulate this use `multi.hold(conn)`. `multi.hold()` is able to emulate what `thread.hold()` outside of a thread, albeit with some drawbacks. + +Fixed +--- +- + +ToDo +--- + +- Work on network parallelism (I am really excited to start working on this. Not because it will have much use, but because it seems like a cool addition/project to work on. I just need time to actually do work on stuff) + # Update 15.2.0 - Upgrade Complete Full Update Showcase diff --git a/multi/init.lua b/multi/init.lua index cd91633..080c5d9 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -58,15 +58,15 @@ multi.Priority_Very_Low = 16384 multi.Priority_Idle = 65536 multi.PriorityResolve = { - [1]="Core", - [4]="Very High", - [16]="High", - [64]="Above Normal", - [256]="Normal", - [1024]="Below Normal", - [4096]="Low", - [16384]="Very Low", - [65536]="Idle", + [1] = "Core", + [4] = "Very High", + [16] = "High", + [64] = "Above Normal", + [256] = "Normal", + [1024] = "Below Normal", + [4096] = "Low", + [16384] = "Very Low", + [65536] = "Idle", } local PList = {multi.Priority_Core,multi.Priority_Very_High,multi.Priority_High,multi.Priority_Above_Normal,multi.Priority_Normal,multi.Priority_Below_Normal,multi.Priority_Low,multi.Priority_Very_Low,multi.Priority_Idle} @@ -116,19 +116,20 @@ function multi:newConnection(protect,func,kill) local lock = false c.callback = func c.Parent=self + setmetatable(c,{__call=function(self,...) local t = ... if type(t)=="table" then for i,v in pairs(t) do if v==self then - local ref = self:connect(select(2,...)) + local ref = self:Connect(select(2,...)) ref.root_link = select(1,...) return ref end end - return self:connect(...) + return self:Connect(...) else - return self:connect(...) + return self:Connect(...) end end, __add = function(c1,c2) @@ -154,32 +155,18 @@ function multi:newConnection(protect,func,kill) end) return cn end}) + c.Type='connector' c.func={} c.ID=0 local protect=protect or false local connections={} c.FC=0 + function c:hasConnections() return #call_funcs~=0 end - function c:holdUT(n) - local n=n or 0 - self.waiting=true - local count=0 - local id=self:connect(function() - count = count + 1 - if n<=count then - self.waiting=false - end - end) - repeat - self.Parent:uManager() - until self.waiting==false - id:Destroy() - return self - end - c.HoldUT=c.holdUT + function c:getConnection(name,ignore) if ignore then return connections[name] or CRef @@ -187,14 +174,17 @@ function multi:newConnection(protect,func,kill) return connections[name] or self end end + function c:Lock() lock = true return self end + function c:Unlock() lock = false return self end + if protect then function c:Fire(...) if lock then return end @@ -216,48 +206,56 @@ function multi:newConnection(protect,func,kill) end end end + local fast = {} function c:getConnections() return call_funcs end + function c:fastMode() function self:Fire(...) for i=1,#fast do fast[i](...) end end - function self:connect(func) + function self:Connect(func) table.insert(fast,func) end end + function c:Bind(t) local temp = call_funcs call_funcs=t return temp end + function c:Remove() 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(call_funcs,num,func) else table.insert(call_funcs,1,func) end + local temp = { func=func, Type="connector_link", Parent=self, connect = function(s,...) - return self:connect(...) + return self:Connect(...) end } + setmetatable(temp,{ __call=function(s,...) - return self:connect(...) + return self:Connect(...) end, __index = function(t,k) if rawget(t,"root_link") then @@ -272,6 +270,7 @@ function multi:newConnection(protect,func,kill) rawset(t,k,v) end, }) + function temp:Fire(...) if lock then return end if protect then @@ -283,6 +282,7 @@ function multi:newConnection(protect,func,kill) return call_funcs(...) end end + function temp:Destroy() for i=#call_funcs,1,-1 do if call_funcs[i]~=nil then @@ -294,6 +294,7 @@ function multi:newConnection(protect,func,kill) end end end + if name then connections[name]=temp end @@ -302,7 +303,8 @@ function multi:newConnection(protect,func,kill) end return temp end - function c:connect(...)--func,name,num + + function c:Connect(...)--func,name,num local tab = {...} local funcs={} for i=1,#tab do @@ -320,8 +322,15 @@ function multi:newConnection(protect,func,kill) return conn_helper(self,tab[1],tab[2],tab[3]) end end + + function c:SetHelper(func) + conn_helper = func + end + c.Connect=c.connect c.GetConnection=c.getConnection + c.HasConnections = c.hasConnections + c.GetConnection = c.getConnection if not(ignoreconn) then multi:create(c) end @@ -2043,14 +2052,14 @@ function multi.print(...) end end -multi.GetType=multi.getType -multi.IsPaused=multi.isPaused -multi.IsActive=multi.isActive -multi.Reallocate=multi.Reallocate -multi.ConnectFinal=multi.connectFinal -multi.ResetTime=multi.SetTime -multi.IsDone=multi.isDone -multi.SetName = multi.setName +multi.GetType = multi.getType +multi.IsPaused = multi.isPaused +multi.IsActive = multi.isActive +multi.Reallocate = multi.Reallocate +multi.ConnectFinal = multi.connectFinal +multi.ResetTime = multi.SetTime +multi.IsDone = multi.isDone +multi.SetName = multi.setName -- Special Events local _os = os.exit diff --git a/multi/integration/lanesManager/extensions.lua b/multi/integration/lanesManager/extensions.lua index 198e551..bc37455 100644 --- a/multi/integration/lanesManager/extensions.lua +++ b/multi/integration/lanesManager/extensions.lua @@ -41,6 +41,7 @@ function multi:newSystemThreadedQueue(name) GLOBAL[name or "_"] = c return c end + function multi:newSystemThreadedTable(name) local c = {} c.link = lanes.linda() @@ -58,6 +59,7 @@ function multi:newSystemThreadedTable(name) GLOBAL[name or "_"] = c return c end + function multi:newSystemThreadedJobQueue(n) local c = {} c.cores = n or THREAD.getCores()*2 diff --git a/test.lua b/test.lua index 1616eb4..dc3361e 100644 --- a/test.lua +++ b/test.lua @@ -2,8 +2,30 @@ package.path = "./?/init.lua;"..package.path multi, thread = require("multi"):init{print=true} GLOBAL, THREAD = require("multi.integration.threading"):init() -function multi:newSystemThreadedConnection() - -- +function multi:newSystemThreadedConnection(name,...) + local master_conn = multi:newConnection(...) + local c = {} + local name = name or multi.randomString(16) + local connections = {} -- All triggers sent from main connection. When a connection is triggered on another thread, they speak to the main then send stuff out. + setmetatable(c,master_conn) -- A different approach will be taken for the non main connection objects + c.subscribe = multi:newSystemThreadedQueue("Subscribe_"..name) + multi:newThread("STC_"..name,function() + while true do + thread.yield() + local item = c.subscribe:pop() + if item ~= nil then + connections[#connections+1] = item + thread.skip(multi.Priority_Normal) -- Usually a bunch of threads subscribe close to the same time. Process those by ensuring that they come alive around the same time + else -- I'm using these "Constant" values since they may change with other releases and this should allow these functions to adjust with them. + thread.skip(multi.Priority_Idle) + end + end + end) + function c:init() + return self + end + GLOBAL[name or "_"] = c + return c end multi:mainloop() \ No newline at end of file