diff --git a/docs/changes.md b/docs/changes.md index 4bd8fca..ef90391 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -10,6 +10,40 @@ Table of contents # Update 16.0.0 - ? Added --- +- Connection objects now support the % function. This supports a function % connection object. What it does is allow you to **mod**ify the incoming arguments of a connection event. + ```lua + local conn1 = multi:newConnection() + local conn2 = function(a,b,c) return a*2, b*2, c*2 end % conn1 + conn2(function(a,b,c) + print("Conn2",a,b,c) + end) + conn1(function(a,b,c) + print("Conn1",a,b,c) + end) + conn1:Fire(1,2,3) + conn2:Fire(1,2,3) + ``` + Output: + ``` + Conn2 2 4 6 + Conn1 1 2 3 + Conn2 1 2 3 + ``` + **Note:** Conn1 does not get modified, however firing conn1 will also fire conn2 and have it's arguments modified. Also firing conn2 directly **does not** modify conn2's arguments! + See it's implementation below: + ```lua + __mod = function(obj1, obj2) + local cn = multi:newConnection() + if type(obj1) == "function" and type(obj2) == "table" then + obj2(function(...) + cn:Fire(obj1(...)) + end) + else + error("Invalid mod!", type(obj1), type(obj2),"Expected function, connection(table)") + end + return cn + end + ``` - Connection objects can now be concatenated with functions, not each other. For example: ```lua multi, thread = require("multi"):init{print=true,findopt=true} @@ -66,6 +100,42 @@ Added I run after it all! ``` + **Note:** Concat of connections does modify internal events on both connections depending on the direction func .. conn or conn .. func See implemention below: + ```lua + __concat = function(obj1, obj2) + local cn = multi:newConnection() + local ref + if type(obj1) == "function" and type(obj2) == "table" then + cn(function(...) + if obj1(...) then + obj2:Fire(...) + end + end) + cn.__connectionAdded = function(conn, func) + cn:Unconnect(conn) + obj2:Connect(func) + end + elseif type(obj1) == "table" and type(obj2) == "function" then + ref = cn(function(...) + obj1:Fire(...) + obj2(...) + end) + cn.__connectionAdded = function() + cn.rawadd = true + cn:Unconnect(ref) + ref = cn(function(...) + if obj2(...) then + obj1:Fire(...) + end + end) + end + else + error("Invalid concat!", type(obj1), type(obj2),"Expected function/connection(table), connection(table)/function") + end + return cn + end + ``` + Changed --- diff --git a/init.lua b/init.lua index dca42cc..a392bad 100644 --- a/init.lua +++ b/init.lua @@ -82,6 +82,10 @@ function multi.Stop() mainloopActive = false end +local function pack(...) + return {...} +end + -- Types multi.DESTROYED = multi.DestroyedObj multi.ROOTPROCESS = "rootprocess" @@ -140,6 +144,19 @@ local CRef = { Fire = function() end } +--[[ + cn(function(...) + local data = pack(obj1(...)) + local len = #data + if len ~= 0 then + if data[1] == true then + obj2:Fire(...) + else + obj2:Fire(unpack(data)) + end + end + end) +]] local optimization_stats = {} local ignoreconn = true function multi:newConnection(protect,func,kill) @@ -169,6 +186,17 @@ function multi:newConnection(protect,func,kill) return self:Connect(...) end end, + __mod = function(obj1, obj2) + local cn = multi:newConnection() + if type(obj1) == "function" and type(obj2) == "table" then + obj2(function(...) + cn:Fire(obj1(...)) + end) + else + error("Invalid mod!", type(obj1), type(obj2),"Expected function, connection(table)") + end + return cn + end, __concat = function(obj1, obj2) local cn = multi:newConnection() local ref @@ -197,7 +225,7 @@ function multi:newConnection(protect,func,kill) end) end else - error("Invalid concat!", type(obj1), type(obj2)) + error("Invalid concat!", type(obj1), type(obj2),"Expected function/connection(table), connection(table)/function") end return cn end, diff --git a/tests/test.lua b/tests/test.lua index e264b1d..abfa52c 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -1,42 +1,13 @@ package.path = "../?/init.lua;../?.lua;"..package.path multi, thread = require("multi"):init{print=true,findopt=true} -local conn1, conn2 = multi:newConnection(), multi:newConnection():fastMode() -conn3 = conn1 + conn2 - -conn1(function() - print("Hi 1") +local conn1 = multi:newConnection() +local conn2 = function(a,b,c) return a*2, b*2, c*2 end % conn1 +conn2(function(a,b,c) + print("Conn2",a,b,c) end) - -conn2(function() - print("Hi 2") +conn1(function(a,b,c) + print("Conn1",a,b,c) end) - -conn3(function() - print("Hi 3") -end) - -function test(a,b,c) - print("I run before all and control if things go!") - return a>b -end - -conn4 = test .. conn1 - -conn5 = conn2 .. function() print("I run after it all!") end - -conn4:Fire(3,2,3) - -conn5(function() - print("Test 1") -end) - -conn5(function() - print("Test 2") -end) - -conn5(function() - print("Test 3") -end) - -conn5:Fire() \ No newline at end of file +conn1:Fire(1,2,3) +conn2:Fire(1,2,3) \ No newline at end of file