diff --git a/docs/changes.md b/docs/changes.md index 91ef5c8..c7436b4 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -299,6 +299,7 @@ Added multi:mainloop() ``` +- multi.OnObjectDestroyed(func(obj, process)) now supplies obj, process just like OnObjectCreated - 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! diff --git a/init.lua b/init.lua index e2af02c..318ff2a 100644 --- a/init.lua +++ b/init.lua @@ -584,7 +584,7 @@ function multi:Destroy() if self.Type==multi.registerType("process", "processes") or self.Type==multi.registerType("rootprocess") then local c=self:getChildren() for i=1,#c do - self.OnObjectDestroyed:Fire(c[i]) + self.OnObjectDestroyed:Fire(c[i], self) c[i]:Destroy() end local new = {} @@ -601,7 +601,7 @@ function multi:Destroy() else for i=#self.Parent.Mainloop,1,-1 do if self.Parent.Mainloop[i]==self then - self.Parent.OnObjectDestroyed:Fire(self) + self.Parent.OnObjectDestroyed:Fire(self, self.Parent) table.remove(self.Parent.Mainloop,i) self.Destroyed = true break @@ -1442,8 +1442,9 @@ end function thread:newProcessor(name, nothread, priority) -- Inactive proxy proc - local proc = multi:getCurrentProcess():newProcessor(name, true) - local thread_proc = multi:getCurrentProcess():newProcessor(name).Start() + local process = multi:getCurrentProcess() + local proc = process:newProcessor(name, true) + local thread_proc = process:newProcessor(name).Start() local Active = true local handler @@ -1458,7 +1459,7 @@ function thread:newProcessor(name, nothread, priority) end function proc:getFullName() - return thread_proc.parent:getFullName() .. "." .. c.Name + return thread_proc.parent:getFullName() .. "." .. self.Name end function proc:getName() @@ -1496,6 +1497,7 @@ function thread:newProcessor(name, nothread, priority) proc.OnObjectCreated(function(obj) if not obj.Act then return end + multi.print("Converting "..obj.Type.." to thread!") thread_proc:newThread(function() obj.reallocate = empty_func while true do @@ -1505,7 +1507,7 @@ function thread:newProcessor(name, nothread, priority) end) end) - self:create(proc) + process:create(proc) return proc end @@ -2191,7 +2193,7 @@ function multi:getLoad() end function multi:setPriority(s) - if not self.IsAnActor or self.Type == multi.registerType("process", "processes") then return end + if not self:IsAnActor() or self.Type == multi.registerType("process", "processes") then return end if type(s)=="number" then self.Priority=s elseif type(s)=='string' then @@ -2378,6 +2380,17 @@ function multi.warn(...) end end +function multi.debug(...) + if multi.defaultSettings.debugging then + local t = {} + for i,v in ipairs(multi.pack(...)) do t[#t+1] = tostring(v) end + io.write("\x1b[97mDEBUG:\x1b[0m " .. table.concat(t," ") + .. "\n" .. multi:getCurrentProcess():getFullName() + .. " " .. (multi:getCurrentTask() and multi:getCurrentTask().Type or "Unknown Type") .. "\n" .. + ((coroutine.running()) and debug.traceback((coroutine.running())) or debug.traceback()) .. "\n") + end +end + function multi.error(self, err) if type(err) == "bool" then crash = err end if type(self) == "string" then err = self end @@ -2462,12 +2475,16 @@ function multi:getHandler() return threadManager:getHandler() end +local function task_holder() + return #tasks > 0 +end + multi:newThread("Task Handler", function() while true do if #tasks > 0 then table.remove(tasks)() else - thread.yield() + thread.hold(task_holder) end end end).OnError(multi.error) diff --git a/integration/debugManager/init.lua b/integration/debugManager/init.lua index da70e03..bb6f24b 100644 --- a/integration/debugManager/init.lua +++ b/integration/debugManager/init.lua @@ -3,17 +3,55 @@ local multi, thread = require("multi"):init() multi.defaultSettings.debugging = true local dbg = {} +dbg.__index = dbg +dbg.processors = {} -local creation_hook +-- Hooks to all on object created events! +local c_cache = {} +local d_cache = {} + +local proc = multi:newProcessor("Debug_Processor").Start() + +dbg.OnObjectCreated = function(obj, process) + if c_cache[obj] then + return false + else + c_cache[obj] = true + proc:newTask(function() + c_cache[obj] = false + end) + return true + end +end .. multi:newConnection() + +dbg.OnObjectDestroyed = function(obj, process) + if d_cache[obj] then + return false + else + d_cache[obj] = true + proc:newTask(function() + d_cache[obj] = false + end) + return true + end +end .. multi:newConnection() + +local creation_hook, destruction_hook local types +local processes = {} creation_hook = function(obj, process) - local types = multi:getTypes() - print("Created: ",obj.Type, "in", process.Type, process:getFullName()) - if obj.Type == multi.PROCESS then + types = multi:getTypes() + if obj.Type == multi.PROCESS and not dbg.processors[obj] then obj.OnObjectCreated(creation_hook) + obj.OnObjectDestroyed(destruction_hook) + dbg.processors[obj] = {} end - + dbg.OnObjectCreated:Fire(obj, process) +end + +destruction_hook = function(obj, process) + dbg.OnObjectDestroyed:Fire(obj, process) end local debug_stats = {} @@ -21,24 +59,8 @@ local debug_stats = {} local tmulti = multi:getThreadManagerProcess() multi.OnObjectCreated(creation_hook) tmulti.OnObjectCreated(creation_hook) +multi.OnObjectDestroyed(destroction_hook) +tmulti.OnObjectDestroyed(destroction_hook) -multi - ---[[ - multi.ROOTPROCESS = "rootprocess" - multi.CONNECTOR = "connector" - multi.TIMEMASTER = "timemaster" - multi.PROCESS = "process" - multi.TIMER = "timer" - multi.EVENT = "event" - multi.UPDATER = "updater" - multi.ALARM = "alarm" - multi.LOOP = "loop" - multi.TLOOP = "tloop" - multi.STEP = "step" - multi.TSTEP = "tstep" - multi.THREAD = "thread" - multi.SERVICE = "service" - multi.PROXY = "proxy" - multi.THREADEDFUNCTION = "threaded_function" -]] \ No newline at end of file +-- We write to a debug interface in the multi namespace +multi.debugging = dbg diff --git a/tests/test.lua b/tests/test.lua index 806f58a..f96eeb1 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -1,7 +1,15 @@ package.path = "../?/init.lua;../?.lua;"..package.path -multi, thread = require("multi"):init{print=true,warn=true,error=true} +multi, thread = require("multi"):init{print=true,warn=true,error=true,debugging=true} require("multi.integration.priorityManager") +multi.debugging.OnObjectCreated(function(obj, process) + multi.print("Created:", obj.Type, "in", process.Type, process:getFullName()) +end) + +multi.debugging.OnObjectDestroyed(function(obj, process) + multi.print("Destroyed:", obj.Type, "in", process.Type, process:getFullName()) +end) + -- test = multi:newProcessor("Test") -- test:setPriorityScheme(multi.priorityScheme.TimeBased) @@ -68,6 +76,11 @@ proc:newThread(function() end end) +proc:newAlarm(5):OnRing(function(a) + multi.print(";) Goodbye") + a:Destroy() +end) + multi:mainloop()