Fixed issue where the Connection Host wouldn't trigger itself when a non host calls Fire

This commit is contained in:
Ryan Ward 2022-09-22 23:06:45 -04:00
commit 6de93c10af
11 changed files with 256 additions and 85 deletions

View File

@ -1,4 +1,4 @@
# Multi Version: 15.2.1
# Multi Version: 15.3.0 Connecting the dots
**Key Changes**
- Bug fix
@ -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</br>
If you want to use the system threads, then you'll need to install lanes or love2d game engine!

View File

@ -4,8 +4,118 @@ Table of contents
[Update 15.2.1 - Bug fix](#update-1521---bug-fix)</br>
[Update 15.2.0 - Upgrade Complete](#update-1520---upgrade-complete)</br>[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.3.0 - A world of connection
Full Update Showcase
```lua
multi, thread = require("multi"):init{print=true}
GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
local conn = multi:newSystemThreadedConnection("conn"):init()
multi:newSystemThread("Thread_Test_1",function()
local multi, thread = require("multi"):init()
local conn = GLOBAL["conn"]:init()
conn(function()
print(THREAD:getName().." was triggered!")
end)
multi:mainloop()
end)
multi:newSystemThread("Thread_Test_2",function()
local multi, thread = require("multi"):init()
local conn = GLOBAL["conn"]:init()
conn(function(a,b,c)
print(THREAD:getName().." was triggered!",a,b,c)
end)
multi:newAlarm(2):OnRing(function()
print("Fire 2!!!")
conn:Fire(4,5,6)
THREAD.kill()
end)
multi:mainloop()
end)
conn(function(a,b,c)
print("Mainloop conn got triggered!",a,b,c)
end)
alarm = multi:newAlarm(1)
alarm:OnRing(function()
print("Fire 1!!!")
conn:Fire(1,2,3)
end)
alarm = multi:newAlarm(3):OnRing(function()
multi:newSystemThread("Thread_Test_3",function()
local multi, thread = require("multi"):init()
local conn = GLOBAL["conn"]:init()
conn(function(a,b,c)
print(THREAD:getName().." was triggered!",a,b,c)
end)
multi:newAlarm(2):OnRing(function()
print("Fire 3!!!")
conn:Fire(7,8,9)
end)
multi:mainloop()
end)
end)
multi:newSystemThread("Thread_Test_4",function()
local multi, thread = require("multi"):init()
local conn = GLOBAL["conn"]:init()
local conn2 = multi:newConnection()
multi:newAlarm(2):OnRing(function()
conn2:Fire()
end)
multi:newThread(function()
print("Conn Test!")
thread.hold(conn + conn2)
print("It held!")
end)
multi:mainloop()
end)
multi:mainloop()
```
Added
---
- `multi:newSystemThreadedConnection()`
Allows one to trigger connection events across threads. Works like how any connection would work. Supports all of the features, can even be `added` with non SystemThreadedConnections as demonstrated in the full showcase.
- `multi:newConnection():SetHelper(func)`
Sets the helper function that the connection object uses when creating connection links.
- `multi.ForEach(table, callback_function)`
Loops through the table and calls callback_function with each element of the array.
- If a name is not supplied when creating threads; a name is randomly generated. Unless sending through an established channel/queue you might not be able to easily init the object.
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
---
- SystemThreaded Objects variables weren't consistent.
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.1 - Bug fix
Fixed issue #41
---
# Update 15.2.0 - Upgrade Complete

View File

@ -1,9 +1,9 @@
commands = [[
mkdir luajit && python -m hererocks -j 2.1.0-beta3 -r latest --patch --compat all ./luajit && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi
mkdir lua5.1 && python -m hererocks -l 5.1 -r latest --patch --compat all ./lua5.1 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi
mkdir lua5.2 && python -m hererocks -l 5.2 -r latest --patch --compat all ./lua5.2 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi
mkdir lua5.3 && python -m hererocks -l 5.3 -r latest --patch --compat all ./lua5.3 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi
mkdir lua5.4 && python -m hererocks -l 5.4 -r latest --patch --compat all ./lua5.4 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi
mkdir luajit && python -m hererocks -j 2.1.0-beta3 -r latest --patch --compat all ./luajit && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes
mkdir lua5.1 && python -m hererocks -l 5.1 -r latest --patch --compat all ./lua5.1 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes
mkdir lua5.2 && python -m hererocks -l 5.2 -r latest --patch --compat all ./lua5.2 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes
mkdir lua5.3 && python -m hererocks -l 5.3 -r latest --patch --compat all ./lua5.3 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes
mkdir lua5.4 && python -m hererocks -l 5.4 -r latest --patch --compat all ./lua5.4 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes
]]
function string.split (inputstr, sep)
local sep = sep or "\n"

View File

@ -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}
@ -121,19 +121,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)
@ -159,32 +160,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
@ -192,14 +179,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
@ -213,6 +203,7 @@ function multi:newConnection(protect,func,kill)
end
else
function c:Fire(...)
if lock then return end
for i=#call_funcs,1,-1 do
call_funcs[i](...)
if kill then
@ -221,48 +212,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
@ -277,17 +276,11 @@ function multi:newConnection(protect,func,kill)
rawset(t,k,v)
end,
})
function temp:Fire(...)
if lock then return end
if protect then
local t=pcall(call_funcs,...)
if t then
return t
end
else
return call_funcs(...)
end
return call_funcs(...)
end
function temp:Destroy()
for i=#call_funcs,1,-1 do
if call_funcs[i]~=nil then
@ -299,15 +292,19 @@ function multi:newConnection(protect,func,kill)
end
end
end
if name then
connections[name]=temp
end
if self.callback then
self.callback(temp)
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
@ -325,8 +322,15 @@ function multi:newConnection(protect,func,kill)
return conn_helper(self,tab[1],tab[2],tab[3])
end
end
c.Connect=c.connect
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
@ -1249,9 +1253,8 @@ local startme_len = 0
function thread:newThread(name,func,...)
multi.OnLoad:Fire() -- This was done incase a threaded function was called before mainloop/uManager was called
local func = func or name
if type(name) == "function" then
name = "Thread#"..threadCount
if func == name then
name = name or multi.randomString(16)
end
local c={nil,nil,nil,nil,nil,nil,nil}
local env = {self=c}
@ -2050,14 +2053,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

View File

@ -231,6 +231,12 @@ function multi:newSystemThreadedConnection(name)
ping:Resume()
end,false)
local function fire(...)
for _, link in pairs(c.links) do
link:push {c.TRIG, {...}}
end
end
thread:newThread("STC_SUB_MAN"..name,function()
local item
while true do
@ -246,11 +252,11 @@ function multi:newSystemThreadedConnection(name)
end)
c.links[#c.links+1] = item[2]
elseif item[1] == c.TRIG then
c:Fire(unpack(item[2]))
fire(unpack(item[2]))
c.proxy_conn:Fire(unpack(item[2]))
end
end
end).OnError(print)
end)
--- ^^^ This will only exist in the init thread
function c:Fire(...)
@ -259,7 +265,7 @@ function multi:newSystemThreadedConnection(name)
for _, link in pairs(self.links) do
link:push {self.TRIG, args}
end
--c.proxy_conn:Fire(...)
self.proxy_conn:Fire(...)
else
self.subscribe:push {self.TRIG, args}
end
@ -295,7 +301,7 @@ function multi:newSystemThreadedConnection(name)
-- This shouldn't be the case
end
end
end).OnError(print)
end)
return self
end

View File

@ -50,7 +50,7 @@ local __SleepingLinda = lanes.linda() -- handles sleeping stuff
local __ConsoleLinda = lanes.linda() -- handles console stuff
local __StatusLinda = lanes.linda() -- handles pushstatus for stfunctions
local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda, __SleepingLinda, __StatusLinda)
local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda, __SleepingLinda, __StatusLinda, __ConsoleLinda)
local count = 1
local started = false
local livingThreads = {}
@ -62,6 +62,7 @@ function THREAD:newFunction(func,holdme)
end
function multi:newSystemThread(name, func, ...)
local name = name or multi.randomString(16)
multi.InitSystemThreadErrorHandler()
local rand = math.random(1, 10000000)
local return_linda = lanes.linda()

View File

@ -29,7 +29,7 @@ local function getOS()
end
end
local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda)
local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda, __Console)
local THREAD = {}
THREAD.Priority_Core = 3
THREAD.Priority_High = 2
@ -70,7 +70,7 @@ local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda)
function THREAD.getConsole()
local c = {}
c.queue = _Console
c.queue = __Console
function c.print(...)
c.queue:send("Q", {...})
end
@ -137,6 +137,6 @@ local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda)
return GLOBAL, THREAD
end
return {init = function(g,s,st)
return INIT(g,s,st)
return {init = function(g,s,st,c)
return INIT(g,s,st,c)
end}

View File

@ -27,6 +27,7 @@ local multi, thread = require("multi").init()
GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD
function multi:newSystemThreadedQueue(name)
local name = name or multi.randomString(16)
local c = {}
c.Name = name
local fRef = {"func",nil}
@ -64,10 +65,11 @@ function multi:newSystemThreadedQueue(name)
return c
end
function multi:newSystemThreadedTable(name)
local name = name or multi.randomString(16)
local c = {}
c.name = name
c.Name = name
function c:init()
return THREAD.createTable(self.name)
return THREAD.createTable(self.Name)
end
THREAD.package(name,c)
return c
@ -440,7 +442,12 @@ function multi:newSystemThreadedConnection(name)
end,{sleep=3})
if not res then
self.links = remove(self.links, pings)
for i=1,#links do
if links[i] == link then
table.remove(links,i,link)
break
end
end
else
link:pop()
end
@ -458,6 +465,12 @@ function multi:newSystemThreadedConnection(name)
ping:Resume()
end,false)
local function fire(...)
for _, link in pairs(c.links) do
link:push {c.TRIG, {...}}
end
end
thread:newThread("STC_SUB_MAN"..name,function()
local item
while true do
@ -473,7 +486,7 @@ function multi:newSystemThreadedConnection(name)
end)
c.links[#c.links+1] = item[2]
elseif item[1] == c.TRIG then
c:Fire(unpack(item[2]))
fire(unpack(item[2]))
c.proxy_conn:Fire(unpack(item[2]))
end
end
@ -486,6 +499,7 @@ function multi:newSystemThreadedConnection(name)
for _, link in pairs(self.links) do
link:push {self.TRIG, args}
end
self.proxy_conn:Fire(...)
else
self.subscribe:push {self.TRIG, args}
end
@ -497,6 +511,7 @@ function multi:newSystemThreadedConnection(name)
self.proxy_conn = multi:newConnection()
local mt = getmetatable(self.proxy_conn)
setmetatable(self, {__index = self.proxy_conn, __call = function(t,func) self.proxy_conn(func) end, __add = mt.__add})
if self.CID == THREAD.getID() then return self end
thread:newThread("STC_CONN_MAN"..name,function()
local item
local link_self_ref = multi:newSystemThreadedQueue()
@ -524,7 +539,7 @@ function multi:newSystemThreadedConnection(name)
return self
end
GLOBAL[name] = c
THREAD.package(name,c)
return c
end

View File

@ -25,6 +25,7 @@ local multi, thread = require("multi").init()
GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD
function multi:newSystemThreadedQueue(name)
local name = name or multi.randomString(16)
local c = {}
c.Name = name
local fRef = {"func",nil}
@ -62,10 +63,11 @@ function multi:newSystemThreadedQueue(name)
return c
end
function multi:newSystemThreadedTable(name)
local name = name or multi.randomString(16)
local c = {}
c.name = name
c.Name = name
function c:init()
return THREAD.createTable(self.name)
return THREAD.createTable(self.Name)
end
THREAD.package(name,c)
return c

View File

@ -9,8 +9,8 @@ multi:newSystemThread("Thread_Test_1",function()
local multi, thread = require("multi"):init()
local conn = GLOBAL["conn"]:init()
local console = THREAD.getConsole()
conn(function()
console.print(THREAD:getName().." was triggered!")
conn(function(a,b,c)
console.print(THREAD:getName().." was triggered!",a,b,c)
end)
multi:mainloop()
end)
@ -22,22 +22,22 @@ multi:newSystemThread("Thread_Test_2",function()
conn(function(a,b,c)
console.print(THREAD:getName().." was triggered!",a,b,c)
end)
multi:newAlarm(3):OnRing(function()
multi:newAlarm(2):OnRing(function()
console.print("Fire 2!!!")
conn:Fire(4,5,6)
--THREAD.kill()
THREAD.kill()
end)
multi:mainloop()
end)
local console = THREAD.getConsole()
conn(function(a,b,c)
print("Mainloop conn got triggered!",a,b,c)
console.print("Mainloop conn got triggered!",a,b,c)
end)
alarm = multi:newAlarm(1)
alarm:OnRing(function()
print("Fire 1!!!")
console.print("Fire 1!!!")
conn:Fire(1,2,3)
end)

33
test2.lua Normal file
View File

@ -0,0 +1,33 @@
function difference(a, b)
local ai = {}
local r = {}
local rr = {}
for k,v in pairs(a) do r[k] = v; ai[v]=true end
for k,v in pairs(b) do
if ai[v]==nil then table.insert(rr,r[k]) end
end
return rr
end
function remove(a, b)
local ai = {}
local r = {}
for k,v in pairs(a) do ai[v]=true end
for k,v in pairs(b) do
if ai[v]==nil then table.insert(r,a[k]) end
end
return r
end
function printtab(tab,msg)
print(msg or "TABLE")
for i,v in pairs(tab) do
print(i, v)
end
print("")
end
local tab1 = {1,2,3,4,5}
local tab2 = {3,4,5,6,7}
tab1 = remove(tab1,tab2)
printtab(tab1, "Table 1")
printtab(tab2, "Table 2")