Group = {} function Group.new(self, sim) local o = { state = false, fxstate = false, updatetick = 0, wires = {}, out_ports = {}, in_ports = {}, 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