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

Detect and stop Ctrl+T while allowing countdown

Started by Rasputin, 04 June 2012 - 07:57 PM
Rasputin #1
Posted 04 June 2012 - 09:57 PM
Hey there, I have a small problem with a program I'm creating to control a nuclear reactor. The reactor is controlled by the program and runs continuously for three hours before an automatic shutdown takes place, however, I do not want users to be able to terminate the program (I will install it as the startup program).

The problem is that when I have both the countdown AND blocking (ctrl+t) code in the same function the countdown does not take place.

function countdown()
term.clear()
term.setCursorPos(1,1)
  s = 5
  m = 0
  h = 0
  tleft = "yes"
  delay = s + m*60 + h*3600
if tleft == "yes" then
  while delay ~= 0 do
   h = math.floor(delay/3600)
   m = math.floor(delay/60 - h*60)
   s = math.floor(delay -h*3600 -m*60)
   print("		  +----------------------------+")
   print("		  |  Reactor Control		  |")
   print("		  +----------------------------+")
   print("			Ctrl+T Emergency shutdown	  ")
   print("			Reactor is " .. reactor .. "")
   print("			Time until shutdown " .. h, ":", m, ":", s .. "  ")
   print("		  +----------------------------+")
  local event, param = os.pullEventRaw()
	  if event == "terminate" then
	   forceshutdown(main)
	  end
   sleep(1)
   delay = delay - 1
   term.clear()
   term.setCursorPos( 1, 1 )
  if delay == 0 then  
   forceshutdown()
   break
  end
  end
end
end

Countdown progresses when holding down any key, it should countdown regardless of keys being pressed and should only terminate when ctrl+t is detected, which is what happens.

Help of any kind is greatly appreciated!
my_hat_stinks #2
Posted 04 June 2012 - 10:05 PM
The problem is that it waits at os.pullEventRaw() for an event to occur

You could either use hooks and timers ( :)/>/>) or modify your code so the sleep is instead a timer os.startTimer(1), start it befoer the pull event, put os.pullEventRaw() in an endless loop, and break the loop with "break" on either the correct timer event, or the terminate event

Something along the lines of this:
local CountdownTimer = os.startTimer(1)
while true do
   local e,p1 = os.pullEventRaw()
   if e=="terminate" then
	  --[[Terminate stuff here]]
   elseif e=="timer" and p1==CountdownTimer then
	  break --End the loop
   end
end
Rasputin #3
Posted 04 June 2012 - 10:16 PM
The problem is that it waits at os.pullEventRaw() for an event to occur

You could either use hooks and timers ( :)/>/>) or modify your code so the sleep is instead a timer os.startTimer(1), start it befoer the pull event, put os.pullEventRaw() in an endless loop, and break the loop with "break" on either the correct timer event, or the terminate event

Something along the lines of this:
local CountdownTimer = os.startTimer(1)
while true do
   local e,p1 = os.pullEventRaw()
   if e=="terminate" then
	  --[[Terminate stuff here]]
   elseif e=="timer" and p1==CountdownTimer then
	  break --End the loop
   end
end

Would this allow the digital countdown, though? The countdown is visibly counting down in seconds, minutes and hours…
my_hat_stinks #4
Posted 04 June 2012 - 10:21 PM
Would this allow the digital countdown, though? The countdown is visibly counting down in seconds, minutes and hours…

As long as you replace the lines
local event, param = os.pullEventRaw()
	  if event == "terminate" then
	   forceshutdown(main)
	  end
   sleep(1)
With what I posted, and it'll work the exact same way

The only difference is that the sleep is also dealt with in the event, so it shouldn't just wait until something happens to count down
D3matt #5
Posted 04 June 2012 - 10:56 PM
Also, you will want to store your countdown outside the file, otherwise somebody can ctrl-R to restart the timer, and BOOM goes the reactor when its 3 hours are up.
kazagistar #6
Posted 05 June 2012 - 12:08 AM
Here is something I have never been completely clear about… if the chunk unloads, and then reloads, is there any way to get the computer to turn back on automatically? I feel like the simplest solution is to have the computer output a redstone signal if it is on, and then pass it to an inverter right before it hits the generator, so if the computer is off, the generator will shut off automatically. Otherwise, you might get the case where the computer is in an unloaded chunk, but the generator is still loaded, and fails to get shut off properly.
Cranium #7
Posted 24 July 2012 - 04:21 AM
You could always have the program run a constant print to file command for the current state of cable/redstone output, then have it read the previous state on startup.
I don't know how it's done myself, but I know some people have done it successfully.