diff --git a/changes.md b/changes.md index 4835289..e329a8a 100644 --- a/changes.md +++ b/changes.md @@ -96,6 +96,7 @@ multi:mainloop() ``` Changed: --- +- threaded functions no longer auto detect the presence of arguments when within a threaded function. However, you can use the holup method to produce the same effect. If you plan on using a function in different ways then you can use .wait() and .connect() without setting the holup argument - thread:newFunction(func,holup) -- Added an argument holup 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. @@ -195,6 +196,7 @@ Removed: Fixed: --- +- Issue where connections object:conn() was firing based on the existance of a Type field. Now this only fires if the table contains a reference to itself. Otherwise it will connect instead of firing - Issue where async functions connect wasn't properly triggering when a function returned - Issue where async functions were not passing arguments properly. - Issue where async functions were not handling errors properly diff --git a/multi/init.lua b/multi/init.lua index da2eb76..cc5fda9 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -783,8 +783,13 @@ function multi:newConnection(protect,func,kill) c.lock = false setmetatable(c,{__call=function(self,...) local t = ... - if type(t)=="table" and t.Type ~= nil then - return self:Fire(args,select(2,...)) + if type(t)=="table" then + for i,v in pairs(t) do + if v==self then + return self:Fire(...) + end + end + return self:connect(...) else return self:connect(...) end @@ -1559,41 +1564,18 @@ function multi:newThread(name,func,...) if type(name) == "function" then name = "Thread#"..threadCount end - -- local env = {} - -- setmetatable(env,{ - -- __index = Gref, - -- __newindex = function(t,k,v) - -- if type(v)=="function" then - -- rawset(t,k,thread:newFunction(v)) - -- else - -- if type(v)=="table" then - -- if v.isTFunc then - -- if not _G["_stack_"] or #_G["_stack_"]==0 then - -- _G["_stack_"] = {} - -- local s = _G["_stack_"] - -- local a,b,c,d,e,f,g = v.wait(true) - -- table.insert(s,a) - -- table.insert(s,b) - -- table.insert(s,c) - -- table.insert(s,d) - -- table.insert(s,e) - -- table.insert(s,f) - -- local x = table.remove(_G["_stack_"]) - -- rawset(t,k,x) - -- else - -- local x = table.remove(_G["_stack_"]) - -- rawset(t,k,x) - -- end - -- else - -- Gref[k]=v - -- end - -- else - -- Gref[k]=v - -- end - -- end - -- end - -- }) - -- setfenv(func,env) + local env = {} + setmetatable(env,{ + __index = Gref, + __newindex = function(t,k,v) + if type(v)=="function" then + rawset(t,k,thread:newFunction(v)) + else + Gref[k]=v + end + end + }) + setfenv(func,env) local c={} c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil} c.startArgs = {...} diff --git a/test.lua b/test.lua index 832e28a..2fbb34e 100644 --- a/test.lua +++ b/test.lua @@ -1,24 +1,78 @@ package.path="?.lua;?/init.lua;?.lua;"..package.path local multi, thread = require("multi"):init() -func = thread:newFunction(function() - thread.sleep(math.random(1,3)) - local t = math.random(1,10) - return t +function multi:newService(func) -- Priority managed threads + local c = {} + c.Type = "Service" + c.OnError = multi:newConnection() + c.OnStopped = multi:newConnection() + c.OnStarted = multi:newConnection() + local data = {} + local active = false + local time = multi:newTimer() + local p = multi.Priority_Normal + local scheme = 1 + local function process() + thread.hold(function() + return active + end) + func(c,data) + if scheme == 1 then + if (p^(1/3))/10 == .1 then + thread.yield() + else + thread.sleep((p^(1/3))/10) + end + elseif scheme == 2 then + thread.skip(math.abs(p-1)*32+1) + end + end + multi:newThread(function() + while true do + process() + end + end).OnError = c.OnError -- use the threads onerror as our own + function c.SetScheme(n) + scheme = n + end + function c.Stop() + c:OnStopped(c) + time:Reset() + time:Pause() + data = {} + time = {} + active = false + end + function c.Pause() + time:Pause() + active = false + end + function c.Resume() + time:Resume() + active = true + end + function c.Start() + c:OnStarted(c) + time:Start() + active = true + end + function c.getUpTime() + return time:Get() + end + function c.setPriority(pri) + p = pri + end + return c +end +serv = multi:newService(function(self,data) + thread.sleep(1) + error("sorry i crashed :'(") end) -func().connect(function(a) - print(a) +serv.OnError(function(...) + print(...) end) -func().connect(function(a) - print(a) +serv.OnStarted(function(t) + print("Started!",t.Type) end) -func().connect(function(a) - print(a) -end) -func().connect(function(a) - print(a) -end) -func().connect(function(a) - print(a) -end) ---os.exit() +serv:Start() +serv:setPriority(multi.Priority_Idle) multi:mainloop() \ No newline at end of file