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

os.pullEvent() timeout function?

Started by MrObsidy, 18 March 2016 - 07:31 AM
MrObsidy #1
Posted 18 March 2016 - 08:31 AM
Hiya!
So I am working on a custom Bios (/rom/startup) for my server (Yes, I know what I am doing), however I have a problem. In order to stop Boot Viruses, I want to make a "Press DEL to enter Setup" thing. However, as in normal RL Computers, BIOS is not auto-entered. So I want to have a timeout, after which the normal Boot from the specified Boot device boots.
So what I need is a os.pullEvent("timer" (for the timeout), "key" (for DEL)).
I can't use "if event == whatever", because If a rednet event ir redstone or whatever event triggers, You cannot get into the Setup. In order to fix this I could do a while not event == whatever loop, but If soneone does a redbet spam the systen will be halting forever there as It constantly Loops.
Maybe I can use the Parallel API?

Alex
Lupus590 #2
Posted 18 March 2016 - 10:14 AM
start a timer before you call os.pullEvent

http://computercraft...i/Os.startTimer


os.pullEvent only accepts one filter, if you want to accept mutiple events then don't give a filter and test your event types
Edit: or use the function that valithor is giving you, it's basically os.pullEvent but with support for multiple filters



--# Lua

local duration = 10 --# how long the timer lasts
local timerID = os.startTimer(duration)


while true do
  local event = { os.pullEvent() }

  if event[1] == "timer" then
	if event[2] == timerID then --# is this our timer
	  --# do something
	  break --#loop
	end --# if timerID
  elseif event[1] == "char" then
	--# do something
	--# if you want a particular key then you will have to test it here
	--# perhaps call a function to handle menu navigation
	break --#loop
  else
	--# not an event we are interested in, ignore it
  end
end --#loop

--# do stuff


Edited on 18 March 2016 - 12:17 PM
valithor #3
Posted 18 March 2016 - 12:29 PM
Seeing as you didn't want to do something like what Lupus suggested, you could so something like:

local function excludePullEvent(filter,...)
  -- #Making it to where you can pass a table of filters or just list them as individual args
  local filters
  if type(filter) == "table" then
	filters = filter
  else
	filters = {filter,...}
  end
  --#starting a loop, where we will pull events and check them against the filters table
  while true do
	local event = {os.pullEvent()}
	for k,v in pairs(filters) do
	  if v[1] == event[1] then
		return unpack(event)
	  end
	end
  end
end
Edited on 18 March 2016 - 11:30 AM
MrObsidy #4
Posted 18 March 2016 - 03:40 PM
Thanks!
Bomb Bloke #5
Posted 19 March 2016 - 10:41 AM
Seeing as you didn't want to do something like what Lupus suggested,

Erm, Lupus' code fits the bill just fine; just like yours, it acts on wanted events, and loops when receiving unwanted events. I suspect that MrObsidy wrote something similar but restarted his timer on every iteration… rednet spam won't otherwise cause the system to pause for any appreciable amount of extra time, let alone "forever". Putting aside that there's no point in having any modem channels open at that point in the boot process anyway.

Your function would ideally be used alongside code like Lupus' for this particular use-case, as his is required to confirm the correct timer has fired. It could be useful as a "wait for user input" thingy or somesuch, though.