local ffi = FFI or require("ffi") GateDefinition = { ports = {}, logic = function(gate) end, input = function(gate, argv) end } function GateDefinition.new(objref, name, description, init, logic, input, global, ports) name = collapseescape(name) init = collapseescape(init) logic = collapseescape(logic) input = collapseescape(input) global = collapseescape(global) description = collapseescape(description) local def = { objref = objref, name = name, description = description, ports = ports or {}, num_in_ports = 0, num_out_ports = 0, data_size_c = cDataSizeByName[name:lower()] or 0, logic_function_c = cFuncsByName[name:lower()] or 0, } local initfunc = loadstring(tostring(init)) if initfunc~=nil then def.init = initfunc() or function()end else print("Error loading init func for ".. (name or "")) print(init) end local logicfunc = loadstring(tostring(logic)) if logicfunc ~= nil then def.logic = logicfunc() or function()end else print("Error loading logic function for " .. (name or "")) print(logic) end local inputfunc = loadstring(tostring(input)) if inputfunc ~= nil then def.input = inputfunc() or function()end else print("Error loading input function for " .. (name or "")) print(input) end local globalfunc = loadstring(tostring(global)) if globalfunc~=nil then globalfunc() else print("Error loading global function for ".. (name or "")) print(global) end for i = 1, #def.ports do local portd = def.ports[i] if portd.type==PortTypes.output then def.num_out_ports = def.num_out_ports + 1 elseif portd.type==PortTypes.input then def.num_in_ports = def.num_in_ports + 1 else error("invalid port type: "..name.." port "..i) end end return def end function GateDefinition.constructgate(def, objref, position, rotation) local gate = Gate.new(objref, def) for i = 1, #def.ports do local portd = def.ports[i] local type = portd.type local pos = {portd.position[1], portd.position[2], portd.position[3]} local dir = portd.direction if dir < 4 then dir = (dir + rotation) % 4 end local x = pos[1] if rotation == 1 then pos[1] = pos[2] pos[2] = -x elseif rotation == 2 then pos[1] = -pos[1] pos[2] = -pos[2] elseif rotation == 3 then pos[1] = -pos[2] pos[2] = x end local port = Port.new(type, dir, {position[1]+pos[1], position[2]+pos[2], position[3]+pos[3]}, portd.causeupdate, i, gate) gate.ports[port.idx] = port gate.port_nets[port.idx] = nil gate.port_states[port.idx] = 0 gate.port_net_state [port.idx] = ffi.cast("int*", 0) gate.port_net_state_num[port.idx] = ffi.cast("int*", 0) gate.port_net_in_queue [port.idx] = ffi.cast("int*", 0) gate.port_nets_c [port.idx] = ffi.cast("struct Net*", 0) end return gate end