Reflex is a simple reaction time tester. Only the Return key is used in interaction with the program. When pressing Return for the first time, the user is instructed to Wait...; after a few seconds, the program says Go! and the user must strike Return again as fast as possible. The elapsed time is displayed and the test can be repeated.
Here is the program:
module Reflex where
import POSIX
import RandomGenerator
data State = Idle | Waiting Msg | Counting
format t = show (secOf t) ++ '.' : fracs ++ " secs"
where n = microsecOf t `div` 10000
fracs = if n<10 then '0':show n else show n
reflex env = class
print str = env.stdout.write (str ++ "\n")
tmr = new timer
gen = new baseGen (microsecOf env.startTime)
state := Idle
enter _ = action
case state of
Idle -> r <- gen.next
waitingTime = sec 2 + millisec (r `mod` 2000)
msg <- after waitingTime action
tmr.reset
print "Go!"
state := Counting
print "Wait..."
state := Waiting msg
Waiting msg -> abort msg
print "Cheat!!!"
state := Idle
Counting -> t <- tmr.sample
print (format t)
state := Idle
result action
env.stdin.installR enter
print "Press return to start"
root = newRoot reflex
Comments to the code: