This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
ttamttam's profile picture

Sending tables across rednet

Started by ttamttam, 01 July 2013 - 07:43 PM
ttamttam #1
Posted 01 July 2013 - 09:43 PM
so I've been working on a missile control system for the ICBM mod and i can't seem to send tables across rednet.
I use Direwolf20's button API:

local mon = peripheral.wrap("right")
mon.setTextScale(1)
mon.setTextColor(colors.white)
local button={}
mon.setBackgroundColor(colors.black)
function clearTable()
   button = {}
   mon.clear()
end
			  
function setTable(name, func, xmin, xmax, ymin, ymax)
   button[name] = {}
   button[name]["func"] = func
   button[name]["active"] = false
   button[name]["xmin"] = xmin
   button[name]["ymin"] = ymin
   button[name]["xmax"] = xmax
   button[name]["ymax"] = ymax
end
function funcName()
   print("You clicked buttonText")
end
	  
function fillTable()
   setTable("ButtonText", funcName, 5, 25, 4, 8)
end	
function fill(text, color, bData)
   mon.setBackgroundColor(color)
   local yspot = math.floor((bData["ymin"] + bData["ymax"]) /2)
   local xspot = math.floor((bData["xmax"] - bData["xmin"] - string.len(text)) /2) +1
   for j = bData["ymin"], bData["ymax"] do
	  mon.setCursorPos(bData["xmin"], j)
	  if j == yspot then
		 for k = 0, bData["xmax"] - bData["xmin"] - string.len(text) +1 do
			if k == xspot then
			   mon.write(text)
			else
			   mon.write(" ")
			end
		 end
	  else
		 for i = bData["xmin"], bData["xmax"] do
			mon.write(" ")
		 end
	  end
   end
   mon.setBackgroundColor(colors.black)
end
	
function screen()
   local currColor
   for name,data in pairs(button) do
	  local on = data["active"]
	  if on == true then currColor = colors.lime else currColor = colors.red end
	  fill(name, currColor, data)
   end
end
function toggleButton(name)
   button[name]["active"] = not button[name]["active"]
   screen()
end	
function flash(name)
   toggleButton(name)
   screen()
   sleep(0.15)
   toggleButton(name)
   screen()
end
											
function checkxy(x, y)
   for name, data in pairs(button) do
	  if y>=data["ymin"] and  y <= data["ymax"] then
		 if x>=data["xmin"] and x<= data["xmax"] then
			data["func"]()
			return true
			--data["active"] = not data["active"]
			--print(name)
		 end
	  end
   end
   return false
end
	
function heading(text)
   w, h = mon.getSize()
   mon.setCursorPos((w-string.len(text))/2+1, 1)
   mon.write(text)
end
	
function label(w, h, text)
   mon.setCursorPos(w, h)
   mon.write(text)
end
Here is the code for the computer in control of requesting the info

os.loadAPI("button")
rednet.open("back")
m = peripheral.wrap("right")
speaker = peripheral.wrap("top")
m.clear()
function getClick()
  event,side,x,y = os.pullEvent("monitor_touch")
  button.checkxy(x,y)
end
function save(table, name)
local file = fs.open(name, "w")
file.write(textutils.serialize(table))
file.close()
end
function load(name)
  local file = fs.open(name)
  local data = file.readAll()
  file.close()
  return textutils.unserialize(data)
end
function fillStartup()
  m.clear()
  m.setCursorPos(1,1)
  m.write("Please use the player detector to")
  m.setCursorPos(1,2)
  m.write("continue")
  speaker.speak("Please use the player detector to continue.")
  local event, i = os.pullEvent("player")
  if i == "ttamttam" then
	print("welcome back ttamttam")
	speaker.speak("welcome backk tam tam")
	fillMenu()  
  else
	 m.clear()
	 m.setCursorPos(1,1)
	 m.write("You are not welcome here, ")
	 m.write(i)
	 speaker.speak("You are not welcome here.")
  end
end
function fillMenu()
  button.clearTable()
  button.setTable("Missile Command", missileCommand, 5,35,3,5)
  button.setTable("Exit", exit, 5,35,7,9)
  button.screen()
end
function missileCommand()
  button.flash("Missile Command")
  button.clearTable()
  button.setTable("Silo One", function() silo(11) end, 5,19,3,5)
  button.setTable("Silo Two", function() silo(nil) end, 21,35,3,5)
  button.setTable("Silo Three", function() silo(nil) end, 5,19,7,9)
  button.setTable("Silo Four", function() silo(nil) end, 21,35,7,9)
  button.screen()
end
function silo(number)
  button.clearTable()
  rednet.send(number,"getStats")
  repeat
	local id, message, distance = rednet.receive()
  until id == number
  print("passed loop")
  print(number)
  print(message)
  messageCopy = load("message")
  m.setCursorPos(1,3)
  if messageCopy.canLuanch == 1 then
	m.setTextColor(colors.green)
	m.write("Missile is ready to luanch")
  else
	m.setTextColor(colors.red)
	m.write("Missile cannot luanch")
  end
  m.setCursorPos(1,5)
  m.setTextColor(colors.white)
  m.write("Currently aimed at:")
  m.setCursorPos(1,6)
  m.write("X")
  m.write(messageCopy.x)
  m.write(" Y")
  m.write(messageCopy.y)
  m.write(" Z")
  m.write(messageCopy.z)

  m.setCursorPos(1,8)
  m.write("Frequency:")
  m.setCursorPos(1,9)
  m.write(messageCopy.frequency)
end
function exit()
  button.flash("Exit")
  speaker.speak("Goodbye")
  os.shutdown()
end
fillStartup()
while true do
  getClick()
end

and here is the computer that should be sending the table:

icbm = peripheral.wrap("top")
rednet.open("bottom")
function save(table, name)
  local file = fs.open(name, "w")
  file.write(textutils.serialize(table))
  file.close()
end
function load(name)
  local file = fs.open(name,"r")
  local data = file.readAll()
  file.close()
  return textutils.unserialize(data)
end
while true do
  id, message, distance = rednet.receive()
  print("received message")
  if id == 8 then
	print("received message from id 8")
	if message == "getStats" then
	  print("message reads getStats")
	  stats = {canLaunch,x,y,z,frequency}
	  if icbm.canLaunch() == true then
		stats.canLaunch = 1
	  else
		stats.canLaunch = 0
	  end
	  print(stats.canLaunch)
	  stats.x, stats.y, stats.z = icbm.getTarget()
	  print(stats.x)
	  print(stats.y)
	  print(stats.z)
	  stats.frequency = icbm.getFrequency()
	  print(stats.frequency)
	  save(stats, statsCopy)
	  rednet.send(8, statsCopy)
	  print("sent message")
	  print(stats)
	  print(statsCopy)
	  i = textutils.unserialize(statsCopy)
	  print(i)
	end
  end
end
as you can see I've tried doing a bunch of workarounds (for example making true 1 and false 0) but none have worked.
Mods involved are icbm and misc. peripherals
Lyqyd #2
Posted 02 July 2013 - 01:52 PM
Split into new topic.
Grim Reaper #3
Posted 02 July 2013 - 02:32 PM
'statsCopy' is never defined, so the 'fs' API cannot create a file with a name of nil. Therefore, when you try to read from that file, you'll be getting nothing back from it since it was never created in the first place.
ttamttam #4
Posted 02 July 2013 - 07:02 PM
I usually understand code better when I'm able to look at, could you give me an example of working code?
albrat #5
Posted 03 July 2013 - 02:17 AM
you never defined statsCopy in this section of your code.
final section…


while true do
  id, message, distance = rednet.receive()
  print("received message")
  if id == 8 then
		print("received message from id 8")
		if message == "getStats" then
		  print("message reads getStats")
		  stats = {canLaunch,x,y,z,frequency}
		  if icbm.canLaunch() == true then
				stats.canLaunch = 1
		  else
				stats.canLaunch = 0
		  end
		  print(stats.canLaunch)
		  stats.x, stats.y, stats.z = icbm.getTarget()
		  print(stats.x)
		  print(stats.y)
		  print(stats.z)
		  stats.frequency = icbm.getFrequency()
		  print(stats.frequency)
		  save(stats,[ statsCopy)
		  rednet.send(8, statsCopy)
		  print("sent message")
		  print(stats)
		  print(statsCopy)
		  i = textutils.unserialize(statsCopy)
		  print(i)
		end
  end
end
this function takes the name of the file but does not return any information to the call.

function save(table, name)
local file = fs.open(name, "w")
file.write(textutils.serialize(table))
file.close()
end

Basically once the function ends … StatsCopy is blank. (other than being a file on the disk.)

after the line save(stats, statsCopy)
you would have to do "statsCopy = stats" then send over rednet… (rednet can not send a file without reading the file through a handling system - search for bluetooth via rednet)
TeamDman #6
Posted 04 July 2013 - 02:03 PM
Try textutils.serialize(table table) then use textutils.unserialize(string) when decoding the string.