From d25893566e4ea9792edb2472132e1908c1fff48d Mon Sep 17 00:00:00 2001 From: Redo0 Date: Tue, 25 May 2021 17:11:48 -0500 Subject: [PATCH] make sim global; make nonessential queues optional --- StartBackend.bat | 5 +-- sim/gate.lua | 20 ++++++------ sim/gatedef.lua | 6 ++-- sim/group.lua | 34 ++++++++++---------- sim/main.lua | 8 ++--- sim/port.lua | 17 +++------- sim/simulation.lua | 78 ++++++++++++++++++++++++++++++++++------------ sim/wire.lua | 9 ++---- 8 files changed, 99 insertions(+), 78 deletions(-) diff --git a/StartBackend.bat b/StartBackend.bat index 2086b42..c235c09 100644 --- a/StartBackend.bat +++ b/StartBackend.bat @@ -3,5 +3,6 @@ set savefolder=savedata if not exist %savefolder% mkdir %savefolder% set saveloc=%cd%\%savefolder%\ cd "sim" -luajit "main.lua" %saveloc% -pause \ No newline at end of file + +luajit -jp "main.lua" %saveloc% +pause diff --git a/sim/gate.lua b/sim/gate.lua index 7b6b28b..7e64d3b 100644 --- a/sim/gate.lua +++ b/sim/gate.lua @@ -5,16 +5,18 @@ FFI.cdef[[ struct Gate { int objref; int definition_objref; + bool in_queue; struct Port ports[1]; }; ]] -function Gate.new(self, objref, definition, sim) +function Gate.new(self, objref, definition) local o = { objref = objref, definition = definition, ports = {}, - sim = sim, + in_queue = false, + logic = definition.logic, } setmetatable(o, self) self.__index = self @@ -27,7 +29,7 @@ function Gate.addport(self, port) end function Gate.getportstate(self, index) - return Port.getinputstate(self.ports[index]) + return self.ports[index].group.state end function Gate.setportstate(self, index, state) @@ -51,19 +53,15 @@ function Gate.getportisfalling(self, index) end function Gate.cb(gate, ...) - Simulation.queuecallback(Gate.getsim(gate), gate, ...) + Simulation.queuecallback(GSim, gate, ...) end function Gate.queue(gate, delay) - Simulation.queuegatelater(Gate.getsim(gate), gate, delay) + Simulation.queuegatelater(GSim, gate, delay) end function Gate.gettick(gate) - return Gate.getsim(gate).currenttick -end - -function Gate.getsim(gate) - return gate.sim + return GSim.currenttick end function Gate.getdefinition(gate) @@ -77,7 +75,7 @@ function Gate.init(gate) end function Gate.logic(gate) - Gate.getdefinition(gate).logic(gate) + gate.logic(gate) end function Gate.input(gate, argv) diff --git a/sim/gatedef.lua b/sim/gatedef.lua index 30d5487..c9c537c 100644 --- a/sim/gatedef.lua +++ b/sim/gatedef.lua @@ -58,8 +58,8 @@ function GateDefinition.new(self, objref, name, description, init, logic, input, return o end -function GateDefinition.constructgate(def, objref, position, rotation, sim) - local gate = Gate.new(Gate, objref, def, sim) +function GateDefinition.constructgate(def, objref, position, rotation) + local gate = Gate.new(Gate, objref, def) for i = 1, #def.ports do local portd = def.ports[i] @@ -84,7 +84,7 @@ function GateDefinition.constructgate(def, objref, position, rotation, sim) pos[2] = x end - Gate.addport(gate, Port.new(Port, type, dir, {position[1]+pos[1], position[2]+pos[2], position[3]+pos[3]}, portd.causeupdate, Gate.getsim(gate))) + Gate.addport(gate, Port.new(Port, type, dir, {position[1]+pos[1], position[2]+pos[2], position[3]+pos[3]}, portd.causeupdate)) end return gate diff --git a/sim/group.lua b/sim/group.lua index f278485..4fffb05 100644 --- a/sim/group.lua +++ b/sim/group.lua @@ -6,6 +6,7 @@ FFI.cdef[[ struct Net { bool state; bool fxstate; + bool in_queue; int updatetick; int internal_ref; int state_num; @@ -14,7 +15,7 @@ FFI.cdef[[ }; ]] -function Group.new(self, sim) +function Group.new(self) local o = { state = false, fxstate = false, @@ -25,12 +26,11 @@ function Group.new(self, sim) in_ports_update = {}, state_num = 0, + in_queue = false, nwires = 0, nout_ports = 0, nin_ports = 0, - - sim = sim, } setmetatable(o, self) self.__index = self @@ -51,7 +51,7 @@ function Group.addwire(self, wire) Wire.setgroup(wire, self) Wire.update(wire) - Simulation.queuegroup(Group.getsim(self), self) + Simulation.queuegroup(GSim, self) end end end @@ -60,7 +60,7 @@ function Group.removewire(self, wire) Wire.setgroup(wire, nil) self.wires[wire] = nil - local sim = Group.getsim(self) + local sim = GSim for k, wire in pairs(self.wires) do Wire.setgroup(wire, nil) @@ -94,7 +94,7 @@ function Group.removewire(self, wire) self.nout_ports = 0 self.nin_ports = 0 - Simulation.dequeuegroup(Group.getsim(self), self) + Simulation.dequeuegroup(GSim, self) end function Group.addport(self, port) @@ -110,7 +110,7 @@ function Group.addport(self, port) self.state_num = self.state_num + 1 end - Simulation.queuegroup(Group.getsim(self), self) + Simulation.queuegroup(GSim, self) elseif port.type == PortTypes.input then if self.in_ports[port] then error("port already in group") end @@ -121,7 +121,7 @@ function Group.addport(self, port) self.in_ports_update[port] = port end - Simulation.queuegate(Port.getsim(port), Port.getgate(port)) + Simulation.queuegate(GSim, Port.getgate(port)) end end @@ -139,7 +139,7 @@ function Group.removeport(self, port) self.state_num = self.state_num - 1 end - Simulation.queuegroup(Group.getsim(self), self) + Simulation.queuegroup(GSim, self) elseif port.type == PortTypes.input then if not self.in_ports[port] then error("port not in group") end @@ -150,7 +150,7 @@ function Group.removeport(self, port) self.in_ports_update[port] = nil end - Simulation.queuegate(Port.getsim(port), Port.getgate(port)) + Simulation.queuegate(GSim, Port.getgate(port)) end end @@ -188,26 +188,24 @@ function Group.mergeinto(self, group) self.nout_ports = 0 self.nin_ports = 0 - Simulation.dequeuegroup(Group.getsim(self), self) + Simulation.dequeuegroup(GSim, self) end function Group.setstate(self, state) if state ~= self.state then + local sim = GSim + self.state = state - self.updatetick = Group.getsim(self).currenttick + self.updatetick = sim.currenttick for k, port in pairs(self.in_ports_update) do - Simulation.queuegate(Port.getsim(port), Port.getgate(port)) + Simulation.queuegate(sim, Port.getgate(port)) end - Simulation.queuegroupfx(Group.getsim(self), self) + Simulation.queuegroupfx(sim, self) end end -function Group.getsim(group) - return group.sim -end - function Group.update(group) Group.setstate(group, group.state_num>0) end diff --git a/sim/main.lua b/sim/main.lua index ac02d0b..abc1268 100644 --- a/sim/main.lua +++ b/sim/main.lua @@ -149,7 +149,7 @@ while 1 do local max = vectotable(data[i+4]) local bounds = {min[1], min[2], min[3], max[1], max[2], max[3]} - local wire = Wire.new(Wire, tonumber(data[i+1]), tonumber(data[i+2]), bounds, sim) + local wire = Wire.new(Wire, tonumber(data[i+1]), tonumber(data[i+2]), bounds) Simulation.addwire(sim, wire) i = i + 4 @@ -161,12 +161,12 @@ while 1 do local position = vectotable(data[i+3]) local rotation = tonumber(data[i+4]) - local gate = GateDefinition.constructgate(definition, objref, position, rotation, sim) + local gate = GateDefinition.constructgate(definition, objref, position, rotation) Simulation.addgate(sim, gate) --print(gate.objref) - Gate.init(gate) - Gate.logic(gate) + --Gate.init(gate) + --Gate.logic(gate) i = i + 4 elseif data[i] == "RW" then diff --git a/sim/port.lua b/sim/port.lua index 277bc45..9af0026 100644 --- a/sim/port.lua +++ b/sim/port.lua @@ -29,7 +29,7 @@ FFI.cdef[[ }; ]] -function Port.new(self, type, direction, position, causeupdate, sim) +function Port.new(self, type, direction, position, causeupdate) local o = { type = type, direction = direction, @@ -38,7 +38,6 @@ function Port.new(self, type, direction, position, causeupdate, sim) state = false, gate = nil, group = nil, - sim = sim, } setmetatable(o, self) self.__index = self @@ -53,7 +52,7 @@ function Port.setstate(port, state) -- output state else Port.getgroup(port).state_num = Port.getgroup(port).state_num - 1 end - Simulation.queuegroup(Port.getsim(port), Port.getgroup(port)) + Simulation.queuegroup(GSim, Port.getgroup(port)) end end @@ -66,14 +65,14 @@ function Port.isrising(port) if port.group == nil then return false end - return port.group.state and (port.group.updatetick == Port.getsim(port).currenttick) + return port.group.state and (port.group.updatetick == GSim.currenttick) end function Port.isfalling(port) if port.group == nil then return false end - return port.group.state == false and (port.updatetick == Port.getsim(port).currenttick) + return port.group.state == false and (port.updatetick == GSim.currenttick) end function Port.getgate(port) @@ -99,11 +98,3 @@ end function Port.getstate(port) return port.state end - -function Port.getinputstate(port) - return Port.getgroup(port).state -end - -function Port.getsim(port) - return port.sim -end diff --git a/sim/simulation.lua b/sim/simulation.lua index 39ae01a..44cd992 100644 --- a/sim/simulation.lua +++ b/sim/simulation.lua @@ -18,8 +18,10 @@ function Simulation.new(self) initqueue = {}, inputqueue = {}, tickqueue = {}, + inputqueue_nonempty = false, + initqueue_nonempty = false, - callbacks = {}, + callbacks = nil, currenttick = 0 } @@ -114,6 +116,9 @@ function Simulation.addgate(self, gate) end self.ngates = self.ngates + 1 + + Simulation.queuegateinit(self, gate) + Simulation.queuegate(self, gate) end function Simulation.removewire(self, objref) @@ -214,7 +219,7 @@ function Simulation.connectwire(self, wire) end if Wire.getgroup(wire)==nil then - Group.addwire(Group.new(Group, self), wire) + Group.addwire(Group.new(Group), wire) end end @@ -228,12 +233,15 @@ function Simulation.connectport(self, port) end if Port.getgroup(port) == nil then - Group.addport(Group.new(Group, self), port) + Group.addport(Group.new(Group), port) end end function Simulation.queuegate(self, gate) - self.gatequeue[gate] = gate + if not gate.in_queue then + table.insert(self.gatequeue, gate) + gate.in_queue = true + end end function Simulation.queuegatelater(self, gate, delay) @@ -247,23 +255,44 @@ end function Simulation.queuegateinput(self, gate, argv) self.inputqueue[gate] = self.inputqueue[gate] or {} table.insert(self.inputqueue[gate], argv) + self.inputqueue_nonempty = true end function Simulation.queuegateinit(self, gate) self.initqueue[gate] = gate + self.initqueue_nonempty = true end function Simulation.queuegroup(self, group) - self.groupqueue[group] = group + if not group.in_queue then + table.insert(self.groupqueue, group) + group.in_queue = true + end +end + +local function array_remove(array, value) + for i = 1, #array do + local v = array[i] + if v==value then + array[i] = array[#array] + array[#array] = nil + return + end + end + error("element not in array") end function Simulation.dequeuegroup(self, group) - self.groupqueue[group] = nil + if group.in_queue then + array_remove(self.groupqueue, group) + end self.groupfxqueue[group] = nil end function Simulation.dequeuegate(self, gate) - self.gatequeue[gate] = nil + if gate.in_queue then + array_remove(self.gatequeue, gate) + end self.initqueue[gate] = nil self.inputqueue[gate] = nil for tick, tickq in pairs(self.tickqueue) do @@ -276,26 +305,34 @@ function Simulation.queuegroupfx(self, group) end function Simulation.queuecallback(self, gate, ...) + self.callbacks = self.callbacks or {} self.callbacks[gate.objref] = {...} end function Simulation.tick(self) - for k, group in pairs(self.groupqueue) do + for k, group in ipairs(self.groupqueue) do Group.update(group) + group.in_queue = false end self.groupqueue = {} - for k, gate in pairs(self.initqueue) do - Gate.init(gate) - end - self.initqueue = {} - - for gate, inputs in pairs(self.inputqueue) do - for inputidx, argv in ipairs(inputs) do - Gate.input(gate, argv) + if self.initqueue_nonempty then + for k, gate in pairs(self.initqueue) do + Gate.init(gate) end + self.initqueue = {} + self.initqueue_nonempty = false + end + + if self.inputqueue_nonempty then + for gate, inputs in pairs(self.inputqueue) do + for inputidx, argv in ipairs(inputs) do + Gate.input(gate, argv) + end + end + self.inputqueue = {} + self.inputqueue_nonempty = false end - self.inputqueue = {} if self.tickqueue[self.currenttick] ~= nil then for i, gate in pairs(self.tickqueue[self.currenttick]) do @@ -304,8 +341,9 @@ function Simulation.tick(self) self.tickqueue[self.currenttick] = nil end - for k, gate in pairs(self.gatequeue) do + for k, gate in ipairs(self.gatequeue) do Gate.logic(gate) + gate.in_queue = false end self.gatequeue = {} @@ -331,7 +369,7 @@ function Simulation.sendfxupdate(self) end function Simulation.sendcallbacks(self) - if next(self.callbacks) ~= nil then + if self.callbacks ~= nil then local data = "CB" for objref, args in pairs(self.callbacks) do @@ -343,6 +381,6 @@ function Simulation.sendcallbacks(self) end client:send(data .. "\n") - self.callbacks = {} + self.callbacks = nil end end diff --git a/sim/wire.lua b/sim/wire.lua index eacaa43..86329e9 100644 --- a/sim/wire.lua +++ b/sim/wire.lua @@ -10,13 +10,12 @@ FFI.cdef[[ }; ]] -function Wire.new(self, objref, layer, bounds, sim) +function Wire.new(self, objref, layer, bounds) local o = { objref = objref, layer = layer, group = nil, bounds = bounds, - sim = sim, } setmetatable(o, self) self.__index = self @@ -28,7 +27,7 @@ function Wire.setlayer(self, layer) Group.removewire(self.group, self) end self.layer = layer - Simulation.connectwire(Wire.getsim(self), self) + Simulation.connectwire(GSim, self) end function Wire.update(self) @@ -54,7 +53,3 @@ end function Wire.getbounds(self) return self.bounds end - -function Wire.getsim(wire) - return wire.sim -end