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

Running parallel?

Started by Zamithal, 27 December 2012 - 05:49 PM
Zamithal #1
Posted 27 December 2012 - 06:49 PM

rednet.open("top")
function getColor()
  if redstone.testBundledInput("left", colors.white) == true then
	color = "white"
  elseif redstone.testBundledInput("left", colors.lightBlue) == true then
	color = "lightBlue"
  elseif redstone.testBundledInput("left", colors.yellow) == true then
	color = "yellow"
  elseif redstone.testBundledInput("left", colors.magenta) == true then
	color = "magenta"
  elseif redstone.testBundledInput("left", colors.purple) == true then
	color = "purple"
  elseif redstone.testBundledInput("left", colors.lime) == true then
	color = "lime"
  elseif redstone.testBundledInput("left", colors.orange) == true then
	color = "orange"
  elseif redstone.testBundledInput("left", colors.red) == true then
	color = "red"
  elseif redstone.testBundledInput("left", colors.pink) == true then
	color = "pink"
  end
end
function getReading()
   local senderId, message, distance = rednet.receive()
   color = message
end

function getTrueColor()
   if color == "white" then
	 trueColor = 1
   elseif color == "lightBlue" then
	 trueColor = 8
   elseif color == "yellow" then
	 trueColor = 16
   elseif color == "magenta" then
	 trueColor = 4
   elseif color == "purple" then
	 trueColor = 1024
   elseif color == "lime" then
	 trueColor = 32
   elseif color == "orange" then
	 trueColor = 2
   elseif color == "red" then
	 trueColor = 16384
   elseif color == "pink" then
	 trueColor = 64
   end
  redstone.setBundledOutput("right", trueColor)
end

while true do
parallel.waitForAny(getColor(), getReading(), getTrueColor)
end

Can someone explain to me what is wrong with this code? it never turns on any output (I have not tried brodcasting it a message yet, just the wire inputs.)
Kingdaro #2
Posted 27 December 2012 - 06:59 PM
Remove the parentheses on your functions in the parallel.waitForAny call.

parallel.waitForAny(getColor, getReading, getTrueColor)
Lyqyd #3
Posted 27 December 2012 - 07:00 PM
I think your biggest issue is using the parentheses in the call to parallel.waitForAny. You just pass the function names, you don't call them. This code could be vastly improved, though.

Edit: I believe this will do what you're looking for.


rednet.open("top")

while true do
    e, p1, p2 = os.pullEvent()
    if e == "rednet_message" then
        if colors[p2] then rs.setBundledOutput("right", colors[p2]) end
    elseif e == "redstone" then
        rs.setBundledOutput("right", rs.getBundledInput("left"))
    end
end
Zamithal #4
Posted 27 December 2012 - 07:07 PM
I know, i'm rather new at this, Id love to hear your suggestions for improving upon my code. in addition to this, i'm now greeted with a parallel:4:Coroutine limit of 50 reached.
Kingdaro #5
Posted 27 December 2012 - 07:12 PM
Yep, Lyqyd's right. A long list of elseifs usually isn't the best way of doing things, especially in cases of repetition. Here are some nice function rewrites:


function getColor()
  for name, value in pairs(colors) do
    if redstone.testBundledInput("left", value) then
      color = name
      break
    end
  end
end

function getTrueColor()
  trueColor = colors[color]
  redstone.setBundledOutput("right", trueColor)
end

The getColor function basically goes through all of CC's base colors, and if it finds one of the color values in the bundled input, then it sets the global color to the color's name in the colors table.

The getTrueColor function is pretty simple. Since the color is basically a color name, we can just get it directly from the colors table.

EDIT: Bah, you posted before me.

I know, i'm rather new at this, Id love to hear your suggestions for improving upon my code. in addition to this, i'm now greeted with a parallel:4:Coroutine limit of 50 reached.

I believe it's because, with that while true loop, parallel basically continually recreates coroutines for your functions, and all of the functions only execute once, so it's like a coroutine overload with your functions not even being used.

To fix that, have all of your functions using their code surrounded in a while loop, and don't forget the sleep(). Here's an example of how to go about doing that with my rewrites:


function getColor()
  while true do
    for name, value in pairs(colors) do
      if redstone.testBundledInput("left", value) then
        color = name
        break
      end
    end
    sleep(0.5)
  end
end

function getTrueColor()
  while true do
    trueColor = colors[color]
    redstone.setBundledOutput("right", trueColor)
    sleep(0.5)
  end
end

Lyqyd #6
Posted 27 December 2012 - 07:15 PM
OP, I don't know if you saw my edit or not, but I'll bring the code back down here and comment it. I know it looks too small to do what you had your code doing, but it'll work:


rednet.open("top")

while true do
    e, p1, p2 = os.pullEvent() --We pull an event here.  In this way, we can listen for both rednet_message events (like rednet.receive()) and redstone events, so when know when our inputs change.
    if e == "rednet_message" then
   	 if colors[p2] then rs.setBundledOutput("right", colors[p2]) end --if the message we got (stored in p2) was the name of a color (like blue; this is the same as using colors.blue), then set the output to that color.
    elseif e == "redstone" then
        rs.setBundledOutput("right", rs.getBundledInput("left")) --otherwise, if we got a redstone event, set the output on the right to whatever the input on the left is.
    end
end
Zamithal #7
Posted 27 December 2012 - 07:22 PM
Ok thank you, I was originally trying to use

redstone.setBundledOutput("right", "colors."color)
but that didn't work so i moved to elseifs….

So, replacing the elseif functions i'm still left with parallel:4:Coroutine limit of 50 reached, and Lyqyds code works, but i would like the latest input to stay on, and i don't understand enough of it to change it myself.

What I THINK i have gathered:

e is the event?
p1 is the sender ID?
p2 is the message recieved?
colors[variable] is the proper form of "colors."color correct?

edit: ok coroutine fixed
edit 2: I lied, it isn't fixed by putting the while true's inside the function :(/>
Edited on 27 December 2012 - 06:35 PM
Lyqyd #8
Posted 27 December 2012 - 07:37 PM
Well, here's a slightly hacky way to do it, based on my code:


rednet.open("top")

while true do
	e, p1, p2 = os.pullEvent()
	if e == "rednet_message" then
		if colors[p2] then rs.setBundledOutput("right", colors[p2]) end
	elseif e == "redstone" then
		rs.setBundledOutput("right", rs.getBundledInput("left") == 0 and rs.getBundledOutput("right") or rs.getBundledInput("left"))
	end
end

The changed line is now basically: Set the bundled output on the right to the bundled input on the left, unless the bundled input on the left is 0 (no input), in which case, set the bundled output on the right to whatever it currently is.

Edit: Also, as to the things you gathered so far: Right on all four counts, though p1 and p2 are event-specific. The values you mentioned are indeed their values for rednet_message events.
Zamithal #9
Posted 27 December 2012 - 07:46 PM
Ok. thank you, this achieves my desired goal, however i haven't seen ors and ands used outside of conitional statements before, so im not quite sure of what to make of that. :D/>
ChunLing #10
Posted 27 December 2012 - 10:42 PM
Lua evaluates conditional values as nil/false or anything else. So operators like and and or just pass along a value if it is not nil/false, based on whether the prior value was nil false (and passes the second value if the first value is not nil/false, or passes the second value if the first is nil/false). This means that you can use them to replace certain simple if then else end structures (actually, since you can use functions in them, there's no limit to the complexity of the if then else structures they can replace, but you don't save any effort/processor cycles doing that).

Derped out a bit there.
Edited on 27 December 2012 - 09:43 PM