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

Continuing After Os.pullevent() Even If The Event Doesn't Happen.

Started by NomNuggetNom, 20 August 2013 - 03:19 PM
NomNuggetNom #1
Posted 20 August 2013 - 05:19 PM
Hey folks, I'm writing a basic timer that can be controlled with two factors: If redstone is off, the timer is running. If redstone is on, the timer is stopped. I want to implement something that will allow me to toggle it on/off using the touchscreen, but I can't find anything that won't pause the script until it gets input. Any help is greatly appreciated :)/>. Here's my script: (or look on Pastebin for easier viewing)

timerActive = true
seconds = 0
minutes = 0
hours = 0
days = 0
local monitor = peripheral.wrap("right")
function drawColor(color,x,y)
monitor.setBackgroundColor(color)
monitor.setCursorPos(x,y)
monitor.clearLine()
end
function printMiddle(text, lineNum)
width, height = monitor.getSize()
stringLength = string.len(text)
startPos = math.floor(width/2) - math.floor(stringLength/2) + 1
monitor.setCursorPos(startPos,lineNum)
monitor.write(text)
end
function clearScreen()
monitor.setBackgroundColor(32768)
monitor.clear()
end
-------------
while true do
-------------
signalActive = rs.getInput("left")
timeString = ""..tostring(days).. "d "..tostring(hours).."h "..tostring(minutes).. "m "..tostring(seconds).."s "
--[[ Time Handling ]]--
if seconds == 59 then
seconds = 0
minutes = minutes + 1
end
if minutes == 59 then
minutes = 0
hours = hours + 1
end
if hours == 24 then
hours = 0
days = days + 1
end
--[[ Test for signal or touch and act ]]--
if signalActive then
timerActive = false
else
timerActive = true
end
--[[ timerActive ]]--
if not timerActive then
color = colors.red
monitor.setBackgroundColor(32768)
		printMiddle(timeString, 3)
else
color = colors.green
seconds = seconds + 1
monitor.setBackgroundColor(32768)
printMiddle(timeString, 3)
end

--[[ Touchscreen ]]-- This is causing the script to hang :(/>/>
--local event, param1 = os.pullEvent()
--if event == "monitor_touch" then
-- timerActive = not timeActive
--end
--[[ Draw the color ]]--
drawColor(color,1,1)
drawColor(color,1,5)
sleep(1)
clearScreen()
---
end
---
Lyqyd #2
Posted 20 August 2013 - 06:25 PM
Don't use sleep. Instead, restructure your loop to start a timer outside the loop (probably for zero seconds), then use an os.pullEvent. Handle redstone events, timer events, and monitor touch events. The sleep(1) and all your time code go into the timer event handling part of the if to handle the events, and the sleep changes to a os.startTimer call. The redstone and monitor touch handling parts change a control variable or some such that starts or stops the timer part, which it checks.

That's probably confusing. Perhaps someone with more time can explain more fully!
Grim Reaper #3
Posted 20 August 2013 - 06:42 PM
Maybe you could try checking for redstone events at the same time as monitor touches so either could happen at once.
When a redstone input changes on the computer, the redstone event will be fired.


local SIGNAL_SIDE = "left"
local timerActive = rs.getInput (SIGNAL_SIDE)

while true do
    local event = os.pullEvent()

    if event == "monitor_touch" then
        timerActive = not timerActive
    elseif event == "redstone" then
        timerActive = rs.getInput (SIGNAL_SIDE)
    end
end

You could probably use that as a frame to structure your graphics and timer logic around.