make sim global; make nonessential queues optional

This commit is contained in:
Redo0 2021-05-25 17:11:48 -05:00
parent 53e9423ab1
commit d25893566e
8 changed files with 99 additions and 78 deletions

View File

@ -3,5 +3,6 @@ set savefolder=savedata
if not exist %savefolder% mkdir %savefolder% if not exist %savefolder% mkdir %savefolder%
set saveloc=%cd%\%savefolder%\ set saveloc=%cd%\%savefolder%\
cd "sim" cd "sim"
luajit "main.lua" %saveloc%
pause luajit -jp "main.lua" %saveloc%
pause

View File

@ -5,16 +5,18 @@ FFI.cdef[[
struct Gate { struct Gate {
int objref; int objref;
int definition_objref; int definition_objref;
bool in_queue;
struct Port ports[1]; struct Port ports[1];
}; };
]] ]]
function Gate.new(self, objref, definition, sim) function Gate.new(self, objref, definition)
local o = { local o = {
objref = objref, objref = objref,
definition = definition, definition = definition,
ports = {}, ports = {},
sim = sim, in_queue = false,
logic = definition.logic,
} }
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
@ -27,7 +29,7 @@ function Gate.addport(self, port)
end end
function Gate.getportstate(self, index) function Gate.getportstate(self, index)
return Port.getinputstate(self.ports[index]) return self.ports[index].group.state
end end
function Gate.setportstate(self, index, state) function Gate.setportstate(self, index, state)
@ -51,19 +53,15 @@ function Gate.getportisfalling(self, index)
end end
function Gate.cb(gate, ...) function Gate.cb(gate, ...)
Simulation.queuecallback(Gate.getsim(gate), gate, ...) Simulation.queuecallback(GSim, gate, ...)
end end
function Gate.queue(gate, delay) function Gate.queue(gate, delay)
Simulation.queuegatelater(Gate.getsim(gate), gate, delay) Simulation.queuegatelater(GSim, gate, delay)
end end
function Gate.gettick(gate) function Gate.gettick(gate)
return Gate.getsim(gate).currenttick return GSim.currenttick
end
function Gate.getsim(gate)
return gate.sim
end end
function Gate.getdefinition(gate) function Gate.getdefinition(gate)
@ -77,7 +75,7 @@ function Gate.init(gate)
end end
function Gate.logic(gate) function Gate.logic(gate)
Gate.getdefinition(gate).logic(gate) gate.logic(gate)
end end
function Gate.input(gate, argv) function Gate.input(gate, argv)

View File

@ -58,8 +58,8 @@ function GateDefinition.new(self, objref, name, description, init, logic, input,
return o return o
end end
function GateDefinition.constructgate(def, objref, position, rotation, sim) function GateDefinition.constructgate(def, objref, position, rotation)
local gate = Gate.new(Gate, objref, def, sim) local gate = Gate.new(Gate, objref, def)
for i = 1, #def.ports do for i = 1, #def.ports do
local portd = def.ports[i] local portd = def.ports[i]
@ -84,7 +84,7 @@ function GateDefinition.constructgate(def, objref, position, rotation, sim)
pos[2] = x pos[2] = x
end 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 end
return gate return gate

View File

@ -6,6 +6,7 @@ FFI.cdef[[
struct Net { struct Net {
bool state; bool state;
bool fxstate; bool fxstate;
bool in_queue;
int updatetick; int updatetick;
int internal_ref; int internal_ref;
int state_num; int state_num;
@ -14,7 +15,7 @@ FFI.cdef[[
}; };
]] ]]
function Group.new(self, sim) function Group.new(self)
local o = { local o = {
state = false, state = false,
fxstate = false, fxstate = false,
@ -25,12 +26,11 @@ function Group.new(self, sim)
in_ports_update = {}, in_ports_update = {},
state_num = 0, state_num = 0,
in_queue = false,
nwires = 0, nwires = 0,
nout_ports = 0, nout_ports = 0,
nin_ports = 0, nin_ports = 0,
sim = sim,
} }
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
@ -51,7 +51,7 @@ function Group.addwire(self, wire)
Wire.setgroup(wire, self) Wire.setgroup(wire, self)
Wire.update(wire) Wire.update(wire)
Simulation.queuegroup(Group.getsim(self), self) Simulation.queuegroup(GSim, self)
end end
end end
end end
@ -60,7 +60,7 @@ function Group.removewire(self, wire)
Wire.setgroup(wire, nil) Wire.setgroup(wire, nil)
self.wires[wire] = nil self.wires[wire] = nil
local sim = Group.getsim(self) local sim = GSim
for k, wire in pairs(self.wires) do for k, wire in pairs(self.wires) do
Wire.setgroup(wire, nil) Wire.setgroup(wire, nil)
@ -94,7 +94,7 @@ function Group.removewire(self, wire)
self.nout_ports = 0 self.nout_ports = 0
self.nin_ports = 0 self.nin_ports = 0
Simulation.dequeuegroup(Group.getsim(self), self) Simulation.dequeuegroup(GSim, self)
end end
function Group.addport(self, port) function Group.addport(self, port)
@ -110,7 +110,7 @@ function Group.addport(self, port)
self.state_num = self.state_num + 1 self.state_num = self.state_num + 1
end end
Simulation.queuegroup(Group.getsim(self), self) Simulation.queuegroup(GSim, self)
elseif port.type == PortTypes.input then elseif port.type == PortTypes.input then
if self.in_ports[port] then error("port already in group") end 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 self.in_ports_update[port] = port
end end
Simulation.queuegate(Port.getsim(port), Port.getgate(port)) Simulation.queuegate(GSim, Port.getgate(port))
end end
end end
@ -139,7 +139,7 @@ function Group.removeport(self, port)
self.state_num = self.state_num - 1 self.state_num = self.state_num - 1
end end
Simulation.queuegroup(Group.getsim(self), self) Simulation.queuegroup(GSim, self)
elseif port.type == PortTypes.input then elseif port.type == PortTypes.input then
if not self.in_ports[port] then error("port not in group") end 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 self.in_ports_update[port] = nil
end end
Simulation.queuegate(Port.getsim(port), Port.getgate(port)) Simulation.queuegate(GSim, Port.getgate(port))
end end
end end
@ -188,26 +188,24 @@ function Group.mergeinto(self, group)
self.nout_ports = 0 self.nout_ports = 0
self.nin_ports = 0 self.nin_ports = 0
Simulation.dequeuegroup(Group.getsim(self), self) Simulation.dequeuegroup(GSim, self)
end end
function Group.setstate(self, state) function Group.setstate(self, state)
if state ~= self.state then if state ~= self.state then
local sim = GSim
self.state = state self.state = state
self.updatetick = Group.getsim(self).currenttick self.updatetick = sim.currenttick
for k, port in pairs(self.in_ports_update) do 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 end
Simulation.queuegroupfx(Group.getsim(self), self) Simulation.queuegroupfx(sim, self)
end end
end end
function Group.getsim(group)
return group.sim
end
function Group.update(group) function Group.update(group)
Group.setstate(group, group.state_num>0) Group.setstate(group, group.state_num>0)
end end

View File

@ -149,7 +149,7 @@ while 1 do
local max = vectotable(data[i+4]) local max = vectotable(data[i+4])
local bounds = {min[1], min[2], min[3], max[1], max[2], max[3]} 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) Simulation.addwire(sim, wire)
i = i + 4 i = i + 4
@ -161,12 +161,12 @@ while 1 do
local position = vectotable(data[i+3]) local position = vectotable(data[i+3])
local rotation = tonumber(data[i+4]) 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) Simulation.addgate(sim, gate)
--print(gate.objref) --print(gate.objref)
Gate.init(gate) --Gate.init(gate)
Gate.logic(gate) --Gate.logic(gate)
i = i + 4 i = i + 4
elseif data[i] == "RW" then elseif data[i] == "RW" then

View File

@ -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 = { local o = {
type = type, type = type,
direction = direction, direction = direction,
@ -38,7 +38,6 @@ function Port.new(self, type, direction, position, causeupdate, sim)
state = false, state = false,
gate = nil, gate = nil,
group = nil, group = nil,
sim = sim,
} }
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
@ -53,7 +52,7 @@ function Port.setstate(port, state) -- output state
else else
Port.getgroup(port).state_num = Port.getgroup(port).state_num - 1 Port.getgroup(port).state_num = Port.getgroup(port).state_num - 1
end end
Simulation.queuegroup(Port.getsim(port), Port.getgroup(port)) Simulation.queuegroup(GSim, Port.getgroup(port))
end end
end end
@ -66,14 +65,14 @@ function Port.isrising(port)
if port.group == nil then if port.group == nil then
return false return false
end end
return port.group.state and (port.group.updatetick == Port.getsim(port).currenttick) return port.group.state and (port.group.updatetick == GSim.currenttick)
end end
function Port.isfalling(port) function Port.isfalling(port)
if port.group == nil then if port.group == nil then
return false return false
end end
return port.group.state == false and (port.updatetick == Port.getsim(port).currenttick) return port.group.state == false and (port.updatetick == GSim.currenttick)
end end
function Port.getgate(port) function Port.getgate(port)
@ -99,11 +98,3 @@ end
function Port.getstate(port) function Port.getstate(port)
return port.state return port.state
end end
function Port.getinputstate(port)
return Port.getgroup(port).state
end
function Port.getsim(port)
return port.sim
end

View File

@ -18,8 +18,10 @@ function Simulation.new(self)
initqueue = {}, initqueue = {},
inputqueue = {}, inputqueue = {},
tickqueue = {}, tickqueue = {},
inputqueue_nonempty = false,
initqueue_nonempty = false,
callbacks = {}, callbacks = nil,
currenttick = 0 currenttick = 0
} }
@ -114,6 +116,9 @@ function Simulation.addgate(self, gate)
end end
self.ngates = self.ngates + 1 self.ngates = self.ngates + 1
Simulation.queuegateinit(self, gate)
Simulation.queuegate(self, gate)
end end
function Simulation.removewire(self, objref) function Simulation.removewire(self, objref)
@ -214,7 +219,7 @@ function Simulation.connectwire(self, wire)
end end
if Wire.getgroup(wire)==nil then if Wire.getgroup(wire)==nil then
Group.addwire(Group.new(Group, self), wire) Group.addwire(Group.new(Group), wire)
end end
end end
@ -228,12 +233,15 @@ function Simulation.connectport(self, port)
end end
if Port.getgroup(port) == nil then if Port.getgroup(port) == nil then
Group.addport(Group.new(Group, self), port) Group.addport(Group.new(Group), port)
end end
end end
function Simulation.queuegate(self, gate) 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 end
function Simulation.queuegatelater(self, gate, delay) function Simulation.queuegatelater(self, gate, delay)
@ -247,23 +255,44 @@ end
function Simulation.queuegateinput(self, gate, argv) function Simulation.queuegateinput(self, gate, argv)
self.inputqueue[gate] = self.inputqueue[gate] or {} self.inputqueue[gate] = self.inputqueue[gate] or {}
table.insert(self.inputqueue[gate], argv) table.insert(self.inputqueue[gate], argv)
self.inputqueue_nonempty = true
end end
function Simulation.queuegateinit(self, gate) function Simulation.queuegateinit(self, gate)
self.initqueue[gate] = gate self.initqueue[gate] = gate
self.initqueue_nonempty = true
end end
function Simulation.queuegroup(self, group) 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 end
function Simulation.dequeuegroup(self, group) function Simulation.dequeuegroup(self, group)
self.groupqueue[group] = nil if group.in_queue then
array_remove(self.groupqueue, group)
end
self.groupfxqueue[group] = nil self.groupfxqueue[group] = nil
end end
function Simulation.dequeuegate(self, gate) 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.initqueue[gate] = nil
self.inputqueue[gate] = nil self.inputqueue[gate] = nil
for tick, tickq in pairs(self.tickqueue) do for tick, tickq in pairs(self.tickqueue) do
@ -276,26 +305,34 @@ function Simulation.queuegroupfx(self, group)
end end
function Simulation.queuecallback(self, gate, ...) function Simulation.queuecallback(self, gate, ...)
self.callbacks = self.callbacks or {}
self.callbacks[gate.objref] = {...} self.callbacks[gate.objref] = {...}
end end
function Simulation.tick(self) function Simulation.tick(self)
for k, group in pairs(self.groupqueue) do for k, group in ipairs(self.groupqueue) do
Group.update(group) Group.update(group)
group.in_queue = false
end end
self.groupqueue = {} self.groupqueue = {}
for k, gate in pairs(self.initqueue) do if self.initqueue_nonempty then
Gate.init(gate) for k, gate in pairs(self.initqueue) do
end Gate.init(gate)
self.initqueue = {}
for gate, inputs in pairs(self.inputqueue) do
for inputidx, argv in ipairs(inputs) do
Gate.input(gate, argv)
end 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 end
self.inputqueue = {}
if self.tickqueue[self.currenttick] ~= nil then if self.tickqueue[self.currenttick] ~= nil then
for i, gate in pairs(self.tickqueue[self.currenttick]) do for i, gate in pairs(self.tickqueue[self.currenttick]) do
@ -304,8 +341,9 @@ function Simulation.tick(self)
self.tickqueue[self.currenttick] = nil self.tickqueue[self.currenttick] = nil
end end
for k, gate in pairs(self.gatequeue) do for k, gate in ipairs(self.gatequeue) do
Gate.logic(gate) Gate.logic(gate)
gate.in_queue = false
end end
self.gatequeue = {} self.gatequeue = {}
@ -331,7 +369,7 @@ function Simulation.sendfxupdate(self)
end end
function Simulation.sendcallbacks(self) function Simulation.sendcallbacks(self)
if next(self.callbacks) ~= nil then if self.callbacks ~= nil then
local data = "CB" local data = "CB"
for objref, args in pairs(self.callbacks) do for objref, args in pairs(self.callbacks) do
@ -343,6 +381,6 @@ function Simulation.sendcallbacks(self)
end end
client:send(data .. "\n") client:send(data .. "\n")
self.callbacks = {} self.callbacks = nil
end end
end end

View File

@ -10,13 +10,12 @@ FFI.cdef[[
}; };
]] ]]
function Wire.new(self, objref, layer, bounds, sim) function Wire.new(self, objref, layer, bounds)
local o = { local o = {
objref = objref, objref = objref,
layer = layer, layer = layer,
group = nil, group = nil,
bounds = bounds, bounds = bounds,
sim = sim,
} }
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
@ -28,7 +27,7 @@ function Wire.setlayer(self, layer)
Group.removewire(self.group, self) Group.removewire(self.group, self)
end end
self.layer = layer self.layer = layer
Simulation.connectwire(Wire.getsim(self), self) Simulation.connectwire(GSim, self)
end end
function Wire.update(self) function Wire.update(self)
@ -54,7 +53,3 @@ end
function Wire.getbounds(self) function Wire.getbounds(self)
return self.bounds return self.bounds
end end
function Wire.getsim(wire)
return wire.sim
end