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%
set saveloc=%cd%\%savefolder%\
cd "sim"
luajit "main.lua" %saveloc%
luajit -jp "main.lua" %saveloc%
pause

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

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 = {
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

View File

@ -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

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 = {
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