15.3.0 system threaded connections #48
@ -1,6 +1,6 @@
|
|||||||
# Multi Version: 15.3.0
|
# Multi Version: 15.3.0 Connecting the dots
|
||||||
**Key Changes**
|
**Key Changes**
|
||||||
-
|
- Bug fix
|
||||||
|
|
||||||
Found an issue? Please [submit it](https://github.com/rayaman/multi/issues) and someone will look into it!
|
Found an issue? Please [submit it](https://github.com/rayaman/multi/issues) and someone will look into it!
|
||||||
|
|
||||||
@ -16,8 +16,9 @@ Progress is being made in [v15.3.0](https://github.com/rayaman/multi/tree/v15.3.
|
|||||||
INSTALLING
|
INSTALLING
|
||||||
----------
|
----------
|
||||||
Link to optional dependencies:
|
Link to optional dependencies:
|
||||||
[lanes](https://github.com/LuaLanes/lanes)
|
- [lanes](https://github.com/LuaLanes/lanes)
|
||||||
[love2d](https://love2d.org/)
|
|
||||||
|
- [love2d](https://love2d.org/)
|
||||||
|
|
||||||
To install copy the multi folder into your environment and you are good to go</br>
|
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!
|
If you want to use the system threads, then you'll need to install lanes or love2d game engine!
|
||||||
|
|||||||
114
changes.md
114
changes.md
@ -1,8 +1,122 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
Table of contents
|
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.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
|
# Update 15.2.0 - Upgrade Complete
|
||||||
|
|
||||||
Full Update Showcase
|
Full Update Showcase
|
||||||
|
|||||||
10
makeENV.lua
10
makeENV.lua
@ -1,9 +1,9 @@
|
|||||||
commands = [[
|
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 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
|
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
|
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
|
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
|
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)
|
function string.split (inputstr, sep)
|
||||||
local sep = sep or "\n"
|
local sep = sep or "\n"
|
||||||
|
|||||||
@ -109,6 +109,12 @@ function multi:getStats()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--Helpers
|
--Helpers
|
||||||
|
function multi.ForEach(tab,func)
|
||||||
|
for i=1,#tab do
|
||||||
|
func(tab[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local ignoreconn = true
|
local ignoreconn = true
|
||||||
function multi:newConnection(protect,func,kill)
|
function multi:newConnection(protect,func,kill)
|
||||||
local c={}
|
local c={}
|
||||||
@ -116,19 +122,20 @@ function multi:newConnection(protect,func,kill)
|
|||||||
local lock = false
|
local lock = false
|
||||||
c.callback = func
|
c.callback = func
|
||||||
c.Parent=self
|
c.Parent=self
|
||||||
|
|
||||||
setmetatable(c,{__call=function(self,...)
|
setmetatable(c,{__call=function(self,...)
|
||||||
local t = ...
|
local t = ...
|
||||||
if type(t)=="table" then
|
if type(t)=="table" then
|
||||||
for i,v in pairs(t) do
|
for i,v in pairs(t) do
|
||||||
if v==self then
|
if v==self then
|
||||||
local ref = self:connect(select(2,...))
|
local ref = self:Connect(select(2,...))
|
||||||
ref.root_link = select(1,...)
|
ref.root_link = select(1,...)
|
||||||
return ref
|
return ref
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return self:connect(...)
|
return self:Connect(...)
|
||||||
else
|
else
|
||||||
return self:connect(...)
|
return self:Connect(...)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
__add = function(c1,c2)
|
__add = function(c1,c2)
|
||||||
@ -154,32 +161,18 @@ function multi:newConnection(protect,func,kill)
|
|||||||
end)
|
end)
|
||||||
return cn
|
return cn
|
||||||
end})
|
end})
|
||||||
|
|
||||||
c.Type='connector'
|
c.Type='connector'
|
||||||
c.func={}
|
c.func={}
|
||||||
c.ID=0
|
c.ID=0
|
||||||
local protect=protect or false
|
local protect=protect or false
|
||||||
local connections={}
|
local connections={}
|
||||||
c.FC=0
|
c.FC=0
|
||||||
|
|
||||||
function c:hasConnections()
|
function c:hasConnections()
|
||||||
return #call_funcs~=0
|
return #call_funcs~=0
|
||||||
end
|
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)
|
function c:getConnection(name,ignore)
|
||||||
if ignore then
|
if ignore then
|
||||||
return connections[name] or CRef
|
return connections[name] or CRef
|
||||||
@ -187,14 +180,17 @@ function multi:newConnection(protect,func,kill)
|
|||||||
return connections[name] or self
|
return connections[name] or self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function c:Lock()
|
function c:Lock()
|
||||||
lock = true
|
lock = true
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function c:Unlock()
|
function c:Unlock()
|
||||||
lock = false
|
lock = false
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
if protect then
|
if protect then
|
||||||
function c:Fire(...)
|
function c:Fire(...)
|
||||||
if lock then return end
|
if lock then return end
|
||||||
@ -208,6 +204,7 @@ function multi:newConnection(protect,func,kill)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
function c:Fire(...)
|
function c:Fire(...)
|
||||||
|
if lock then return end
|
||||||
for i=#call_funcs,1,-1 do
|
for i=#call_funcs,1,-1 do
|
||||||
call_funcs[i](...)
|
call_funcs[i](...)
|
||||||
if kill then
|
if kill then
|
||||||
@ -216,48 +213,56 @@ function multi:newConnection(protect,func,kill)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local fast = {}
|
local fast = {}
|
||||||
function c:getConnections()
|
function c:getConnections()
|
||||||
return call_funcs
|
return call_funcs
|
||||||
end
|
end
|
||||||
|
|
||||||
function c:fastMode()
|
function c:fastMode()
|
||||||
function self:Fire(...)
|
function self:Fire(...)
|
||||||
for i=1,#fast do
|
for i=1,#fast do
|
||||||
fast[i](...)
|
fast[i](...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function self:connect(func)
|
function self:Connect(func)
|
||||||
table.insert(fast,func)
|
table.insert(fast,func)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function c:Bind(t)
|
function c:Bind(t)
|
||||||
local temp = call_funcs
|
local temp = call_funcs
|
||||||
call_funcs=t
|
call_funcs=t
|
||||||
return temp
|
return temp
|
||||||
end
|
end
|
||||||
|
|
||||||
function c:Remove()
|
function c:Remove()
|
||||||
local temp = call_funcs
|
local temp = call_funcs
|
||||||
call_funcs={}
|
call_funcs={}
|
||||||
return temp
|
return temp
|
||||||
end
|
end
|
||||||
|
|
||||||
local function conn_helper(self,func,name,num)
|
local function conn_helper(self,func,name,num)
|
||||||
self.ID=self.ID+1
|
self.ID=self.ID+1
|
||||||
|
|
||||||
if num then
|
if num then
|
||||||
table.insert(call_funcs,num,func)
|
table.insert(call_funcs,num,func)
|
||||||
else
|
else
|
||||||
table.insert(call_funcs,1,func)
|
table.insert(call_funcs,1,func)
|
||||||
end
|
end
|
||||||
|
|
||||||
local temp = {
|
local temp = {
|
||||||
func=func,
|
func=func,
|
||||||
Type="connector_link",
|
Type="connector_link",
|
||||||
Parent=self,
|
Parent=self,
|
||||||
connect = function(s,...)
|
connect = function(s,...)
|
||||||
return self:connect(...)
|
return self:Connect(...)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
setmetatable(temp,{
|
setmetatable(temp,{
|
||||||
__call=function(s,...)
|
__call=function(s,...)
|
||||||
return self:connect(...)
|
return self:Connect(...)
|
||||||
end,
|
end,
|
||||||
__index = function(t,k)
|
__index = function(t,k)
|
||||||
if rawget(t,"root_link") then
|
if rawget(t,"root_link") then
|
||||||
@ -272,17 +277,11 @@ function multi:newConnection(protect,func,kill)
|
|||||||
rawset(t,k,v)
|
rawset(t,k,v)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
function temp:Fire(...)
|
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(...)
|
return call_funcs(...)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
function temp:Destroy()
|
function temp:Destroy()
|
||||||
for i=#call_funcs,1,-1 do
|
for i=#call_funcs,1,-1 do
|
||||||
if call_funcs[i]~=nil then
|
if call_funcs[i]~=nil then
|
||||||
@ -294,15 +293,19 @@ function multi:newConnection(protect,func,kill)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if name then
|
if name then
|
||||||
connections[name]=temp
|
connections[name]=temp
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.callback then
|
if self.callback then
|
||||||
self.callback(temp)
|
self.callback(temp)
|
||||||
end
|
end
|
||||||
|
|
||||||
return temp
|
return temp
|
||||||
end
|
end
|
||||||
function c:connect(...)--func,name,num
|
|
||||||
|
function c:Connect(...)--func,name,num
|
||||||
local tab = {...}
|
local tab = {...}
|
||||||
local funcs={}
|
local funcs={}
|
||||||
for i=1,#tab do
|
for i=1,#tab do
|
||||||
@ -320,7 +323,14 @@ function multi:newConnection(protect,func,kill)
|
|||||||
return conn_helper(self,tab[1],tab[2],tab[3])
|
return conn_helper(self,tab[1],tab[2],tab[3])
|
||||||
end
|
end
|
||||||
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
|
c.GetConnection = c.getConnection
|
||||||
if not(ignoreconn) then
|
if not(ignoreconn) then
|
||||||
multi:create(c)
|
multi:create(c)
|
||||||
@ -1244,9 +1254,8 @@ local startme_len = 0
|
|||||||
function thread:newThread(name,func,...)
|
function thread:newThread(name,func,...)
|
||||||
multi.OnLoad:Fire() -- This was done incase a threaded function was called before mainloop/uManager was called
|
multi.OnLoad:Fire() -- This was done incase a threaded function was called before mainloop/uManager was called
|
||||||
local func = func or name
|
local func = func or name
|
||||||
|
if func == name then
|
||||||
if type(name) == "function" then
|
name = name or multi.randomString(16)
|
||||||
name = "Thread#"..threadCount
|
|
||||||
end
|
end
|
||||||
local c={nil,nil,nil,nil,nil,nil,nil}
|
local c={nil,nil,nil,nil,nil,nil,nil}
|
||||||
local env = {self=c}
|
local env = {self=c}
|
||||||
|
|||||||
@ -22,9 +22,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
]]
|
]]
|
||||||
local multi, thread = require("multi"):init()
|
local multi, thread = require("multi"):init()
|
||||||
|
if not (GLOBAL and THREAD) then
|
||||||
local GLOBAL, THREAD = multi.integration.GLOBAL,multi.integration.THREAD
|
local GLOBAL, THREAD = multi.integration.GLOBAL,multi.integration.THREAD
|
||||||
|
else
|
||||||
|
lanes = require("lanes")
|
||||||
|
end
|
||||||
function multi:newSystemThreadedQueue(name)
|
function multi:newSystemThreadedQueue(name)
|
||||||
|
local name = name or multi.randomString(16)
|
||||||
local c = {}
|
local c = {}
|
||||||
|
c.Name = name
|
||||||
c.linda = lanes.linda()
|
c.linda = lanes.linda()
|
||||||
function c:push(v)
|
function c:push(v)
|
||||||
self.linda:send("Q", v)
|
self.linda:send("Q", v)
|
||||||
@ -41,9 +47,12 @@ function multi:newSystemThreadedQueue(name)
|
|||||||
GLOBAL[name or "_"] = c
|
GLOBAL[name or "_"] = c
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
|
|
||||||
function multi:newSystemThreadedTable(name)
|
function multi:newSystemThreadedTable(name)
|
||||||
|
local name = name or multi.randomString(16)
|
||||||
local c = {}
|
local c = {}
|
||||||
c.link = lanes.linda()
|
c.link = lanes.linda()
|
||||||
|
c.Name = name
|
||||||
setmetatable(c,{
|
setmetatable(c,{
|
||||||
__index = function(t,k)
|
__index = function(t,k)
|
||||||
return c.link:get(k)
|
return c.link:get(k)
|
||||||
@ -58,14 +67,15 @@ function multi:newSystemThreadedTable(name)
|
|||||||
GLOBAL[name or "_"] = c
|
GLOBAL[name or "_"] = c
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
|
|
||||||
function multi:newSystemThreadedJobQueue(n)
|
function multi:newSystemThreadedJobQueue(n)
|
||||||
local c = {}
|
local c = {}
|
||||||
c.cores = n or THREAD.getCores()*2
|
c.cores = n or THREAD.getCores()*2
|
||||||
c.OnJobCompleted = multi:newConnection()
|
c.OnJobCompleted = multi:newConnection()
|
||||||
local funcs = multi:newSystemThreadedTable()
|
local funcs = multi:newSystemThreadedTable():init()
|
||||||
local queueJob = multi:newSystemThreadedQueue()
|
local queueJob = multi:newSystemThreadedQueue():init()
|
||||||
local queueReturn = multi:newSystemThreadedQueue()
|
local queueReturn = multi:newSystemThreadedQueue():init()
|
||||||
local doAll = multi:newSystemThreadedQueue()
|
local doAll = multi:newSystemThreadedQueue():init()
|
||||||
local ID=1
|
local ID=1
|
||||||
local jid = 1
|
local jid = 1
|
||||||
function c:isEmpty()
|
function c:isEmpty()
|
||||||
@ -169,3 +179,120 @@ function multi:newSystemThreadedJobQueue(n)
|
|||||||
end
|
end
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function multi:newSystemThreadedConnection(name)
|
||||||
|
local name = name or multi.randomString(16)
|
||||||
|
local c = {}
|
||||||
|
c.CONN = 0x00
|
||||||
|
c.TRIG = 0x01
|
||||||
|
c.PING = 0x02
|
||||||
|
c.PONG = 0x03
|
||||||
|
local 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
|
||||||
|
c.CID = THREAD.getID()
|
||||||
|
c.subscribe = multi:newSystemThreadedQueue("SUB_STC_"..self.Name):init()
|
||||||
|
c.Name = name
|
||||||
|
c.links = {} -- All triggers sent from main connection. When a connection is triggered on another thread, they speak to the main then send stuff out.
|
||||||
|
-- Locals will only live in the thread that creates the original object
|
||||||
|
local ping
|
||||||
|
local pong = function(link, links)
|
||||||
|
local res = thread.hold(function()
|
||||||
|
return link:peek()[1] == c.PONG
|
||||||
|
end,{sleep=3})
|
||||||
|
|
||||||
|
if not res then
|
||||||
|
self.links = remove(self.links, pings)
|
||||||
|
else
|
||||||
|
link:pop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ping = thread:newFunction(function(self)
|
||||||
|
ping:Pause()
|
||||||
|
multi.ForEach(self.links, function(link) -- Sync new connections
|
||||||
|
link:push{self.PING}
|
||||||
|
multi:newThread("pong Thread", pong, link, links)
|
||||||
|
end)
|
||||||
|
|
||||||
|
thread.sleep(3)
|
||||||
|
|
||||||
|
ping:Resume()
|
||||||
|
end,false)
|
||||||
|
|
||||||
|
thread:newThread("STC_SUB_MAN"..name,function()
|
||||||
|
local item
|
||||||
|
while true do
|
||||||
|
thread.yield()
|
||||||
|
-- We need to check on broken connections
|
||||||
|
ping(c) -- Should return instantlly and process this in another thread
|
||||||
|
item = thread.hold(function() -- This will keep things held up until there is something to process
|
||||||
|
return c.subscribe:pop()
|
||||||
|
end)
|
||||||
|
if item[1] == c.CONN then
|
||||||
|
multi.ForEach(c.links, function(link) -- Sync new connections
|
||||||
|
item[2]:push{c.CONN, link}
|
||||||
|
end)
|
||||||
|
c.links[#c.links+1] = item[2]
|
||||||
|
elseif item[1] == c.TRIG then
|
||||||
|
c:Fire(unpack(item[2]))
|
||||||
|
c.proxy_conn:Fire(unpack(item[2]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
--- ^^^ This will only exist in the init thread
|
||||||
|
|
||||||
|
function c:Fire(...)
|
||||||
|
local args = {...}
|
||||||
|
if self.CID == THREAD.getID() then -- Host Call
|
||||||
|
for _, link in pairs(self.links) do
|
||||||
|
link:push {self.TRIG, args}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.subscribe:push {self.TRIG, args}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function c:init()
|
||||||
|
local multi, thread = require("multi"):init()
|
||||||
|
self.links = {}
|
||||||
|
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})
|
||||||
|
thread:newThread("STC_CONN_MAN"..name,function()
|
||||||
|
local item
|
||||||
|
local link_self_ref = multi:newSystemThreadedQueue()
|
||||||
|
self.subscribe:push{self.CONN, link_self_ref}
|
||||||
|
while true do
|
||||||
|
item = thread.hold(function()
|
||||||
|
return link_self_ref:peek()
|
||||||
|
end)
|
||||||
|
if item[1] == self.PING then
|
||||||
|
link_self_ref:push{self.PONG}
|
||||||
|
link_self_ref:pop()
|
||||||
|
elseif item[1] == self.CONN then
|
||||||
|
if item[2].Name ~= link_self_ref.Name then
|
||||||
|
table.insert(self.links, item[2])
|
||||||
|
end
|
||||||
|
link_self_ref:pop()
|
||||||
|
elseif item[1] == self.TRIG then
|
||||||
|
self.proxy_conn:Fire(unpack(item[2]))
|
||||||
|
link_self_ref:pop()
|
||||||
|
else
|
||||||
|
-- This shouldn't be the case
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
GLOBAL[name] = c
|
||||||
|
|
||||||
|
return c
|
||||||
|
end
|
||||||
@ -62,6 +62,7 @@ function THREAD:newFunction(func,holdme)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function multi:newSystemThread(name, func, ...)
|
function multi:newSystemThread(name, func, ...)
|
||||||
|
local name = name or multi.randomString(16)
|
||||||
multi.InitSystemThreadErrorHandler()
|
multi.InitSystemThreadErrorHandler()
|
||||||
local rand = math.random(1, 10000000)
|
local rand = math.random(1, 10000000)
|
||||||
local return_linda = lanes.linda()
|
local return_linda = lanes.linda()
|
||||||
@ -87,6 +88,7 @@ function multi:newSystemThread(name, func, ...)
|
|||||||
},
|
},
|
||||||
priority=c.priority
|
priority=c.priority
|
||||||
},function(...)
|
},function(...)
|
||||||
|
require("multi.integration.lanesManager.extensions")
|
||||||
local has_error = true
|
local has_error = true
|
||||||
return_linda:set("returns",{func(...)})
|
return_linda:set("returns",{func(...)})
|
||||||
has_error = false
|
has_error = false
|
||||||
|
|||||||
@ -27,6 +27,7 @@ local multi, thread = require("multi").init()
|
|||||||
GLOBAL = multi.integration.GLOBAL
|
GLOBAL = multi.integration.GLOBAL
|
||||||
THREAD = multi.integration.THREAD
|
THREAD = multi.integration.THREAD
|
||||||
function multi:newSystemThreadedQueue(name)
|
function multi:newSystemThreadedQueue(name)
|
||||||
|
local name = name or multi.randomString(16)
|
||||||
local c = {}
|
local c = {}
|
||||||
c.Name = name
|
c.Name = name
|
||||||
local fRef = {"func",nil}
|
local fRef = {"func",nil}
|
||||||
@ -64,10 +65,11 @@ function multi:newSystemThreadedQueue(name)
|
|||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newSystemThreadedTable(name)
|
function multi:newSystemThreadedTable(name)
|
||||||
|
local name = name or multi.randomString(16)
|
||||||
local c = {}
|
local c = {}
|
||||||
c.name = name
|
c.Name = name
|
||||||
function c:init()
|
function c:init()
|
||||||
return THREAD.createTable(self.name)
|
return THREAD.createTable(self.Name)
|
||||||
end
|
end
|
||||||
THREAD.package(name,c)
|
THREAD.package(name,c)
|
||||||
return c
|
return c
|
||||||
|
|||||||
@ -25,6 +25,7 @@ local multi, thread = require("multi").init()
|
|||||||
GLOBAL = multi.integration.GLOBAL
|
GLOBAL = multi.integration.GLOBAL
|
||||||
THREAD = multi.integration.THREAD
|
THREAD = multi.integration.THREAD
|
||||||
function multi:newSystemThreadedQueue(name)
|
function multi:newSystemThreadedQueue(name)
|
||||||
|
local name = name or multi.randomString(16)
|
||||||
local c = {}
|
local c = {}
|
||||||
c.Name = name
|
c.Name = name
|
||||||
local fRef = {"func",nil}
|
local fRef = {"func",nil}
|
||||||
@ -62,10 +63,11 @@ function multi:newSystemThreadedQueue(name)
|
|||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newSystemThreadedTable(name)
|
function multi:newSystemThreadedTable(name)
|
||||||
|
local name = name or multi.randomString(16)
|
||||||
local c = {}
|
local c = {}
|
||||||
c.name = name
|
c.Name = name
|
||||||
function c:init()
|
function c:init()
|
||||||
return THREAD.createTable(self.name)
|
return THREAD.createTable(self.Name)
|
||||||
end
|
end
|
||||||
THREAD.package(name,c)
|
THREAD.package(name,c)
|
||||||
return c
|
return c
|
||||||
|
|||||||
80
test.lua
80
test.lua
@ -1,20 +1,72 @@
|
|||||||
package.path = "./?/init.lua;?.lua;lua5.4/share/lua/?/init.lua;lua5.4/share/lua/?.lua;"..package.path
|
package.path = "./?/init.lua;?.lua;lua5.2/share/lua/5.2/?/init.lua;lua5.2/share/lua/5.2/?.lua;"
|
||||||
package.cpath = "lua5.4/lib/lua/?/core.dll;"..package.cpath
|
package.cpath = "lua5.2/lib/lua/5.2/?/core.dll;"
|
||||||
multi, thread = require("multi"):init{print=true}
|
multi, thread = require("multi"):init{print=true}
|
||||||
GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
|
GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
|
||||||
|
|
||||||
test = THREAD:newFunction(function()
|
local conn = multi:newSystemThreadedConnection("conn"):init()
|
||||||
PNT()
|
|
||||||
return 1,2
|
multi:newSystemThread("Thread_Test_1",function()
|
||||||
end,true)
|
local multi, thread = require("multi"):init()
|
||||||
multi:newThread(function()
|
local conn = GLOBAL["conn"]:init()
|
||||||
while true do
|
conn(function()
|
||||||
print("...")
|
print(THREAD:getName().." was triggered!")
|
||||||
thread.sleep(1)
|
end)
|
||||||
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)
|
end)
|
||||||
multi:newAlarm(.1):OnRing(function() os.exit() end)
|
|
||||||
print(test())
|
|
||||||
print("Hi!")
|
|
||||||
|
|
||||||
multi:mainloop()
|
multi:mainloop()
|
||||||
33
test2.lua
Normal file
33
test2.lua
Normal 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")
|
||||||
Loading…
x
Reference in New Issue
Block a user