Connections can be % with functions

This commit is contained in:
Ryan Ward 2023-01-11 22:53:03 -05:00
parent 7114b87bdd
commit 3776fdff9d
3 changed files with 107 additions and 38 deletions

View File

@ -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
---

View File

@ -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,

View File

@ -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()
conn1:Fire(1,2,3)
conn2:Fire(1,2,3)