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

Rednet Troubles

Started by pyropanda5, 14 February 2017 - 07:51 AM
pyropanda5 #1
Posted 14 February 2017 - 08:51 AM
I'm currently working on making a queue system for a train system and I've run into a strange problem. When receiving a rednet signal the first if statement won't work if I put quotes around the required protocol, despite the fact that the else if statements work with quotes around the required protocol. The code in its current state works but I'm trying to figure out why this is happening.

Server Code

local queue = {}
rednet.open("back")
term.clear()
term.setCursorPos(1,1)
--checks if a destination is already in the queue
function inqueue(element)
for _, value in pairs(queue) do
	if value ==  element then
	  return true
  end
end
return false
end
--ends the program
function quit()
while true do
  local event, key = os.pullEvent("key")
  if key == 20 then
   os.reboot()
  end
end
end
--receives a destination and adds it to the queue
function receivedestination()
while true do
  local senderId, message, protocol = rednet.receive()
   if protocol == arrival then
	table.remove(queue, 1)
	else if protocol == "destination" then
	 table.insert(queue, message)
	  else if protocol == "origin" and inqueue(message) == false then
	  table.insert(queue, message)
	 end
	end
   end
  term.clear()
  term.setCursorPos(1,1)
  local text = textutils.serialize(queue)
  print(text)
end
end
parallel.waitForAll(receivedestination, quit)


Client Code

local station = 1 --current station number
rednet.open("right")
term.clear()
term.setCursorPos(1,1)
while true do
local event, key = os.pullEvent("key")
if key == 2 and station ~= 1 then
  rednet.send(23,station, "origin")
  rednet.send(23,1, "destination")
  else if key == 3 and station ~= 2 then
   rednet.send(23,station, "origin")
   rednet.send(23,2, "destination")
   else if key == 4 and station ~= 3 then
	rednet.send(23,station, "origin")
	rednet.send(23,3, "destination")
	else if key == 22 then
	 rednet.send(23,u, "arrival")
	 else if key == 20 then
	  error()
	 end
	end
   end
  end
end
print("Key Sent at")
print(os.time())
end
Bomb Bloke #2
Posted 14 February 2017 - 09:41 AM
When your client does:

rednet.send(23,u, "arrival")

… it attempts to send the data in the variable "u" to the remote server. But you never defined any such variable, and so its content is nil.

When performing multiple assignments as a single statement, the build of LuaJ used by ComputerCraft stops as soon as as it hits the first nil value. For example:

one, two, three = "one", nil, "three"
print(one)   --> "one"
print(two)   --> nil
print(three) --> Also nil!

So when the rednet API tries to pull your incoming nil message out of the event queue, it also ends up seeing the protocol as nil.

And because your server script never assigns a value to the "arrival" variable, "protocol == arrival" resolves as true - because both values are nil.

A couple of other points; instead of this sort of thing:

if <condition> then
	...
else
	if <condition> then
		...
	else
		if <condition> then
			...
		else
			if <condition> then
				...
			end
		end
	end
end

… you can do:

if <condition> then
	...
elseif <condition> then
	...
elseif <condition> then
	...
elseif <condition> then
	...
end

You can also use the values in the keys API to turn the likes of:

if key == 22 then

… into a much more readable:

if key == keys.u then
SquidDev #3
Posted 14 February 2017 - 02:02 PM
When performing multiple assignments as a single statement, the build of LuaJ used by ComputerCraft stops as soon as as it hits the first nil value.
I think this is actually caused by the parallel API stopping at the first nil argument of an event, rather than LuaJ itself. Do you know if there is an existing bug report anywhere for this? - I'd not seen this before.
Edited on 14 February 2017 - 01:03 PM
Bomb Bloke #4
Posted 15 February 2017 - 12:53 AM
I think this is actually caused by the parallel API stopping at the first nil argument of an event, rather than LuaJ itself. Do you know if there is an existing bug report anywhere for this? - I'd not seen this before.

You're right, I can't reproduce last night's tests. I must've made a typo when first performing them.

The data gets lost whenever table.unpack() is used to pass on the event information. This happens both within the parallel API and in os.pullEvent().

Testing different VMs I do see different unpack behaviours, though I'm not sure what the intended one is. Certainly it doesn't matter in this case, as it merely serves to explain why bugged code bugs out in a particular manner, not why it bugs out in the first place. It has been discussed before, though.