From 4fe428e5728aaf14eaf5d87bf7ed47feededa3cc Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Sat, 6 May 2023 16:46:15 -0400 Subject: [PATCH] THREAD.exposeENV(), thread:newProcessor() --- docs/changes.md | 7 ++- init.lua | 48 +++++++++++--- integration/lanesManager/threads.lua | 18 ++++-- integration/loveManager/threads.lua | 19 ++++-- integration/pseudoManager/init.lua | 3 +- integration/pseudoManager/threads.lua | 19 ++++-- tests/test.lua | 91 ++++++++++++++++----------- 7 files changed, 144 insertions(+), 61 deletions(-) diff --git a/docs/changes.md b/docs/changes.md index 0667130..ec4996c 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -67,6 +67,7 @@ Allows the user to have multi auto set priorities (Requires chronos). Also adds Added --- +- thread:newProcessor(name) -- works mostly like a normal process, but all objects are wrapped within a thread. So if you create a few loops, you can use thread.hold() call threaded functions and wait and use all features that using coroutines provide. - multi.Processors:getHandler() -- returns the thread handler for a process - multi.OnPriorityChanged(self, priority) -- Connection is triggered whenever the priority of an object is changed! - multi.setClock(clock_func) -- If you have access to a clock function that works like os.clock() you can set it using this function. The priorityManager if chronos is installed sets the clock to it's current version. @@ -85,7 +86,8 @@ Added -- cause the library to force hard crash itself! } ``` -- THREAD.setENV(table) -- Set a simple table that will be merged into the global namespace +- THREAD.exposeEnv(name) -- Merges set env into the global namespace of the system thread it was called in. +- THREAD.setENV(table [, name]) -- Set a simple table that will be merged into the global namespace. If a name is supplied the global namespace will not be merged. Call THREAD.exposeEnv(name) to expose that namespace within a thread. **Note:** To maintain compatibility between each integration use simple tables. No self references, and string indices only. ```lua @@ -284,6 +286,7 @@ Fixed ToDo --- +- N/A # Update 15.3.1 - Bug fix Fixed @@ -1984,7 +1987,7 @@ L: 2120906 I: 2120506 ``` -Auto Priority works by seeing what should be set high or low. Due to lua not having more persicion than milliseconds, I was unable to have a detailed manager that can set things to high, above normal, normal, ect. This has either high or low. If a process takes longer than .001 millisecond it will be set to low priority. You can change this by using the setting auto_lowest = multi.Priority_[PLevel] the defualt is low, not idle, since idle tends to get about 1 process each second though you can change it to idle using that setting. +Auto Priority works by seeing what should be set high or low. Due to lua not having more persicion than milliseconds, I was unable to have a detailed manager that can set things to high, above normal, normal, ect. This has either high or low. If a process takes longer than .001 millisecond it will be set to low priority. You can change this by using the setting auto_lowest = multi.Priority_[PLevel] the defualt is low, not idle, since idle tends to get about 1 process each second though you can change it to idle using that setting. This is nolonger the case in version 16.0.0 multi has evolved ;) **Improved:** - Performance at the base level has been doubled! On my machine benchmark went from ~9mil to ~20 mil steps/s. diff --git a/init.lua b/init.lua index 8057a15..53cf5e8 100644 --- a/init.lua +++ b/init.lua @@ -323,9 +323,10 @@ function multi:newConnection(protect,func,kill) print(err) end if kill then - table.remove(kills,i) + table.insert(kills,i) multi:newTask(function() - for _,k in pairs(kills) do + for _, k in pairs(kills) do + table.remove(kills, _) table.remove(fast, k) end end) @@ -360,9 +361,9 @@ function multi:newConnection(protect,func,kill) if kill then table.insert(kills,i) multi:newTask(function() - for k = #kills, 1, -1 do + for _, k in pairs(kills) do + table.remove(kills, _) table.remove(fast, k) - table.remove(kills,i) end end) end @@ -1420,7 +1421,8 @@ end function thread:newProcessor(name) -- Inactive proxy proc local proc = multi:getCurrentProcess():newProcessor(name, true) - local thread_proc = multi:getCurrentProcess():newProcessor(name, true) + local thread_proc = multi:getCurrentProcess():newProcessor(name).Start() + local Active = true local handler = thread_proc:getHandler() @@ -1428,24 +1430,54 @@ function thread:newProcessor(name) return thread_proc.threads end + function proc:getFullName() + return thread_proc.parent:getFullName() .. "." .. c.Name + end + + function proc:getName() + return thread_proc.Name + end + + function proc:isActive() + return Active + end + function proc:newThread(name, func,...) return thread.newThread(thread_proc, name, func, ...) end - function c:newFunction(func, holdme) + function proc:newFunction(func, holdme) return thread:newFunctionBase(function(...) return thread_proc:newThread("Threaded Function Handler", func, ...) end, holdme)() end + + function proc.Start() + Active = true + return c + end + + function proc.Stop() + Active = false + return c + end + + function proc:Destroy() + Active = false + thread_proc:Destroy() + end proc.OnObjectCreated(function(obj) + if not obj.Act then return end thread_proc:newThread(function() + obj.reallocate = empty_func while true do - thread.yield() - -- + thread.hold(function() return Active end) + obj:Act() end end) end) + return proc end diff --git a/integration/lanesManager/threads.lua b/integration/lanesManager/threads.lua index 4ba71e7..274a562 100644 --- a/integration/lanesManager/threads.lua +++ b/integration/lanesManager/threads.lua @@ -129,12 +129,22 @@ local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda, __Console) end }) - function THREAD.setENV(env) - GLOBAL["__env"] = env + function THREAD.setENV(env, name) + name = name or "__env" + GLOBAL[name] = env end - function THREAD.getENV() - return GLOBAL["__env"] + function THREAD.getENV(name) + name = name or "__env" + return GLOBAL[name] + end + + function THREAD.exposeENV(name) + name = name or "__env" + local env = THREAD.getENV(name) + for i,v in pairs(env) do + _G[i] = v + end end return GLOBAL, THREAD diff --git a/integration/loveManager/threads.lua b/integration/loveManager/threads.lua index 250b2ec..b0de12f 100644 --- a/integration/loveManager/threads.lua +++ b/integration/loveManager/threads.lua @@ -167,12 +167,23 @@ function threads.unpackENV(env) return e end -function threads.setENV(env) - (threads.getGlobal())["__env"] = threads.packENV(env) + +function threads.setENV(env, name) + name = name or "__env" + (threads.getGlobal())[name] = threads.packENV(env) end -function threads.getENV() - return threads.unpackENV((threads.getGlobal())["__env"]) +function threads.getENV(name) + name = name or "__env" + return threads.unpackENV((threads.getGlobal())[name]) +end + +function threads.exposeENV(name) + name = name or "__env" + local env = threads.getENV(name) + for i,v in pairs(env) do + _G[i] = v + end end function threads.createTable(n) diff --git a/integration/pseudoManager/init.lua b/integration/pseudoManager/init.lua index 26a7144..d503b4d 100644 --- a/integration/pseudoManager/init.lua +++ b/integration/pseudoManager/init.lua @@ -59,13 +59,14 @@ function multi:newSystemThread(name,func,...) GLOBAL["$__THREADNAME__"] = name GLOBAL["$THREAD_ID"] = id GLOBAL["$thread"] = thread + local env = { GLOBAL = GLOBAL, THREAD = THREAD, THREAD_NAME = name, __THREADNAME__ = name, THREAD_ID = id, - thread = thread + thread = thread, } if GLOBAL["__env"] then diff --git a/integration/pseudoManager/threads.lua b/integration/pseudoManager/threads.lua index 26fc38c..6e44a23 100644 --- a/integration/pseudoManager/threads.lua +++ b/integration/pseudoManager/threads.lua @@ -96,12 +96,23 @@ local function INIT(thread) THREAD.hold = thread.hold - function THREAD.setENV(env) - GLOBAL["__env"] = env + function THREAD.setENV(env, name) + name = name or "__env" + GLOBAL[name] = env end - function THREAD.getENV() - return GLOBAL["__env"] + function THREAD.getENV(name) + name = name or "__env" + return GLOBAL[name] + end + + function THREAD.exposeENV(name) + name = name or "__env" + local env = THREAD.getENV(name) + for i,v in pairs(env) do + -- This may need to be reworked! + _G[i] = v + end end return GLOBAL, THREAD diff --git a/tests/test.lua b/tests/test.lua index 2b0e4e1..0d326f2 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -11,49 +11,64 @@ require("multi.integration.priorityManager") -- print("Running...") -local conn1, conn2 = multi:newConnection(), multi:newConnection() -conn3 = conn1 + conn2 +-- local conn1, conn2 = multi:newConnection(), multi:newConnection() +-- conn3 = conn1 + conn2 -conn1(function() - print("Hi 1") +-- conn1(function() +-- print("Hi 1") +-- end) + +-- conn2(function() +-- print("Hi 2") +-- end) + +-- conn3(function() +-- print("Hi 3") +-- end) + +-- function test(a,b,c) +-- print("I run before all and control if execution should continue!") +-- return a>b +-- end + +-- conn4 = test .. conn1 + +-- conn5 = conn2 .. function() print("I run after it all!") end + +-- conn4:Fire(3,2,3) +-- -- This second one won't trigger the Hi's +-- conn4:Fire(1,2,3) + +-- conn5(function() +-- print("Test 1") +-- end) + +-- conn5(function() +-- print("Test 2") +-- end) + +-- conn5(function() +-- print("Test 3") +-- end) + +-- conn5:Fire() +multi.print("Testing thread:newProcessor()") + +proc = thread:newProcessor("Test") + +proc:newLoop(function() + multi.print("Running...") + thread.sleep(1) end) -conn2(function() - print("Hi 2") +proc:newThread(function() + while true do + multi.warn("Everything is a thread in this proc!") + thread.sleep(1) + end end) -conn3(function() - print("Hi 3") -end) - -function test(a,b,c) - print("I run before all and control if execution should continue!") - return a>b -end - -conn4 = test .. conn1 - -conn5 = conn2 .. function() print("I run after it all!") end - -conn4:Fire(3,2,3) --- This second one won't trigger the Hi's -conn4:Fire(1,2,3) - -conn5(function() - print("Test 1") -end) - -conn5(function() - print("Test 2") -end) - -conn5(function() - print("Test 3") -end) - -conn5:Fire() - ---multi:mainloop() +multi:mainloop() -- local conn1, conn2, conn3 = multi:newConnection(nil,nil,true), multi:newConnection(), multi:newConnection()