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

how to give an os.pullEvent a timeout? (And return nil?)

Started by fatboychummy, 21 November 2016 - 01:42 AM
fatboychummy #1
Posted 21 November 2016 - 02:42 AM
so, I am making a rather large script, and was wondering about some parts of os.pullevent().

I would like it to time out after a certain period of time, and then run another function within the script if it times out.
Is there a way I can do this? I tried the rednet.receive thing where you set it's parameters to rednet.receive(_,number), but that didn't work.


[attachment=2695:Capture.PNG]
Dog #2
Posted 21 November 2016 - 03:12 AM
I believe it's just rednet.receive(number), and yeah, os.pullEvent doesn't have a timeout. You're probably best using a timer, then act on the event captured with an if/elseif statement.

local myTimer = os.startTimer(5)
while true do
  local a, b, c, d, e = os.pullEvent()
  if a == "timer" and b == myTimer then --# act when myTimer triggers
    --# do timer stuff
  elseif a == "myEvent" then --# act when the event you are waiting for triggers
    --# do event stuff
  end
end
Edited on 21 November 2016 - 02:14 AM
fatboychummy #3
Posted 21 November 2016 - 03:39 AM
I believe it's just rednet.receive(number), and yeah, os.pullEvent doesn't have a timeout. You're probably best using a timer, then act on the event captured with an if/elseif statement.

local myTimer = os.startTimer(5)
while true do
  local a, b, c, d, e = os.pullEvent()
  if a == "timer" and b == myTimer then --# act when myTimer triggers
	--# do timer stuff
  elseif a == "myEvent" then --# act when the event you are waiting for triggers
	--# do event stuff
  end
end


So… I did that.


Now I have a crapload of empty timer events???
literally so many timer events that it looks like this:
http://imgur.com/vZvoTwB
(these events are fired EVERY TICK, but my timer is set to fire every 0.7 seconds).


… So, on the other hand. I'm just going to scrap the timer thing (for now, unless I find a better way). but now the timer things have seemed to stay (Not sure if it is a glitch on CC's hand, because I am using CCtweaks).
Dog #4
Posted 21 November 2016 - 04:03 AM
Only one timer event will fire with the code I gave you. I'd need to see the code you wrote to help you work out why it's acting the way it is. As for the timer events somehow persisting, I have no answer for that.
Bomb Bloke #5
Posted 21 November 2016 - 05:07 AM
Also bear in mind that timer events always go to the end of the event queue. One appearing every server tick won't stop you from pulling other events, unless you're somehow spawning enough additional events to overflow the queue (which has a maximum length of 256 entries).

If they really bug you, you could always call os.cancelTimer(timerID) on timers you're sure you don't need any more. As Dog says, though, no one can really comment on why your code runs the way it does if you're not going to show it to us.
HDeffo #6
Posted 22 November 2016 - 03:23 PM

local iEventTime = 0
local tEventData
os.pullEventRaw = function (event, timeout)
   iEventTime = os.time()
   while true do
	  tEventData = {coroutine.yield()}
	  if not event or tEventData[1] == event then
		 return unpack (tEventData)
	  elseif timeout and os.time()-iEventTime >= timeout then
		 return nil
	  end
   end
end
os.pullEvent = function (event, timeout)
   os.pullEventRaw (event, timeout)
   if tEventData[1]=="terminate" then
	  error ("terminated", 0)
   else
	  return unpack (tEventData)
   end
end


There you go events with timeouts and no timers
Edited on 23 November 2016 - 05:26 AM
Bomb Bloke #7
Posted 22 November 2016 - 03:43 PM
And if event == nil…? :P/>

Frankly though, having os.pullEventRaw() return nil is very limiting. Performing the timer check within one's own code allows for much more flexible solutions.
HDeffo #8
Posted 23 November 2016 - 06:26 AM
And if event == nil…? :P/>

Frankly though, having os.pullEventRaw() return nil is very limiting. Performing the timer check within one's own code allows for much more flexible solutions.

lol fixed :P/> I agree just receiving nil from it is a limited choice but it is exactly as he asked for so it solves the question to his specification exactly.
Cross_Sans #9
Posted 04 December 2016 - 01:56 PM

local received = false;
function waitBeforeFunction()
sleep(5);
if received == false then
  myfunction();
end
return;
end
function rednetReceive()
local event, message, id = os.pullEvent("rednet_receive");
received = true;
--# Do someting with event, message and id.
return;
end
parallel.waitForAny(rednetReceive, waitBeforeFunction);
Edited on 04 December 2016 - 12:59 PM
Dog #10
Posted 04 December 2016 - 03:55 PM
Redall - afaik there is no event named "rednet_receive" - I believe the event you're looking for is "rednet_message".