lua-logic/sim/gatedef.lua
2022-11-13 22:49:31 -06:00

115 lines
2.8 KiB
Lua

local ffi = FFI or require("ffi")
local cFuncsByName, cDataSizeByName = require("compiled_sim_gates")
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