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

Break a loop using a monitor_touch event

Started by petomka, 12 August 2014 - 01:58 PM
petomka #1
Posted 12 August 2014 - 03:58 PM
Hey!

Im new here to the forums and also new to LUA so i don't know if there's an existing post and I couldn't find something on google. So, how you could see in the title, my problem is that i don't know how I should break a loop with a monitor_touch event.

I'll explain briefly what this program does: I programmed it for a mobfarm I built. There are 5 buttons, each of them showing a number. If you press one of these buttons, a timer will start, the computer connected to the monitor will ouput a redstone signal and the farm starts to work until the timer is over. Then you're back in the menu where the 5 buttons are.

My problem: While the timer is running, I'd like to add a button to cancel the timer and immediately return to the menu. But I can't get the code right. Either the timer doesn't "time" or the button doesn't react to the monitor_touch.

The code for the timer is the following:
Spoiler

function Timer()
while time >= 0.2 do
  CancelButton()
  m.clear()
  m.setCursorPos(1,3)
  m.write(time)
  time = time - 0.1
  sleep(0.1)
  event,side,x,y = os.pullEvent()
  if event == "monitor_touch" then
   if x >= 1 and y == 5 then
	time = 0
	break
   end
  end
end
end

You can find the full code on pastebin: http://pastebin.com/AfTkq4mD

Thanks for any replies!
KingofGamesYami #2
Posted 12 August 2014 - 07:37 PM
You want to manually make a timer. This is actually quite simple.

function doRedstone( side, time )
 rs.setOutput( side, true ) --#turn on redstone
 local id = os.startTimer( time ) --#start a timer event in "time" seconds.
 while true do --#loop
  local event = {os.pullEvent()} --#pull an event
  if event[ 1 ] == "timer" and event[ 2 ] == id then --#sleeping time is over
   break --#exit the loop
  elseif event[ 1 ] == "monitor_touch" and event[ 3 ] >= 1 and event[ 4 ] == 5 then --#button was pushed
   break --#exit the loop
  end
 end
 rs.setOutput( side, false ) --#turn off redstone
end
petomka #3
Posted 12 August 2014 - 10:06 PM
Thanks for your reply, KingofGamesYami.

But It wasn't actually for what i was looking for.
If I start a timer, I'd like things looking like this:

http://imgur.com/13Rsem8 (I couldn't put the image, so please view the link)

In your version I miss an (at least for me) important feature, namely that you can see how long the timer did actually run (or am I too retarded to put the code right?) .
KingofGamesYami #4
Posted 12 August 2014 - 10:35 PM
Well, it is relatively easy to add that…

local function isIn( tbl, value ) --#table search function.
for k, v in pairs( tbl ) do
  if v == value then
   return true
  end
end
return false
end
function doRedstone( side, time )
 rs.setOutput( side, true ) --#turn on redstone
 local ids = {}
 for i = 0.1, time, 0.1 do --#make a bunch of timers.
  ids[ #ids + 1 ] = os.startTimer( i )
 end
 local num = 0
 while true do --#loop
  local event = {os.pullEvent()} --#pull an event
  if event[ 1 ] == "timer" and event[ 2 ] == ids[ #ids ] then --#last timer is up
   break --#exit the loop
  elseif event[ 1 ] == "monitor_touch" and event[ 3 ] >= 1 and event[ 4 ] == 5 then --#button was pushed
   break --#exit the loop
  elseif event[ 1 ] == "timer" and isIn( ids, event[ 2 ] ) then --#the event was a timer we made, but not the last one
   num = num + 0.1
   term.setCursorPos( 1, 1 )
   term.write( num )
  end
 end
 rs.setOutput( side, false ) --#turn off redstone
end
Edited on 12 August 2014 - 08:41 PM
petomka #5
Posted 12 August 2014 - 11:01 PM
I replaced your code with my timer, but now I can't even start the timer any more. I got the following error message as well:
test:81: Expected string, boolean

Line 81 in my code is where you put this:
rs.setOutput( side, true ) --#turn on redstone

I feel so noobish… But thanks that you're trying man :)/>
KingofGamesYami #6
Posted 13 August 2014 - 12:22 AM
I replaced your code with my timer, but now I can't even start the timer any more. I got the following error message as well:
test:81: Expected string, boolean

Line 81 in my code is where you put this:
rs.setOutput( side, true ) --#turn on redstone

I feel so noobish… But thanks that you're trying man :)/>
You need to give the function the side.
Call it like this:

doRedstone( "right", 10 )
petomka #7
Posted 13 August 2014 - 12:45 AM
You're awesome man :lol:/>

I got things working now exactly like I imagined, thank you :)/> The only thing I changed was that the timer is a countdown now, so I can see how much time is left!

Really thanks for helping me out :D/>