diff --git a/multi/init.lua b/multi/init.lua index 34af0e6..0839c83 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -44,6 +44,10 @@ multi.clock = os.clock multi.time = os.time multi.LinkedPath = multi multi.isRunning = false +multi.defaultSettings = { + priority = 0, + protect = false, +} --Do not change these ever...Any other number will not work (Unless you are using enablePriority2()) multi.Priority_Core = 1 multi.Priority_High = 4 @@ -590,7 +594,7 @@ function multi:newConnection(protect) end end) repeat - self.Parent:uManager() + self.Parent:uManager(multi.defaultSettings) until self.waiting==false id:Destroy() end @@ -747,6 +751,7 @@ function multi:newCondition(func) end multi.NewCondition=multi.newCondition function multi:mainloop(settings) + multi.defaultSettings = settings or multi.defaultSettings if not multi.isRunning then local protect = false local priority = false @@ -838,11 +843,12 @@ function multi:uManager(settings) settings.preLoop(self) end end + multi.defaultSettings = settings or multi.defaultSettings self.uManager=self.uManagerRef end function multi:uManagerRef(settings) if self.Active then - if settings.priority==1 then + if multi.defaultSettings.priority==1 then local Loop=self.Mainloop local PS=self for _D=#Loop,1,-1 do @@ -851,7 +857,7 @@ function multi:uManagerRef(settings) if (PS.PList[P])%Loop[_D].Priority==0 then if Loop[_D].Active then self.CID=_D - if not settings.protect then + if not multi.defaultSettings.protect then Loop[_D]:Act() else local status, err=pcall(Loop[_D].Act,Loop[_D]) @@ -865,7 +871,7 @@ function multi:uManagerRef(settings) end end end - elseif settings.priority==2 then + elseif multi.defaultSettings.priority==2 then local Loop=self.Mainloop local PS=self for _D=#Loop,1,-1 do @@ -873,7 +879,7 @@ function multi:uManagerRef(settings) if (PS.PStep)%Loop[_D].Priority==0 then if Loop[_D].Active then self.CID=_D - if not settings.protect then + if not multi.defaultSettings.protect then Loop[_D]:Act() else local status, err=pcall(Loop[_D].Act,Loop[_D]) @@ -896,7 +902,7 @@ function multi:uManagerRef(settings) if Loop[_D] then if Loop[_D].Active then self.CID=_D - if not settings.protect then + if not multi.defaultSettings.protect then Loop[_D]:Act() else local status, err=pcall(Loop[_D].Act,Loop[_D]) diff --git a/multi/integration/networkManager.lua b/multi/integration/networkManager.lua index 0ed13eb..9cb84a9 100644 --- a/multi/integration/networkManager.lua +++ b/multi/integration/networkManager.lua @@ -14,6 +14,7 @@ local CMD_INITNODE = 0x05 local CMD_INITMASTER = 0x06 local CMD_GLOBAL = 0x07 local CMD_LOAD = 0x08 +local CMD_CALL = 0x09 local char = string.char local byte = string.byte @@ -45,24 +46,10 @@ end function queue:peek() return self[1] end +local queues = {} multi.OnNetQueue = multi:newConnection() multi.OnGUpdate = multi:newConnection() --- internal global system -local GLOBAL = {} -local THREAD = {} -local PROXY = {} -setmetatable(GLOBAL,{ - __index = function(t,k) - return PROXY[k] - end, - __newindex = function(t,k,v) - local v = v - PROXY[k] = v - multi.OnGUpdate:Fire(k,packData(v)) - end -}) - -- Managing the data that goes through the system local function packData(data) -- returns the data that was sterilized @@ -104,6 +91,20 @@ local function resolveData(data) end end +-- internal global system +local GLOBAL = {} +local PROXY = {} +setmetatable(GLOBAL,{ + __index = function(t,k) + return PROXY[k] + end, + __newindex = function(t,k,v) + local v = v + PROXY[k] = v + multi.OnGUpdate:Fire(k,packData(v)) + end +}) + -- The main driving force of the network manager: Nodes function multi:newNode(name,settings) -- Here we have to use the net library to broadcast our node across the network @@ -114,7 +115,8 @@ function multi:newNode(name,settings) node.server = net:newUDPServer(0) -- hosts the node using the default port node.port = node.server.port node.connections = net.ClientCache - node.queue = newQueue() + node.queue = queue:newQueue() + node.loadRate=1 if settings then if settings.crossTalk then net.OnCastedClientInfo(function(client,name,ip,port) @@ -157,30 +159,35 @@ function multi:newNode(name,settings) local name,d=dat:match("(.-)|(.+)") multi.OnNetQueue:Fire(name,d) elseif cmd == CMD_TASK then - + local args,func = dat:match("(.-)|(.+)") + func = resolveData(func) + args = resolveData(args) + func(unpack(args)) elseif cmd == CMD_INITNODE then print("Connected with another node!") - node.nodes[dat]={server,ip,port} + node.connections[dat]={server,ip,port} multi.OnGUpdate(function(k,v) server:send(ip,table.concat{char(CMD_GLOBAL),k,"|",v},port) - end) - -- set this up + end)-- set this up elseif cmd == CMD_INITMASTER then print("Connected to the master!") - node.masters[dat]={server,ip,port} + node.connections[dat]={server,ip,port} multi.OnGUpdate(function(k,v) server:send(ip,table.concat{char(CMD_GLOBAL),k,"|",v},port) - end) - -- set this up + end)-- set this up + multi:newTLoop(function() + server:send(ip,char(CMD_LOAD)..node.name.."|"..multi:getLoad(),port) + end,node.loadRate) + server:send(ip,char(CMD_LOAD)..node.name.."|"..multi:getLoad(),port) elseif cmd == CMD_GLOBAL then local k,v = dat:match("(.-)|(.+)") PROXY[k]=resolveData(v) - elseif cmd == CMD_LOAD then - local load = multi:getLoad() - server:send(ip,node.name.."|"..load,port) end end) - function node:sendTo(name,data) + function node:sendToMaster(name,data) + self.connections[name]:send(data) + end + function node:sendToNode(name,data) self.connections[name]:send(data) end node.server:broadcast("NODE_"..name) @@ -188,46 +195,79 @@ function multi:newNode(name,settings) end -- Masters -function multi:newMaster(name,settings) -- You will be able to have more than one master connecting to a node if that is what you want to do. I want you to be able to have the freedom to code any way that you want to code. +function multi:newMaster(name,settings) -- You will be able to have more than one master connecting to node(s) if that is what you want to do. I want you to be able to have the freedom to code any way that you want to code. local master = {} master.name = name master.conn = multi:newConnection() + master.conn2 = multi:newConnection() + master.OnFirstNodeConnected = multi:newConnection() master.queue = queue:newQueue() master.connections = net.ClientCache -- Link to the client cache that is created on the net interface - function master:newNetworkThread(name,func) -- If name specified then it will be sent to the specified node! Otherwise the least worked node will get the job - local fData = CMD_TASK..packData(func) + master.loads = {} + master.trigger = multi:newFunction(function(self) + master.OnFirstNodeConnected:Fire() + self:Pause() + end) + function master:newNetworkThread(tname,name,func,...) -- If name specified then it will be sent to the specified node! Otherwise the least worked node will get the job + local fData = packData(func) + local tab = {...} + local aData = "" + if #tab~=o then + aData = (packData{...}).."|" + else + aData = (packData{1,1}).."|" + end if not name then local name = self:getFreeNode() - self:sendTo(name,data) + if not name then + name = self:getRandomNode() + end + if name==nil then + multi:newTLoop(function(loop) + if name~=nil then + print("Readying Func") + self:sendTo(name,char(CMD_TASK)..aData..fData) + loop:Desrtoy() + end + end,.1) + else + self:sendTo(name,char(CMD_TASK)..aData..fData) + end else local name = "NODE_"..name - self:sendTo(name,data) + self:sendTo(name,char(CMD_TASK)..aData..fData) end end function master:sendTo(name,data) - self.connections["NODE_"..name]:send(data) + if self.connections["NODE_"..name]==nil then + multi:newTLoop(function(loop) + if self.connections["NODE_"..name]~=nil then + self.connections["NODE_"..name]:send(data) + loop:Desrtoy() + end + end,.1) + else + self.connections["NODE_"..name]:send(data) + end end function master:getFreeNode() local count = 0 - for i,v in pairs(self.connections) - v:send(CMD_LOAD) - count=count+1 - end - local list = {} - local ref = self.conn(function(name,load) - list[#list+1]={load,name} - end) - self.conn:holdUT(count) -- we need to wait until we got a response from each node - ref:Remove() -- We need to destroy that connection that we made local min = math.huge - local ref - for i = 1,#list do - if list[i][1]