Working on 16.0.0 #53

Merged
rayaman merged 120 commits from v16.0.0 into master 2024-02-25 00:00:51 -05:00
5 changed files with 164 additions and 35 deletions
Showing only changes of commit afdd98ab13 - Show all commits

View File

@ -1630,14 +1630,11 @@ function thread:newThread(name, func, ...)
c.Destroy = c.Kill
if thread.isThread() then
multi:newLoop(function(loop)
if self.Type == multi.PROCESS then
table.insert(self.startme, c)
else
table.insert(threadManager.startme, c)
end
loop:Break()
end)
if self.Type == multi.PROCESS then
table.insert(self.startme, c)
else
table.insert(threadManager.startme, c)
end
else
if self.Type == multi.PROCESS then
table.insert(self.startme, c)
@ -2411,8 +2408,8 @@ function multi.error(self, err)
else
io.write("\x1b[91mERROR:\x1b[0m " .. err .. " ?\n")
end
error("^^^ " .. multi:getCurrentProcess():getFullName() .. " " .. multi:getCurrentTask().Type .. "\n" .. debug.traceback().."\n")
if multi.defaultSettings.error then
error("^^^ " .. multi:getCurrentProcess():getFullName() .. " " .. multi:getCurrentTask().Type .. "\n" .. debug.traceback().."\n")
os.exit(1)
end
end

View File

@ -70,9 +70,8 @@ function multi:newSystemThread(name, func, ...)
local rand = math.random(1, 10000000)
local return_linda = lanes.linda()
c = {}
c.name = name
c.Name = name
c.Id = count
c.ID = count
c.loadString = {"base","package","os","io","math","table","string","coroutine"}
livingThreads[count] = {true, name}
c.returns = return_linda
@ -162,13 +161,13 @@ function multi.InitSystemThreadErrorHandler()
for i = #threads, 1, -1 do
temp = threads[i]
status = temp.thread.status
push = __StatusLinda:get(temp.Id)
push = __StatusLinda:get(temp.ID)
if push then
temp.statusconnector:Fire(multi.unpack(({__StatusLinda:receive(nil, temp.Id)})[2]))
temp.statusconnector:Fire(multi.unpack(({__StatusLinda:receive(nil, temp.ID)})[2]))
end
if status == "done" or temp.returns:get("returns") then
returns = ({temp.returns:receive(0, "returns")})[2]
livingThreads[temp.Id] = {false, temp.Name}
livingThreads[temp.ID] = {false, temp.Name}
temp.alive = false
if returns[1] == false then
temp.OnError:Fire(temp, returns[2])
@ -185,13 +184,13 @@ function multi.InitSystemThreadErrorHandler()
elseif status == "error" then
-- The thread never really errors, we handle this through our linda object
elseif status == "cancelled" then
livingThreads[temp.Id] = {false, temp.Name}
livingThreads[temp.ID] = {false, temp.Name}
temp.alive = false
temp.OnError:Fire(temp,"thread_cancelled")
GLOBAL["__THREADS__"] = livingThreads
table.remove(threads, i)
elseif status == "killed" then
livingThreads[temp.Id] = {false, temp.Name}
livingThreads[temp.ID] = {false, temp.Name}
temp.alive = false
temp.OnError:Fire(temp,"thread_killed")
GLOBAL["__THREADS__"] = livingThreads

View File

@ -1,8 +1,122 @@
if ISTHREAD then
error("You cannot require the loveManager from within a thread!")
end
local ThreadFileData = [[
ISTHREAD = true
__FUNC, THREAD_ID, THREAD_NAME, __PACK = ...
GLOBAL, THREAD = require("multi.integration.loveManager.threads"):init()
__FUNC = THREAD.unpackValue(__FUNC)
__PACK = THREAD.unpackValue(__PACK)
math.randomseed(THREAD_ID)
math.random()
math.random()
math.random()
stab = THREAD.createTable(THREAD_NAME .. THREAD_ID)
if GLOBAL["__env"] then
local env = THREAD.unpackENV(GLOBAL["__env"])
for i,v in pairs(env) do
_G[i] = v
end
end
multi, thread = require("multi"):init()
require("multi.integration.loveManager.extensions")
require("multi.integration.sharedExtensions")
stab["returns"] = {__FUNC(multi.unpack(__PACK))}
]]
_G.THREAD_NAME = "MAIN_THREAD"
_G.THREAD_ID = 0
local multi, thread = require("multi"):init()
local GLOBAL, THREAD = require("multi.integration.loveManager.threads"):init()
multi.integration = {}
multi.isMainThread = true
local threads = {}
local tid = 0
function multi:newSystemThread(name, func, ...)
multi.InitSystemThreadErrorHandler()
local name = name or multi.randomString(16)
tid = tid + 1
local c = {}
c.Type = multi.STHREAD
c.Name = name
c.ID = tid
c.thread = love.thread.newThread(ThreadFileData)
c.thread:start(THREAD.packValue(func), c.ID, c.Name, THREAD.packValue({...}))
c.stab = THREAD.createTable(name .. c.ID)
c.creationTime = os.clock()
c.OnDeath = multi:newConnection()
c.OnError = multi:newConnection()
c.status_channel = love.thread.getChannel("__status_channel__" .. c.ID)
function c:getName() return c.name end
table.insert(threads, c)
if self.isActor then
self:create(c)
else
multi.create(multi, c)
end
return c
end
local started = false
local console_channel = love.thread.getChannel("__console_channel__")
function THREAD:newFunction(func, holdme)
return thread:newFunctionBase(function(...)
return multi:newSystemThread("SystemThreaded Function Handler", func, ...)
end, holdme, multi.SFUNCTION)()
end
function love.threaderror(thread, errorstr)
multi.error("Thread error! " .. errorstr)
end
function multi.InitSystemThreadErrorHandler()
if started == true then return end
started = true
thread:newThread("Love System Thread Handler", function()
while true do
thread.yield()
for i = #threads, 1, -1 do
local th = threads[i]
if th.status_channel:peek() ~= nil then
th.statusconnector:Fire(multi.unpack(th.status_channel:pop()))
end
local th_err = th.thread:getError()
if th_err == "Thread Killed!\1" then
th.OnDeath:Fire("Thread Killed!")
table.remove(threads, i)
elseif th_err then
th.OnError:Fire(th, th_err)
table.remove(threads, i)
elseif th.stab.returns then
th.OnDeath:Fire(multi.unpack(th.stab.returns))
th.stab.returns = nil
table.remove(threads, i)
end
end
end
end)
end
THREAD.newSystemThread = function(...)
multi:newSystemThread(...)
end
multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD
require("multi.integration.loveManager.extensions")
require("multi.integration.sharedExtensions")
multi.print("Integrated Love Threading!")
return {
init = function(global_channel, console_channel, status_channel)
init = function()
return GLOBAL, THREAD
end
}

View File

@ -65,7 +65,7 @@ local function unpackValue(d)
if not status then
multi.error(data)
end
return serpent.load(data:sub(2,-1))[1]
return data[1]
else
return d
end
@ -101,8 +101,10 @@ local function createTable(n)
)
end
function INIT(global_channel, console_channel, status_channel)
local GLOBAL, THREAD = createTable("GLOBAL"), {}
function INIT()
local GLOBAL, THREAD = createTable("__GLOBAL__"), {}
local status_channel, console_channel = love.thread.getChannel("__status_channel__" .. THREAD_ID),
love.thread.getChannel("__console_channel__")
-- Non portable methods, shouldn't be used unless you know what you are doing
THREAD.packValue = packValue
@ -117,16 +119,16 @@ function INIT(global_channel, console_channel, status_channel)
return GLOBAL[name]
end
function THREAD.waitFor(name)
THREAD.waitFor = thread:newFunction(function(name)
local function wait()
math.randomseed(os.time())
love.timer.sleep(.001)
thread.yield()
end
repeat
wait()
until GLOBAL[name]
return GLOBAL[name]
end
end, true)
function THREAD.getCores()
return love.system.getProcessorCount()
@ -154,18 +156,16 @@ function INIT(global_channel, console_channel, status_channel)
end
function THREAD.pushStatus(...)
status_channel:push({THREAD_ID, multi.pack(...)})
status_channel:push(multi.pack(...))
end
_G.THREAD_ID = 0
function THREAD.sleep(n)
love.timer.sleep(n)
end
function THREAD.hold(n)
--
end
THREAD.hold = thread:newFunction(function(n)
thread.hold(n)
end, true)
function THREAD.setENV(env, name)
GLOBAL[name or "__env"] = env
@ -187,8 +187,7 @@ function INIT(global_channel, console_channel, status_channel)
end
return {
-- These are the acutal channels
init = function(global_channel, console_channel, status_channel)
return INIT(global_channel, console_channel, status_channel)
init = function()
return INIT()
end
}

View File

@ -1,7 +1,7 @@
package.path = "../?/init.lua;../?.lua;"..package.path
local multi, thread = require("multi"):init()
local GLOBAL, THREAD = require("multi.integration.loveManager"):init()
GLOBAL, THREAD = require("multi.integration.loveManager"):init()
GLOBAL["Test"] = {1,2,3, function() print("HI") end}
@ -10,8 +10,28 @@ for i,v in pairs(GLOBAL["Test"]) do
if type(v) == "function" then v() end
end
multi:newAlarm(3):OnRing(function()
GLOBAL["Test2"] = "We got a value!"
local test = multi:newSystemThread("Test",function()
print("THREAD_ID:",THREAD_ID)
GLOBAL["Test2"] = "We did it!"
eror("hahaha")
return 1,2,3
end)
test.OnDeath(function(a,b,c)
print("Thread finished!",a,b,c)
end)
test.OnError(function(self, err)
print("Got Error!",err)
end)
local func = THREAD:newFunction(function(a,b,c)
print("let's do this!",1,2,3)
return true
end)
func(1,2,3).OnReturn(function(ret)
print("Done",ret)
end)
thread:newThread(function()