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

Sleep without processing events?

Started by Pinkishu, 31 May 2012 - 10:33 AM
Pinkishu #1
Posted 31 May 2012 - 12:33 PM
Hi there,

just wondering if theres any good way to wait for e.g. 0.1 seconds without it dropping events of the event queue?
Cloudy #2
Posted 31 May 2012 - 02:00 PM
Yes - use timers - like so.


local timer = os.startTimer(0.1)
local event, param
while true do
  event, param = os.pullEvent()
  if event == "timer" and param = timer then
    timer = os.startTimer(0.1) --restart timer
    -- do stuff
  elseif event == "redstone" then
    --do other stuff
  end
end
Pinkishu #3
Posted 31 May 2012 - 02:12 PM
Well I meant without timers ;D cause doing it with makes stuff messy.. instead of having 1 function i need 2 or so since i can't just jump back to where it paused
MysticT #4
Posted 31 May 2012 - 05:42 PM
What are you trying to do? cause I think it would be possible with timers. You can make a sleep function that stores the received events and returns a table with them, so you can handle them after the sleep.
Pinkishu #5
Posted 31 May 2012 - 07:26 PM
Well just if i want to wait at some point of my code for 0.1 seconds it makes it a low messier if i have to fiddle with events and then a second function to do the rest after the 0.1 seconds instead of just doing

function foo()
  //part  a
  sleep(0.1)
  //partb
end

vs


function fooA()
  //partA
  //timer
end

function fooB()
  //partB (ALSO having to retain all the variables for procesing htat fooA set)
end

while true do
  //fetch event timer and call fooB
end
MysticT #6
Posted 31 May 2012 - 07:57 PM
If you don't want to miss events you need to handle them or save them. This function would sleep for the given time, and it returns a table containing the events that happend in that time so you can handle them later:

local function sleep2(nTime)
  local tEvts = {}
  local timer = os.startTimer(nTime)
  while true do
    local tEvt = { os.pullEvent() }
    if tEvt[1] == "timer" and tEvt[2] == timer then
	  break
    else
	  table.insert(tEvts, tEvt)
    end
  end
  return tEvts
end
You could use it like:

local events = sleep2(1)
for _,evt in ipairs(events) do
  -- handle the events
  -- evt[1] is the event type (like "redstone", "key", etc). evt[2], evt[3], ..., evt[n] are the arguments
  if evt[1] == "key" then
    handleKey(evt[2])
  elseif evt[1] == "rednet_message" then
    handleMessage(evt[2], evt[3])
  end
end
The only problem would be if there's too many events (if you sleep for too much), it may throw a "too long without yielding" error cause it would take too long to handle all the events.