urbit/pkg/hs-urbit/lib/Urbit/Behn.hs

53 lines
1.4 KiB
Haskell
Raw Normal View History

2019-05-06 00:46:40 +03:00
{-
# Behn
This provides a timer. To use this,
- Create a new timer with `init`.
- Use `doze` to start the timer.
- Call `wait` to wait until the timer fires.
Then, `wait` will return when the specified time has come.
- If the specified time was in the past, `wait` will return immediately.
- If a timer is set again, the old timer will not fire. The new time
replaces the old one.
- If a timer is unset (with `doze _ Nothing`), the timer will not fire
until a new time has been set.
-}
2019-05-08 21:47:20 +03:00
module Urbit.Behn (Behn, init, wait, doze) where
2019-05-06 00:46:40 +03:00
2019-05-08 21:47:20 +03:00
import Prelude hiding (init)
import Control.Lens
2019-05-06 00:46:40 +03:00
2019-05-09 02:57:34 +03:00
import Control.Concurrent.MVar (MVar, takeMVar, newEmptyMVar, putMVar)
import Control.Monad (void, when)
import Data.IORef (IORef, writeIORef, readIORef, newIORef)
2019-05-06 00:46:40 +03:00
import qualified Urbit.Timer as Timer
import qualified Urbit.Time as Time
import qualified GHC.Event as Ev
2019-05-06 00:46:40 +03:00
-- Behn Stuff ------------------------------------------------------------------
data Behn = Behn
{ bTimer :: Timer.Timer
, bSignal :: MVar ()
2019-05-06 00:46:40 +03:00
}
init :: IO Behn
init = do
tim <- Timer.init
2019-05-06 00:46:40 +03:00
sig <- newEmptyMVar
pure (Behn tim sig)
2019-05-09 02:57:34 +03:00
wait :: Behn -> IO ()
wait (Behn _ sig) = takeMVar sig
2019-05-09 02:57:34 +03:00
doze :: Behn -> Maybe Time.Wen -> IO ()
doze behn Nothing = Timer.stop (bTimer behn)
doze (Behn tim sig) (Just t) =
Timer.start tim (t ^. Time.systemTime) (putMVar sig ())