module Ramus.Time where
import Prelude hiding (filter)
import Ramus.Signal
import Control.Concurrent
import Data.IORef
import System.IO.Unsafe
type Time = Float
millisecond :: Time
millisecond = 1.0
second :: Time
second = 1000.0
every :: Time -> Signal Time
every = undefined
now :: IO Time
now = undefined
delay :: Time -> Signal a -> Signal a
delay t sig = unsafePerformIO $ do
let out = make $ get sig
first <- newIORef True
sig `subscribe` \val -> do
first' <- readIORef first
if first'
then writeIORef first False
else do
threadDelay (round $ t * 1000)
out `set` val
return out
since :: Time -> Signal a -> Signal Bool
since t sig = unsafePerformIO $ do
let out = make False
firstRef <- newIORef True
timerRef <- newIORef Nothing
let tick = do
out `set` False
writeIORef timerRef Nothing
sig `subscribe` \val -> do
first <- readIORef firstRef
if first
then writeIORef firstRef False
else do
timer <- readIORef timerRef
case timer of
Nothing -> do
out `set` True
tim <- forkIO $ do
threadDelay (round $ t * 1000)
tick
writeIORef timerRef $ Just tim
Just tim -> do
killThread tim
tim' <- forkIO $ do
threadDelay (round $ t * 1000)
tick
writeIORef timerRef $ Just tim'
return out
debounce :: Time -> Signal a -> Signal a
debounce t s =
let leading = whenChangeTo False $ since t s
in sampleOn leading s
where
whenEqual value = filter (value ==) value
whenChangeTo value input = whenEqual value $ dropRepeats input