move network functionality to new file
This commit is contained in:
parent
5b8a1ea850
commit
14c61e35d1
294
sim/main.lua
294
sim/main.lua
@ -1,19 +1,22 @@
|
||||
|
||||
-- External requirements
|
||||
local socket = require("socket")
|
||||
local ffi = require("ffi")
|
||||
|
||||
-- Disallow access to undefined global variables (helps detect errors)
|
||||
assert(getmetatable(_G)==nil, "_G already has a metatable")
|
||||
setmetatable(_G, {
|
||||
__index = function(t, i) error("attempt to access nil variable "..i, 2) end
|
||||
})
|
||||
|
||||
-- Set save directory
|
||||
OPT_SAVE_DIR = arg[1] or error("must specify save location")
|
||||
OPT_SAVE_DIR = OPT_SAVE_DIR:gsub("\\", "/")
|
||||
OPT_SAVE_DIR = OPT_SAVE_DIR:gsub("/$", "")
|
||||
print("Save location set to \""..OPT_SAVE_DIR.."\"")
|
||||
|
||||
local socket = require("socket")
|
||||
local ffi = require("ffi")
|
||||
|
||||
-- Local includes
|
||||
dofile("iosafe.lua")
|
||||
|
||||
FFI = ffi
|
||||
dofile("utility.lua")
|
||||
dofile("simulation.lua")
|
||||
@ -24,301 +27,34 @@ dofile("port.lua")
|
||||
dofile("gate.lua")
|
||||
dofile("save.lua")
|
||||
dofile("compile.lua")
|
||||
dofile("network.lua")
|
||||
FFI = nil
|
||||
|
||||
-- Default settings
|
||||
OPT_TICK_ENABLED = true
|
||||
OPT_TICK_TIME = 0.032
|
||||
OPT_TICK_MULT = 1
|
||||
OPT_FX_UPDATES = true
|
||||
OPT_FX_TIME = 0.032
|
||||
|
||||
OPT_TICK_INF = 29
|
||||
|
||||
-- Tick rate measurement state
|
||||
local tickdelay = 0
|
||||
local ticksperinterval = 0
|
||||
|
||||
bool_to_int = {[false] = 0, [true] = 1}
|
||||
|
||||
local lastticktime = 0
|
||||
local ticks = 0
|
||||
local tickrate = 0
|
||||
local lastmeasuretime = 0
|
||||
local lastfxtime = 0
|
||||
|
||||
local avgticks = {}
|
||||
local totalticks = 0
|
||||
|
||||
-- Create new simulation
|
||||
local sim = Simulation.new(Simulation)
|
||||
GSim = sim
|
||||
|
||||
local units = {
|
||||
"uHz",
|
||||
"mHz",
|
||||
"Hz",
|
||||
"kHz",
|
||||
"MHz",
|
||||
"GHz",
|
||||
}
|
||||
|
||||
local function round(x)
|
||||
return math.floor(x+0.5)
|
||||
end
|
||||
|
||||
local function unitize(v)
|
||||
local unit = 1
|
||||
v = v*1000000
|
||||
|
||||
while v >= 1000 do
|
||||
v = v/1000
|
||||
unit = unit+1
|
||||
end
|
||||
|
||||
local s
|
||||
if v >= 100 then
|
||||
s = "" .. round(v/10)*10
|
||||
elseif v >= 10 then
|
||||
s = "" .. round(v)
|
||||
elseif v >= 1 then
|
||||
s = "" .. round(v*10)/10
|
||||
if #s == 1 then s = s .. ".0" end
|
||||
else
|
||||
s = 0
|
||||
end
|
||||
|
||||
return s .. " " .. units[unit]
|
||||
end
|
||||
|
||||
function vectotable(vec)
|
||||
local tbl = {}
|
||||
for comp in string.gmatch(vec, "([^%s]+)") do
|
||||
tbl[#tbl+1] = tonumber(comp)
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
function tabletostring(table)
|
||||
local str = tostring(table[1])
|
||||
for i = 2, #table do
|
||||
str = str .. " " .. tostring(table[i])
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
function toboolean(value)
|
||||
local num = tonumber(value)
|
||||
if num == 1 then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local function acceptclient()
|
||||
client = server:accept()
|
||||
client:settimeout(0)
|
||||
local ip, port = client:getsockname()
|
||||
print("Connection from " .. ip .. ":" .. port)
|
||||
end
|
||||
|
||||
server = assert(socket.bind("*", 25000))
|
||||
client = nil
|
||||
|
||||
local ip, port = server:getsockname()
|
||||
print("Server listening on " .. ip .. ":" .. port)
|
||||
|
||||
acceptclient()
|
||||
|
||||
while 1 do
|
||||
local line, err = client:receive()
|
||||
|
||||
if not err then
|
||||
local data = {}
|
||||
local i = 1
|
||||
line = line:gsub(";;", "; ;")
|
||||
line = line:gsub(";$", "; ")
|
||||
|
||||
for str in string.gmatch(line, "([^;]+)") do
|
||||
data[i] = str or ""
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
local i = 1
|
||||
while i <= #data do
|
||||
if data[i] == "W" then
|
||||
local min = vectotable(data[i+3])
|
||||
local max = vectotable(data[i+4])
|
||||
local bounds = {min[1], min[2], min[3], max[1], max[2], max[3]}
|
||||
|
||||
local wire = Wire.new(tonumber(data[i+1]), tonumber(data[i+2]), bounds)
|
||||
Simulation.addwire(sim, wire)
|
||||
|
||||
i = i + 4
|
||||
elseif data[i] == "G" then
|
||||
local objref = tonumber(data[i+1])
|
||||
local definition = Simulation.getdefinitionbyref(sim, tonumber(data[i+2]))
|
||||
|
||||
assert(definition, "No gate definition for objref "..objref.." defref "..tonumber(data[i+1]))
|
||||
|
||||
local position = vectotable(data[i+3])
|
||||
local rotation = tonumber(data[i+4])
|
||||
local gate = GateDefinition.constructgate(definition, objref, position, rotation)
|
||||
|
||||
Simulation.addgate(sim, gate)
|
||||
--print(gate.objref)
|
||||
--Gate.init(gate)
|
||||
--Gate.logic(gate)
|
||||
|
||||
i = i + 4
|
||||
elseif data[i] == "RW" then
|
||||
Simulation.removewire(sim, tonumber(data[i+1]))
|
||||
i = i + 1
|
||||
elseif data[i] == "RG" then
|
||||
Simulation.removegate(sim, tonumber(data[i+1]))
|
||||
i = i + 1
|
||||
elseif data[i] == "GD" then
|
||||
--print("---------------------------------------[[[[")
|
||||
--print(table.concat(data, "]]]]\n[[[[", i, math.min(#data, i+100)))
|
||||
--print("]]]]---------------------------------------")
|
||||
local objref = tonumber(data[i+1])
|
||||
local name = data[i+2]
|
||||
local desc = data[i+3]
|
||||
local init = data[i+4]
|
||||
local logic = data[i+5]
|
||||
local input = data[i+6]
|
||||
local global = data[i+7]
|
||||
local numports = tonumber(data[i+8])
|
||||
local ports = {}
|
||||
|
||||
for a = i+9, numports*5+i+8, 5 do
|
||||
local portd = {
|
||||
type = tonumber(data[a]),
|
||||
position = vectotable(data[a+1]),
|
||||
direction = tonumber(data[a+2]),
|
||||
causeupdate = toboolean(data[a+3]),
|
||||
name = data[a+4],
|
||||
}
|
||||
ports[#ports+1] = portd
|
||||
|
||||
if not portd.direction then print(line) end
|
||||
end
|
||||
|
||||
local definition = GateDefinition.new(objref, name, desc, init, logic, input, global, ports)
|
||||
Simulation.addgatedefinition(sim, definition)
|
||||
|
||||
i = i + 8 + numports*5
|
||||
elseif data[i] == "SL" then
|
||||
local wire = Simulation.getwirebyref(sim, tonumber(data[i+1]))
|
||||
if wire ~= nil then
|
||||
Wire.setlayer(wire, tonumber(data[i+2]))
|
||||
end
|
||||
|
||||
i = i + 2
|
||||
elseif data[i] == "OPT" then
|
||||
local option = data[i+1]
|
||||
local value = tonumber(data[i+2])
|
||||
|
||||
if option == "TICK_ENABLED" then
|
||||
OPT_TICK_ENABLED = toboolean(value)
|
||||
elseif option == "TICK_TIME" then
|
||||
if value < 0 or value > 999999 then
|
||||
value = 0
|
||||
end
|
||||
if value<=0.001 then value = 0.0001 end
|
||||
OPT_TICK_TIME = value
|
||||
elseif option == "FX_UPDATES" then
|
||||
OPT_FX_UPDATES = toboolean(value)
|
||||
elseif option == "FX_TIME" then
|
||||
if value < 0 or value > 999999 then
|
||||
value = 0
|
||||
end
|
||||
OPT_FX_TIME = value
|
||||
elseif option=="TICK_MULT" then
|
||||
OPT_TICK_MULT = value
|
||||
end
|
||||
|
||||
i = i + 2
|
||||
elseif data[i] == "GINFO" then
|
||||
local userid = data[i+1]
|
||||
local objref = tonumber(data[i+2])
|
||||
|
||||
local info = ""
|
||||
|
||||
local wire = Simulation.getwirebyref(sim, objref)
|
||||
if wire then
|
||||
local group = Wire.getgroup(wire)
|
||||
local numwires = 0; for k, wire2 in pairs(group.wires ) do numwires = numwires +1 end
|
||||
local numportsi = 0; for k, port in pairs(group.in_ports ) do numportsi = numportsi+1 end
|
||||
local numgatesu = group.num_gates_update
|
||||
local numportso = 0; local numportson=0;
|
||||
for k, port in pairs(group.out_ports) do
|
||||
numportso = numportso+1
|
||||
if Port.getstate(port)==1 then numportson = numportson+1 end
|
||||
end
|
||||
|
||||
info = "\\c5Net " .. tostring(group):match("table: 0x(.+)"):upper() .. "\n" .. (Wire.getgroup(wire).state==1 and "\\c2On" or "\\c0Off") .. "\n" ..
|
||||
"Wires: "..numwires.."\n"..
|
||||
"In Ports: " ..numportsi.."\n"..
|
||||
"Out Ports: "..numportso.."\n"..
|
||||
"Gates Update: "..numgatesu.."\n"..
|
||||
"Out Ports On: "..(group.state_num)
|
||||
;
|
||||
end
|
||||
|
||||
local gate = Simulation.getgatebyref(sim, objref)
|
||||
if gate then
|
||||
local def = Gate.getdefinition(gate)
|
||||
info = "\\c5" .. def.name .. "<br>"
|
||||
for i = 1, #gate.ports do
|
||||
local port = gate.ports[i]
|
||||
local state
|
||||
if port.type==PortTypes.input then
|
||||
state = Gate.getportstate(gate, i)
|
||||
else
|
||||
state = Port.getstate(port)
|
||||
end
|
||||
info = info .. (state==1 and "\\c2" or "\\c0") .. def.ports[i].name .. (i ~= #gate.ports and " " or "")
|
||||
end
|
||||
end
|
||||
|
||||
if info ~= "" then
|
||||
client:send("GINFO\t" .. userid .. "\t" .. expandescape(info) .. "\n")
|
||||
end
|
||||
|
||||
i = i + 2
|
||||
elseif data[i] == "SINFO" then
|
||||
client:send("SINFO\t" .. data[i+1] .. "\t" .. sim.nwires .. "\t" .. sim.ngates .. "\t" .. sim.ninports .. "\t" .. sim.noutports .. "\n")
|
||||
i = i + 1
|
||||
elseif data[i] == "TICK" then
|
||||
Simulation.tickinit(sim)
|
||||
Simulation.tickinput(sim)
|
||||
Simulation.ticklogic(sim)
|
||||
ticks = ticks + 1
|
||||
elseif data[i] == "IN" then
|
||||
local gate = Simulation.getgatebyref(sim, tonumber(data[i+1]))
|
||||
local argc = tonumber(data[i+2])
|
||||
local argv = {}
|
||||
for a = i+3, i+3+argc-1 do
|
||||
argv[#argv+1] = collapseescape(data[a])
|
||||
end
|
||||
if gate then
|
||||
Simulation.queuegateinput(sim, gate, argv)
|
||||
end
|
||||
|
||||
i = i+2+argc
|
||||
elseif data[i] == "SAVE" then
|
||||
print("saving all data")
|
||||
logicsave()
|
||||
else
|
||||
print("invalid data "..data[i])
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
end
|
||||
elseif err == "closed" then
|
||||
sim = Simulation.new(Simulation)
|
||||
acceptclient()
|
||||
end
|
||||
network_accept_client()
|
||||
|
||||
while true do
|
||||
local time = os.clock()
|
||||
|
||||
if OPT_TICK_ENABLED then
|
||||
@ -348,6 +84,8 @@ while 1 do
|
||||
end
|
||||
|
||||
if time-lastfxtime >= OPT_FX_TIME then
|
||||
network_update()
|
||||
|
||||
if OPT_FX_UPDATES then
|
||||
Simulation.sendfxupdate(sim)
|
||||
end
|
||||
@ -365,7 +103,7 @@ while 1 do
|
||||
|
||||
ticks = 0
|
||||
|
||||
client:send("TPS\t" .. unitize((totalticks/#avgticks)/0.1) .. "\n")
|
||||
network_send("TPS\t" .. unitize((totalticks/#avgticks)/0.1) .. "\n")
|
||||
lastmeasuretime = os.clock()
|
||||
end
|
||||
end
|
||||
|
213
sim/network.lua
Normal file
213
sim/network.lua
Normal file
@ -0,0 +1,213 @@
|
||||
|
||||
function network_send(data)
|
||||
client:send(data)
|
||||
end
|
||||
|
||||
function network_accept_client()
|
||||
server = assert(socket.bind("*", 25000))
|
||||
client = nil
|
||||
|
||||
local ip, port = server:getsockname()
|
||||
print("Server listening on " .. ip .. ":" .. port)
|
||||
|
||||
client = server:accept()
|
||||
client:settimeout(0)
|
||||
local ip, port = client:getsockname()
|
||||
print("Connection from " .. ip .. ":" .. port)
|
||||
end
|
||||
|
||||
function network_update()
|
||||
local sim = GSim
|
||||
|
||||
local line, err = client:receive()
|
||||
|
||||
if not err then
|
||||
local data = {}
|
||||
local i = 1
|
||||
line = line:gsub(";;", "; ;")
|
||||
line = line:gsub(";$", "; ")
|
||||
|
||||
for str in string.gmatch(line, "([^;]+)") do
|
||||
data[i] = str or ""
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
local i = 1
|
||||
while i <= #data do
|
||||
if data[i] == "W" then
|
||||
local min = vectotable(data[i+3])
|
||||
local max = vectotable(data[i+4])
|
||||
local bounds = {min[1], min[2], min[3], max[1], max[2], max[3]}
|
||||
|
||||
local wire = Wire.new(tonumber(data[i+1]), tonumber(data[i+2]), bounds)
|
||||
Simulation.addwire(sim, wire)
|
||||
|
||||
i = i + 4
|
||||
elseif data[i] == "G" then
|
||||
local objref = tonumber(data[i+1])
|
||||
local definition = Simulation.getdefinitionbyref(sim, tonumber(data[i+2]))
|
||||
|
||||
assert(definition, "No gate definition for objref "..objref.." defref "..tonumber(data[i+1]))
|
||||
|
||||
local position = vectotable(data[i+3])
|
||||
local rotation = tonumber(data[i+4])
|
||||
local gate = GateDefinition.constructgate(definition, objref, position, rotation)
|
||||
|
||||
Simulation.addgate(sim, gate)
|
||||
--print(gate.objref)
|
||||
--Gate.init(gate)
|
||||
--Gate.logic(gate)
|
||||
|
||||
i = i + 4
|
||||
elseif data[i] == "RW" then
|
||||
Simulation.removewire(sim, tonumber(data[i+1]))
|
||||
i = i + 1
|
||||
elseif data[i] == "RG" then
|
||||
Simulation.removegate(sim, tonumber(data[i+1]))
|
||||
i = i + 1
|
||||
elseif data[i] == "GD" then
|
||||
--print("---------------------------------------[[[[")
|
||||
--print(table.concat(data, "]]]]\n[[[[", i, math.min(#data, i+100)))
|
||||
--print("]]]]---------------------------------------")
|
||||
local objref = tonumber(data[i+1])
|
||||
local name = data[i+2]
|
||||
local desc = data[i+3]
|
||||
local init = data[i+4]
|
||||
local logic = data[i+5]
|
||||
local input = data[i+6]
|
||||
local global = data[i+7]
|
||||
local numports = tonumber(data[i+8])
|
||||
local ports = {}
|
||||
|
||||
for a = i+9, numports*5+i+8, 5 do
|
||||
local portd = {
|
||||
type = tonumber(data[a]),
|
||||
position = vectotable(data[a+1]),
|
||||
direction = tonumber(data[a+2]),
|
||||
causeupdate = toboolean(data[a+3]),
|
||||
name = data[a+4],
|
||||
}
|
||||
ports[#ports+1] = portd
|
||||
|
||||
if not portd.direction then print(line) end
|
||||
end
|
||||
|
||||
local definition = GateDefinition.new(objref, name, desc, init, logic, input, global, ports)
|
||||
Simulation.addgatedefinition(sim, definition)
|
||||
|
||||
i = i + 8 + numports*5
|
||||
elseif data[i] == "SL" then
|
||||
local wire = Simulation.getwirebyref(sim, tonumber(data[i+1]))
|
||||
if wire ~= nil then
|
||||
Wire.setlayer(wire, tonumber(data[i+2]))
|
||||
end
|
||||
|
||||
i = i + 2
|
||||
elseif data[i] == "OPT" then
|
||||
local option = data[i+1]
|
||||
local value = tonumber(data[i+2])
|
||||
|
||||
if option == "TICK_ENABLED" then
|
||||
OPT_TICK_ENABLED = toboolean(value)
|
||||
elseif option == "TICK_TIME" then
|
||||
if value < 0 or value > 999999 then
|
||||
value = 0
|
||||
end
|
||||
if value<=0.001 then value = 0.0001 end
|
||||
OPT_TICK_TIME = value
|
||||
elseif option == "FX_UPDATES" then
|
||||
OPT_FX_UPDATES = toboolean(value)
|
||||
elseif option == "FX_TIME" then
|
||||
if value < 0 or value > 999999 then
|
||||
value = 0
|
||||
end
|
||||
OPT_FX_TIME = value
|
||||
elseif option=="TICK_MULT" then
|
||||
OPT_TICK_MULT = value
|
||||
end
|
||||
|
||||
i = i + 2
|
||||
elseif data[i] == "GINFO" then
|
||||
local userid = data[i+1]
|
||||
local objref = tonumber(data[i+2])
|
||||
|
||||
local info = ""
|
||||
|
||||
local wire = Simulation.getwirebyref(sim, objref)
|
||||
if wire then
|
||||
local group = Wire.getgroup(wire)
|
||||
local numwires = 0; for k, wire2 in pairs(group.wires ) do numwires = numwires +1 end
|
||||
local numportsi = 0; for k, port in pairs(group.in_ports ) do numportsi = numportsi+1 end
|
||||
local numgatesu = group.num_gates_update
|
||||
local numportso = 0; local numportson=0;
|
||||
for k, port in pairs(group.out_ports) do
|
||||
numportso = numportso+1
|
||||
if Port.getstate(port)==1 then numportson = numportson+1 end
|
||||
end
|
||||
|
||||
info = "\\c5Net " .. tostring(group):match("table: 0x(.+)"):upper() .. "\n" .. (Wire.getgroup(wire).state==1 and "\\c2On" or "\\c0Off") .. "\n" ..
|
||||
"Wires: "..numwires.."\n"..
|
||||
"In Ports: " ..numportsi.."\n"..
|
||||
"Out Ports: "..numportso.."\n"..
|
||||
"Gates Update: "..numgatesu.."\n"..
|
||||
"Out Ports On: "..(group.state_num)
|
||||
;
|
||||
end
|
||||
|
||||
local gate = Simulation.getgatebyref(sim, objref)
|
||||
if gate then
|
||||
local def = Gate.getdefinition(gate)
|
||||
info = "\\c5" .. def.name .. "<br>"
|
||||
for i = 1, #gate.ports do
|
||||
local port = gate.ports[i]
|
||||
local state
|
||||
if port.type==PortTypes.input then
|
||||
state = Gate.getportstate(gate, i)
|
||||
else
|
||||
state = Port.getstate(port)
|
||||
end
|
||||
info = info .. (state==1 and "\\c2" or "\\c0") .. def.ports[i].name .. (i ~= #gate.ports and " " or "")
|
||||
end
|
||||
end
|
||||
|
||||
if info ~= "" then
|
||||
network_send("GINFO\t" .. userid .. "\t" .. expandescape(info) .. "\n")
|
||||
end
|
||||
|
||||
i = i + 2
|
||||
elseif data[i] == "SINFO" then
|
||||
network_send("SINFO\t" .. data[i+1] .. "\t" .. sim.nwires .. "\t" .. sim.ngates .. "\t" .. sim.ninports .. "\t" .. sim.noutports .. "\n")
|
||||
i = i + 1
|
||||
elseif data[i] == "TICK" then
|
||||
Simulation.tickinit(sim)
|
||||
Simulation.tickinput(sim)
|
||||
Simulation.ticklogic(sim)
|
||||
ticks = ticks + 1
|
||||
elseif data[i] == "IN" then
|
||||
local gate = Simulation.getgatebyref(sim, tonumber(data[i+1]))
|
||||
local argc = tonumber(data[i+2])
|
||||
local argv = {}
|
||||
for a = i+3, i+3+argc-1 do
|
||||
argv[#argv+1] = collapseescape(data[a])
|
||||
end
|
||||
if gate then
|
||||
Simulation.queuegateinput(sim, gate, argv)
|
||||
end
|
||||
|
||||
i = i+2+argc
|
||||
elseif data[i] == "SAVE" then
|
||||
print("saving all data")
|
||||
logicsave()
|
||||
else
|
||||
print("invalid data "..data[i])
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
end
|
||||
elseif err == "closed" then
|
||||
--sim = Simulation.new(Simulation)
|
||||
--acceptclient()
|
||||
print("Connection closed")
|
||||
error()
|
||||
end
|
||||
end
|
@ -365,7 +365,7 @@ function Simulation.sendfxupdate(sim)
|
||||
data = data .. "\t" .. Wire.getobjref(wire)
|
||||
end
|
||||
|
||||
client:send("WU\t" .. data .. "\n")
|
||||
network_send("WU\t" .. data .. "\n")
|
||||
end
|
||||
end
|
||||
|
||||
@ -384,7 +384,7 @@ function Simulation.sendcallbacks(sim)
|
||||
data = data .. "\t" .. objref .. "\t"..(#escargs)..(#escargs>0 and ("\t"..table.concat(escargs, "\t")) or "")
|
||||
end
|
||||
|
||||
client:send(data .. "\n")
|
||||
network_send(data .. "\n")
|
||||
sim.callbacks = nil
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,6 @@
|
||||
|
||||
bool_to_int = {[false] = 0, [true] = 1}
|
||||
|
||||
local escapes = {
|
||||
{"\\", "b"},
|
||||
{"\t", "t"},
|
||||
@ -85,3 +87,64 @@ function array_add(array, value)
|
||||
end
|
||||
table.insert(array, value)
|
||||
end
|
||||
|
||||
function round(x)
|
||||
return math.floor(x+0.5)
|
||||
end
|
||||
|
||||
local units = {
|
||||
"uHz",
|
||||
"mHz",
|
||||
"Hz",
|
||||
"kHz",
|
||||
"MHz",
|
||||
"GHz",
|
||||
}
|
||||
function unitize(v)
|
||||
local unit = 1
|
||||
v = v*1000000
|
||||
|
||||
while v >= 1000 do
|
||||
v = v/1000
|
||||
unit = unit+1
|
||||
end
|
||||
|
||||
local s
|
||||
if v >= 100 then
|
||||
s = "" .. round(v/10)*10
|
||||
elseif v >= 10 then
|
||||
s = "" .. round(v)
|
||||
elseif v >= 1 then
|
||||
s = "" .. round(v*10)/10
|
||||
if #s == 1 then s = s .. ".0" end
|
||||
else
|
||||
s = 0
|
||||
end
|
||||
|
||||
return s .. " " .. units[unit]
|
||||
end
|
||||
|
||||
function vectotable(vec)
|
||||
local tbl = {}
|
||||
for comp in string.gmatch(vec, "([^%s]+)") do
|
||||
tbl[#tbl+1] = tonumber(comp)
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
function tabletostring(table)
|
||||
local str = tostring(table[1])
|
||||
for i = 2, #table do
|
||||
str = str .. " " .. tostring(table[i])
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
function toboolean(value)
|
||||
local num = tonumber(value)
|
||||
if num == 1 then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
@ -20,7 +20,7 @@ function Wire.setlayer(wire, layer)
|
||||
end
|
||||
|
||||
function Wire.update(wire)
|
||||
client:send("WU\t" .. (wire.group.state~=0 and "1" or "0") .. "\t" .. wire.objref .. "\n")
|
||||
network_send("WU\t" .. (wire.group.state~=0 and "1" or "0") .. "\t" .. wire.objref .. "\n")
|
||||
end
|
||||
|
||||
function Wire.setgroup(wire, group)
|
||||
|
Loading…
x
Reference in New Issue
Block a user