184 lines
3.4 KiB
Lua
184 lines
3.4 KiB
Lua
|
|
Group = {}
|
|
|
|
FFI.cdef[[
|
|
struct Port;
|
|
struct Net {
|
|
bool state;
|
|
bool fxstate;
|
|
int updatetick;
|
|
int internal_ref;
|
|
int state_num;
|
|
int num_in_ports_update;
|
|
struct Port* in_ports_update[1];
|
|
};
|
|
]]
|
|
|
|
function Group.new(self, sim)
|
|
local o = {
|
|
state = false,
|
|
fxstate = false,
|
|
updatetick = 0,
|
|
wires = {},
|
|
out_ports = {},
|
|
in_ports = {},
|
|
|
|
state_num = 0,
|
|
|
|
nwires = 0,
|
|
nout_ports = 0,
|
|
nin_ports = 0,
|
|
|
|
sim = sim,
|
|
}
|
|
setmetatable(o, self)
|
|
self.__index = self
|
|
return o
|
|
end
|
|
|
|
function Group.getsize(self)
|
|
return self.nwires + self.nout_ports + self.nin_ports
|
|
end
|
|
|
|
function Group.addwire(self, wire)
|
|
if Wire.getgroup(wire) ~= self then
|
|
if Wire.getgroup(wire) ~= nil then
|
|
Group.mergewith(self, Wire.getgroup(wire))
|
|
else
|
|
self.wires[wire] = wire
|
|
self.nwires = self.nwires + 1
|
|
|
|
Wire.setgroup(wire, self)
|
|
Wire.update(wire)
|
|
Simulation.queuegroup(Group.getsim(self), self)
|
|
end
|
|
end
|
|
end
|
|
|
|
function Group.removewire(self, wire)
|
|
Wire.setgroup(wire, nil)
|
|
self.wires[wire] = nil
|
|
|
|
local sim = Group.getsim(self)
|
|
|
|
for k, wire in pairs(self.wires) do
|
|
Wire.setgroup(wire, nil)
|
|
end
|
|
|
|
for k, port in pairs(self.out_ports) do
|
|
Port.setgroup(port, nil)
|
|
end
|
|
|
|
for k, port in pairs(self.in_ports) do
|
|
Port.setgroup(port, nil)
|
|
end
|
|
|
|
for k, wire in pairs(self.wires) do
|
|
Simulation.connectwire(sim, wire)
|
|
end
|
|
|
|
for k, port in pairs(self.out_ports) do
|
|
Simulation.connectport(sim, port)
|
|
end
|
|
|
|
for k, port in pairs(self.in_ports) do
|
|
Simulation.connectport(sim, port)
|
|
end
|
|
|
|
self.wires = {}
|
|
self.out_ports = {}
|
|
self.in_ports = {}
|
|
|
|
self.nwires = 0
|
|
self.nout_ports = 0
|
|
self.nin_ports = 0
|
|
end
|
|
|
|
function Group.addport(self, port)
|
|
port.group = self
|
|
|
|
if port.type == PortTypes.output then
|
|
self.out_ports[port] = port
|
|
self.nout_ports = self.nout_ports + 1
|
|
Simulation.queuegroup(Group.getsim(self), self)
|
|
elseif port.type == PortTypes.input then
|
|
self.in_ports[port] = port
|
|
self.nin_ports = self.nin_ports + 1
|
|
Port.setinputstate(port, self.state)
|
|
end
|
|
end
|
|
|
|
function Group.removeport(self, port)
|
|
if port.type == PortTypes.output then
|
|
self.out_ports[port] = nil
|
|
self.nout_ports = self.nout_ports - 1
|
|
elseif port.type == PortTypes.input then
|
|
self.in_ports[port] = nil
|
|
self.nin_ports = self.nin_ports - 1
|
|
end
|
|
|
|
Simulation.queuegroup(Group.getsim(self), self)
|
|
end
|
|
|
|
function Group.mergewith(self, group)
|
|
if Group.getsize(self) >= Group.getsize(group) then
|
|
Group.mergeinto(group, self)
|
|
return self
|
|
else
|
|
Group.mergeinto(self, group)
|
|
return group
|
|
end
|
|
end
|
|
|
|
function Group.mergeinto(self, group)
|
|
for k, wire in pairs(self.wires) do
|
|
Wire.setgroup(wire, nil)
|
|
Group.addwire(group, wire)
|
|
end
|
|
|
|
for k, port in pairs(self.out_ports) do
|
|
Group.addport(group, port)
|
|
end
|
|
|
|
for k, port in pairs(self.in_ports) do
|
|
Group.addport(group, port)
|
|
end
|
|
|
|
self.wires = {}
|
|
self.out_ports = {}
|
|
self.in_ports = {}
|
|
|
|
self.nwires = 0
|
|
self.nout_ports = 0
|
|
self.nin_ports = 0
|
|
end
|
|
|
|
function Group.setstate(self, state)
|
|
if state ~= self.state then
|
|
self.state = state
|
|
self.updatetick = Group.getsim(self).currenttick
|
|
|
|
for k, port in pairs(self.in_ports) do
|
|
Port.setinputstate(port, state)
|
|
end
|
|
|
|
Simulation.queuegroupfx(Group.getsim(self), self)
|
|
end
|
|
end
|
|
|
|
function Group.getsim(group)
|
|
return group.sim
|
|
end
|
|
|
|
function Group.update(group)
|
|
local newstate = false
|
|
for j, port in pairs(group.out_ports) do
|
|
newstate = newstate or Port.getstate(port)
|
|
if newstate then
|
|
break
|
|
end
|
|
end
|
|
|
|
Group.setstate(group, newstate)
|
|
end
|