Reflex

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: