{-# LANGUAGE CPP #-} module Timers where #if MIN_VERSION_time(1,8,0) import Data.Time.Clock.System #else import System.Time #endif import Data.IORef import PQueue import Stypes(Timer(..)) type TimersVar = IORef Timers data Timers = Timers { tq::PQueue MsTime (MsTime,Timer),tno::Int } type MsTime = Int initTimers = newIORef (Timers empty 0) createTimer tref interval first = do Timers tq tno <- readIORef tref now <- mstime writeIORef tref (Timers (insert tq (now+first,(interval,Ti tno))) (tno+1)) return (Ti tno) destroyTimer tref t = do Timers tq tno <- readIORef tref writeIORef tref (Timers (remove tq t) tno) timeLeft tref = do tqv <- tq `fmap` readIORef tref case inspect tqv of Nothing -> return Nothing Just ((t,_),_) -> do ms <- mstime return . Just . max 0 $ t - ms removeTimeQ tref = do Timers tqv tno <- readIORef tref case inspect tqv of Just ((first,v@(interval,tnov)),tqv') -> do let tqv2 = if interval == 0 then tqv' else insert tqv' (first+interval,v) writeIORef tref (Timers tqv2 tno) return tnov mstime :: IO MsTime mstime = #if MIN_VERSION_time(1,8,0) do MkSystemTime s ns <- getSystemTime #else do TOD s ps <- getClockTime let ns = ps `quot` 1000 #endif return (fromIntegral s * 1000 + fromIntegral ns `quot` 1000000) -- This overflows with 32-bit Int, but it's ok.