added THREAD:newFunction(func)

This commit is contained in:
Ryan Ward 2020-02-08 11:04:05 -05:00
parent ec8c8c7074
commit d797875317
5 changed files with 68 additions and 17 deletions

View File

@ -6,6 +6,15 @@ Update 14.1.0 Bug Fixes and a change
```lua
package.path="?/init.lua;?.lua;"..package.path
multi,thread = require("multi"):init()
local GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
t = THREAD:newFunction(function(...)
print("This is a system threaded function!",...)
THREAD.sleep(1) -- This is handled within a system thread! Note: this creates a system thread that runs then ends. C
return "We done!"
end)
print(t("hehe",1,2,3,true).connect(function(...)
print("connected:",...)
end)) -- The same features that work with thread:newFunction() are here as well
multi.OnLoad(function()
print("Code Loaded!") -- Connect to the load event
end)
@ -68,11 +77,13 @@ end)
multi:mainloop()
```
# Changed:
- thread:newFunction(func,holdme) -- Added an argument holdme to always force the threaded funcion to wait. Meaning you don't need to tell it to func().wait() or func().connect()
- thread:newFunction(func,holup) -- Added an argument holdme to always force the threaded funcion to wait. Meaning you don't need to tell it to func().wait() or func().connect()
- multi:newConnection(protect,callback,kill) -- Added the kill argument. Makes connections work sort of like a stack. Pop off the connections as they get called. So a one time connection handler.
- I'm not sure callback has been documented in any form. callback gets called each and everytime conn:Fire() gets called! As well as being triggered for each connfunc that is part of the connection.
# Added:
- THREAD:newFunction(func,holup) -- A system threaded based variant to thread:newFunction(func,holup)
- multi:loveloop() -- Handles the run function for love2d as well as run the multi mainloop.
- multi.OnLoad(func) -- A special connection that allows you to connect to the an event that triggers when the multi engine starts! This is slightly different from multi.PreLoad(func) Which connects before any variables have been set up in the multi table, before any settings are cemented into the core. In most cases they will operate exactly the same. This is a feature that was created with module creators in mind. This way they can have code be loaded and managed before the main loop starts.
- multi.OnExit(func) -- A special connection that allows you to connect onto the lua state closing event.
```lua
@ -136,6 +147,8 @@ multi:mainloop()
# Removed:
- multi:newTimeStamper() -- schedulejob replaces timestamper
# Fixed:
- love2d had an issue where threads crashing would break the mainloop
- fixed bugs within the extensions.lua file for love threading
- Modified the thread.* methods to perform better (Tables were being created each time one of these methods were called! Which in turn slowed things down. One table is modified to get things working properly)
- thread.sleep()
- thread.hold()

View File

@ -69,6 +69,20 @@ multi.OnPreLoad(function()
end
end)
end)
function multi:loveloop()
local link
link = multi:newThread(function()
local mainloop = love.run()
while true do
thread.yield()
pcall(mainloop)
end
end).OnError(function(...)
print(...)
end)
multi:mainloop()
end
multi.OnQuit(function()
multi.Stop()
love.event.quit()

View File

@ -48,6 +48,18 @@ local threads = {}
local count = 1
local started = false
local livingThreads = {}
function THREAD:newFunction(func,holup)
return function(...)
local t = multi:newSystemThread("SystemThreadedFunction",function(...)
return func(...)
end,...)
return thread:newFunction(function()
return thread.hold(function()
return t.thread:join(.001)
end)
end,holup)()
end
end
function multi:newSystemThread(name, func, ...)
multi.InitSystemThreadErrorHandler()
rand = math.random(1, 10000000)
@ -63,12 +75,10 @@ function multi:newSystemThread(name, func, ...)
c.alive = true
c.priority = thread.Priority_Normal
local args = {...}
multi.nextStep(function()
c.thread = lanes.gen(table.concat(c.loadString,","),{globals={
THREAD_NAME=name,
THREAD_ID=count
},priority=c.priority}, func)(unpack(args))
end)
c.thread = lanes.gen(table.concat(c.loadString,","),{globals={
THREAD_NAME=name,
THREAD_ID=count
},priority=c.priority}, func)(unpack(args))
count = count + 1
function c:kill()
self.thread:cancel()

View File

@ -22,7 +22,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
local multi, thread = require("multi").init()
local pad = require("multi.integration.loveManager.scratchpad")
GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD
function multi:newSystemThreadedQueue(name)
@ -82,11 +81,8 @@ function multi:newSystemThreadedJobQueue(n)
c.queueAll = love.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
c.id = 0
c.OnJobCompleted = multi:newConnection()
c._bytedata = love.data.newByteData(string.rep(status.BUSY,c.cores))
c.bytedata = pad:new(c._bytedata)
local allfunc = 0
function c:doToAll(func)
self.bytedata:write(string.rep(status.BUSY,c.cores)) -- set all variables to busy
local f = THREAD.dump(func)
for i = 1, self.cores do
self.queueAll:push({allfunc,f})
@ -97,7 +93,6 @@ function multi:newSystemThreadedJobQueue(n)
if self.funcs[name] then
error("A function by the name "..name.." has already been registered!")
end
self.bytedata:write(string.rep(status.BUSY,c.cores)) -- set all variables to busy
self.funcs[name] = func
end
function c:pushJob(name,...)
@ -115,6 +110,7 @@ function multi:newSystemThreadedJobQueue(n)
end
end
end)
print("Cores: ",c.cores)
for i=1,c.cores do
multi:newSystemThread("JobQueue_"..jqc.."_worker_"..i,function(jqc)
local multi, thread = require("multi"):init()
@ -123,8 +119,6 @@ function multi:newSystemThreadedJobQueue(n)
end
require("love.timer")
local clock = os.clock
local pad = require("multi.integration.loveManager.scratchpad")
local status = require("multi.integration.loveManager.status")
local funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table")
local queue = love.thread.getChannel("__JobQueue_"..jqc.."_queue")
local queueReturn = love.thread.getChannel("__JobQueue_"..jqc.."_queueReturn")

View File

@ -27,14 +27,16 @@ end
local ThreadFileData = [[
ISTHREAD = true
THREAD = require("multi.integration.loveManager.threads") -- order is important!
STATUS = require("multi.integration.loveManager.status")
sThread = THREAD
__IMPORTS = {...}
__FUNC__=table.remove(__IMPORTS,1)
__THREADID__=table.remove(__IMPORTS,1)
__THREADNAME__=table.remove(__IMPORTS,1)
stab = THREAD.createStaticTable(__THREADNAME__)
GLOBAL = THREAD.getGlobal()
multi, thread = require("multi").init()
THREAD.loadDump(__FUNC__)(unpack(__IMPORTS))]]
stab["returns"] = {THREAD.loadDump(__FUNC__)(unpack(__IMPORTS))}
]]
local multi, thread = require("multi.compat.love2d"):init()
local THREAD = {}
__THREADID__ = 0
@ -45,18 +47,36 @@ local THREAD = require("multi.integration.loveManager.threads")
local GLOBAL = THREAD.getGlobal()
local THREAD_ID = 1
local OBJECT_ID = 0
function THREAD:newFunction(func,holup)
return function(...)
local t = multi:newSystemThread("SystemThreadedFunction",func,...)
return thread:newFunction(function()
return thread.hold(function()
if t.stab["returns"] then
return unpack(t.stab.returns)
end
end)
end,holup)()
end
end
function multi:newSystemThread(name,func,...)
local c = {}
c.name = name
c.ID=THREAD_ID
c.thread=love.thread.newThread(ThreadFileData)
c.thread:start(THREAD.dump(func),c.ID,c.name,...)
c.stab = THREAD.createStaticTable(name)
GLOBAL["__THREAD_"..c.ID] = {ID=c.ID,Name=c.name,Thread=c.thread}
GLOBAL["__THREAD_COUNT"] = THREAD_ID
THREAD_ID=THREAD_ID+1
return c
end
function love.threaderror(thread, errorstr)
print("Thread error!\n"..errorstr)
end
multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD
require("multi.integration.loveManager.extensions")
return {init=function()
return GLOBAL,THREAD
end}