THREAD_NAME set for main thread, connections break the rules for proxies
This commit is contained in:
parent
5e2ab9af3d
commit
257ed03728
@ -138,7 +138,7 @@ Added
|
|||||||
|
|
||||||
alarm = stp:newAlarm(3)
|
alarm = stp:newAlarm(3)
|
||||||
|
|
||||||
alarm.OnRing:Connect(function(alarm)
|
alarm._OnRing:Connect(function(alarm)
|
||||||
print("Hmm...", THREAD_NAME)
|
print("Hmm...", THREAD_NAME)
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
@ -148,9 +148,70 @@ Added
|
|||||||
```
|
```
|
||||||
Internally the SystemThreadedProcessor uses a JobQueue to handle things. The proxy function allows you to interact with these objects as if they were on the main thread, though there actions are carried out on the main thread.
|
Internally the SystemThreadedProcessor uses a JobQueue to handle things. The proxy function allows you to interact with these objects as if they were on the main thread, though there actions are carried out on the main thread.
|
||||||
|
|
||||||
There are currently limitations to proxies. Connection proxy do not receive events on the non thread side. So connection metamethods do not work! thread.hold(proxy.conn) does work! The backend to get this to work was annoying :P
|
Connection proxies break the rules a bit. Normally methods should always work on the thread side, however for connections in order to have actions work on the thread side you would call the connection using `obj._connName` instead of calling `obj.connName`. This allows you to have more control over connection events. See example below:
|
||||||
|
```lua
|
||||||
|
package.path = "?/init.lua;?.lua;"..package.path
|
||||||
|
|
||||||
This event is subscribed to on the proxy threads side of things!
|
multi, thread = require("multi"):init({print=true})
|
||||||
|
THREAD, GLOBAL = require("multi.integration.lanesManager"):init()
|
||||||
|
|
||||||
|
stp = multi:newSystemThreadedProcessor(8)
|
||||||
|
|
||||||
|
alarm = stp:newAlarm(3)
|
||||||
|
|
||||||
|
-- This doesn't work since this event has already been subscribed to internally on the thread to get thread.hold(alarm.OnRing) to work. But as many events to alarm.OnRing can be made!
|
||||||
|
thread:newThread(function()
|
||||||
|
print("Hold on proxied connection", thread.hold(alarm._OnRing))
|
||||||
|
end)
|
||||||
|
|
||||||
|
alarm.OnRing(function(a)
|
||||||
|
print("OnRing",a, THREAD_NAME, THREAD_ID)
|
||||||
|
end)
|
||||||
|
|
||||||
|
print("alarm.OnRing", alarm.OnRing.Type)
|
||||||
|
print("alarm._OnRing", alarm._OnRing.Type)
|
||||||
|
|
||||||
|
thread:newThread(function()
|
||||||
|
print("Hold on proxied no proxy connection", thread.hold(alarm.OnRing))
|
||||||
|
end)
|
||||||
|
|
||||||
|
thread:newThread(function()
|
||||||
|
print("Hold on proxied no proxy connection", thread.hold(alarm.OnRing))
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- This doesn't work since this event has already been subscribed to internally on the thread to get thread.hold(alarm.OnRing) to work. But as many events to alarm.OnRing can be made!
|
||||||
|
thread:newThread(function()
|
||||||
|
print("Hold on proxied connection", thread.hold(alarm._OnRing))
|
||||||
|
end)
|
||||||
|
|
||||||
|
alarm._OnRing(function(a)
|
||||||
|
print("_OnRing",a, THREAD_NAME, THREAD_ID)
|
||||||
|
a:Reset(1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
multi:mainloop()
|
||||||
|
```
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
INFO: Integrated Lanes Threading!
|
||||||
|
alarm.OnRing connector
|
||||||
|
alarm._OnRing proxy
|
||||||
|
_OnRing table: 025EB128 STJQ_cjKsEZHg 1 <-- This can change each time you run this example!
|
||||||
|
OnRing table: 018BC0C0 MAIN_THREAD 0
|
||||||
|
Hold on proxied no proxy connection table: 018BC0C0 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil
|
||||||
|
Hold on proxied no proxy connection table: 018BC0C0 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil
|
||||||
|
_OnRing table: 025EB128 STJQ_cjKsEZHg 1
|
||||||
|
OnRing table: 018BC0C0 MAIN_THREAD 0
|
||||||
|
_OnRing table: 025EB128 STJQ_cjKsEZHg 1
|
||||||
|
OnRing table: 018BC0C0 MAIN_THREAD 0
|
||||||
|
|
||||||
|
... (Will repeat ever second now)
|
||||||
|
_OnRing table: 025EB128 STJQ_cjKsEZHg 1
|
||||||
|
|
||||||
|
OnRing table: 018BC0C0 MAIN_THREAD 0
|
||||||
|
```
|
||||||
|
|
||||||
|
The proxy version can only subscribe to events on the proxy thread, which means that connection metamethods will not work with the proxy version (`_OnRing` on the non proxy thread side), but the (`OnRing`) version will work. Cleverly handling the proxy thread and the non proxy thread will allow powerful connection logic. Also this is not a full system threaded connection. **Proxies should only be used between 2 threads!** To keep things fast I'm using simple queues to transfer data. There is no guarantee that things will work!
|
||||||
|
|
||||||
Currently supporting:
|
Currently supporting:
|
||||||
- proxyLoop = STP:newLoop(...)
|
- proxyLoop = STP:newLoop(...)
|
||||||
|
|||||||
1
init.lua
1
init.lua
@ -80,6 +80,7 @@ multi.STEP = "step"
|
|||||||
multi.TSTEP = "tstep"
|
multi.TSTEP = "tstep"
|
||||||
multi.THREAD = "thread"
|
multi.THREAD = "thread"
|
||||||
multi.SERVICE = "service"
|
multi.SERVICE = "service"
|
||||||
|
multi.PROXY = "proxy"
|
||||||
|
|
||||||
if not _G["$multi"] then
|
if not _G["$multi"] then
|
||||||
_G["$multi"] = {multi = multi, thread = thread}
|
_G["$multi"] = {multi = multi, thread = thread}
|
||||||
|
|||||||
@ -36,6 +36,9 @@ lanes = require("lanes").configure()
|
|||||||
multi.SystemThreads = {}
|
multi.SystemThreads = {}
|
||||||
multi.isMainThread = true
|
multi.isMainThread = true
|
||||||
|
|
||||||
|
_G.THREAD_NAME = "MAIN_THREAD"
|
||||||
|
_G.THREAD_ID = 0
|
||||||
|
|
||||||
function multi:canSystemThread()
|
function multi:canSystemThread()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@ -32,15 +32,13 @@ THREAD = require("multi.integration.loveManager.threads")
|
|||||||
sThread = THREAD
|
sThread = THREAD
|
||||||
__IMPORTS = {...}
|
__IMPORTS = {...}
|
||||||
__FUNC__=table.remove(__IMPORTS,1)
|
__FUNC__=table.remove(__IMPORTS,1)
|
||||||
__THREADID__=table.remove(__IMPORTS,1)
|
THREAD_ID=table.remove(__IMPORTS,1)
|
||||||
__THREADNAME__=table.remove(__IMPORTS,1)
|
THREAD_NAME=table.remove(__IMPORTS,1)
|
||||||
THREAD_NAME = __THREADNAME__
|
math.randomseed(THREAD_ID)
|
||||||
THREAD_ID = __THREADID__
|
|
||||||
math.randomseed(__THREADID__)
|
|
||||||
math.random()
|
math.random()
|
||||||
math.random()
|
math.random()
|
||||||
math.random()
|
math.random()
|
||||||
stab = THREAD.createStaticTable(__THREADNAME__ .. __THREADID__)
|
stab = THREAD.createStaticTable(THREAD_NAME .. THREAD_ID)
|
||||||
GLOBAL = THREAD.getGlobal()
|
GLOBAL = THREAD.getGlobal()
|
||||||
if GLOBAL["__env"] then
|
if GLOBAL["__env"] then
|
||||||
local env = THREAD.unpackENV(GLOBAL["__env"])
|
local env = THREAD.unpackENV(GLOBAL["__env"])
|
||||||
@ -60,15 +58,15 @@ stab["returns"] = {THREAD.loadDump(__FUNC__)(multi.unpack(__IMPORTS))}
|
|||||||
local multi, thread = require("multi"):init()
|
local multi, thread = require("multi"):init()
|
||||||
|
|
||||||
local THREAD = {}
|
local THREAD = {}
|
||||||
__THREADID__ = 0
|
_G.THREAD_NAME = "MAIN_THREAD"
|
||||||
__THREADNAME__ = "MainThread"
|
_G.THREAD_ID = 0
|
||||||
multi.integration = {}
|
multi.integration = {}
|
||||||
local THREAD = require("multi.integration.loveManager.threads")
|
local THREAD = require("multi.integration.loveManager.threads")
|
||||||
local GLOBAL = THREAD.getGlobal()
|
local GLOBAL = THREAD.getGlobal()
|
||||||
local THREAD_ID = 1
|
|
||||||
multi.isMainThread = true
|
multi.isMainThread = true
|
||||||
|
|
||||||
function multi:newSystemThread(name, func, ...)
|
function multi:newSystemThread(name, func, ...)
|
||||||
|
THREAD_ID = THREAD_ID + 1
|
||||||
local c = {}
|
local c = {}
|
||||||
c.name = name
|
c.name = name
|
||||||
c.ID = THREAD_ID
|
c.ID = THREAD_ID
|
||||||
@ -79,7 +77,7 @@ function multi:newSystemThread(name, func, ...)
|
|||||||
c.OnError = multi:newConnection()
|
c.OnError = multi:newConnection()
|
||||||
GLOBAL["__THREAD_" .. c.ID] = {ID = c.ID, Name = c.name, Thread = c.thread}
|
GLOBAL["__THREAD_" .. c.ID] = {ID = c.ID, Name = c.name, Thread = c.thread}
|
||||||
GLOBAL["__THREAD_COUNT"] = THREAD_ID
|
GLOBAL["__THREAD_COUNT"] = THREAD_ID
|
||||||
THREAD_ID = THREAD_ID + 1
|
|
||||||
function c:getName() return c.name end
|
function c:getName() return c.name end
|
||||||
thread:newThread(name .. "_System_Thread_Handler",function()
|
thread:newThread(name .. "_System_Thread_Handler",function()
|
||||||
if name == "SystemThreaded Function Handler" then
|
if name == "SystemThreaded Function Handler" then
|
||||||
|
|||||||
@ -42,6 +42,8 @@ local multi, thread = require("multi.compat.lovr2d"):init()
|
|||||||
local THREAD = {}
|
local THREAD = {}
|
||||||
__THREADID__ = 0
|
__THREADID__ = 0
|
||||||
__THREADNAME__ = "MainThread"
|
__THREADNAME__ = "MainThread"
|
||||||
|
_G.THREAD_NAME = "MAIN_THREAD"
|
||||||
|
_G.THREAD_ID = 0
|
||||||
multi.integration={}
|
multi.integration={}
|
||||||
multi.integration.lovr2d={}
|
multi.integration.lovr2d={}
|
||||||
local THREAD = require("multi.integration.lovrManager.threads")
|
local THREAD = require("multi.integration.lovrManager.threads")
|
||||||
|
|||||||
@ -35,6 +35,9 @@ multi.isMainThread = true
|
|||||||
local activator = require("multi.integration.pseudoManager.threads")
|
local activator = require("multi.integration.pseudoManager.threads")
|
||||||
local GLOBAL, THREAD = activator.init(thread)
|
local GLOBAL, THREAD = activator.init(thread)
|
||||||
|
|
||||||
|
_G.THREAD_NAME = "MAIN_THREAD"
|
||||||
|
_G.THREAD_ID = 0
|
||||||
|
|
||||||
function multi:canSystemThread() -- We are emulating system threading
|
function multi:canSystemThread() -- We are emulating system threading
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@ -67,7 +67,7 @@ function multi:newProxy(list)
|
|||||||
|
|
||||||
function c:init()
|
function c:init()
|
||||||
local multi, thread = nil, nil
|
local multi, thread = nil, nil
|
||||||
if THREAD_NAME then
|
if THREAD_ID>0 then
|
||||||
local multi, thread = require("multi"):init()
|
local multi, thread = require("multi"):init()
|
||||||
local function check()
|
local function check()
|
||||||
return self.send:pop()
|
return self.send:pop()
|
||||||
@ -113,11 +113,19 @@ function multi:newProxy(list)
|
|||||||
self.Type = multi.PROXY
|
self.Type = multi.PROXY
|
||||||
for _,v in pairs(self.funcs) do
|
for _,v in pairs(self.funcs) do
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
|
-- We have a connection
|
||||||
v[2]:init()
|
v[2]:init()
|
||||||
self[v[1]] = v[2]
|
self["_"..v[1]] = v[2]
|
||||||
v[2].Parent = self
|
v[2].Parent = self
|
||||||
|
setmetatable(v[2],getmetatable(multi:newConnection()))
|
||||||
|
self[v[1]] = multi:newConnection()
|
||||||
|
|
||||||
|
thread:newThread(function()
|
||||||
|
while true do
|
||||||
|
self[v[1]]:Fire(thread.hold(alarm["_"..v[1]]))
|
||||||
|
end
|
||||||
|
end)
|
||||||
else
|
else
|
||||||
lastObj = self
|
|
||||||
self[v] = thread:newFunction(function(self,...)
|
self[v] = thread:newFunction(function(self,...)
|
||||||
if self == me then
|
if self == me then
|
||||||
me.send:push({v, true, ...})
|
me.send:push({v, true, ...})
|
||||||
@ -146,8 +154,6 @@ function multi:newProxy(list)
|
|||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
|
|
||||||
multi.PROXY = "proxy"
|
|
||||||
|
|
||||||
local targets = {}
|
local targets = {}
|
||||||
|
|
||||||
local nFunc = 0
|
local nFunc = 0
|
||||||
@ -416,6 +422,7 @@ end
|
|||||||
-- Modify thread.hold to handle proxies
|
-- Modify thread.hold to handle proxies
|
||||||
local thread_ref = thread.hold
|
local thread_ref = thread.hold
|
||||||
function thread.hold(n, opt)
|
function thread.hold(n, opt)
|
||||||
|
--if type(n) == "table" then print(n.Type, n.isConnection()) end
|
||||||
if type(n) == "table" and n.Type == multi.PROXY and n.isConnection() then
|
if type(n) == "table" and n.Type == multi.PROXY and n.isConnection() then
|
||||||
local ready = false
|
local ready = false
|
||||||
local args
|
local args
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user