    -- | Thread operations.
    module Sound.Osc.Time.Thread where

    import Control.Concurrent {- base -}
    import Control.Monad {- base -}

    import qualified Sound.Osc.Time as Time {- hosc -}

    {- | The 'pauseThread' limit (in seconds).
      Values larger than this require a different thread delay mechanism, see 'sleepThread'.
      The value is the number of microseconds in @maxBound::Int@.
    -}
    pauseThreadLimit :: Fractional n => n
    pauseThreadLimit :: forall n. Fractional n => n
    pauseThreadLimit = Int -> n
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    forall a. Bounded a => a
    maxBound :: Int) n -> n -> n
    forall a. Fractional a => a -> a -> a
    / n
    1e6

    -- | Pause current thread for the indicated duration (in seconds), see 'pauseThreadLimit'.
    pauseThreadFor :: RealFrac n => n -> IO ()
    pauseThreadFor :: forall n. RealFrac n => n -> IO ()
    pauseThreadFor n
    n = Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (n
    n n -> n -> Bool
    forall a. Ord a => a -> a -> Bool
    > n
    0) (Int -> IO ()
    threadDelay (n -> Int
    forall b. Integral b => n -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (n
    n n -> n -> n
    forall a. Num a => a -> a -> a
    * n
    1e6)))

    -- | Pause current thread until the given time, see 'pauseThreadLimit'.
    pauseThreadUntilTime :: RealFrac n => n -> IO ()
    pauseThreadUntilTime :: forall n. RealFrac n => n -> IO ()
    pauseThreadUntilTime n
    t = n -> IO ()
    forall n. RealFrac n => n -> IO ()
    pauseThreadFor (n -> IO ()) -> (NtpReal -> n) -> NtpReal -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (n
    t n -> n -> n
    forall a. Num a => a -> a -> a
    -) (n -> n) -> (NtpReal -> n) -> NtpReal -> n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NtpReal -> n
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (NtpReal -> IO ()) -> IO NtpReal -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< IO NtpReal
    Time.currentTime

    {- | Sleep current thread for the indicated duration (in seconds).
      Divides long sleeps into parts smaller than 'pauseThreadLimit'.
    -}
    sleepThreadFor :: RealFrac n => n -> IO ()
    sleepThreadFor :: forall n. RealFrac n => n -> IO ()
    sleepThreadFor n
    n =
      if n
    n n -> n -> Bool
    forall a. Ord a => a -> a -> Bool
    >= n
    forall n. Fractional n => n
    pauseThreadLimit
        then
          let n' :: n
    n' = n
    forall n. Fractional n => n
    pauseThreadLimit n -> n -> n
    forall a. Num a => a -> a -> a
    - n
    1
          in n -> IO ()
    forall n. RealFrac n => n -> IO ()
    pauseThreadFor n
    n' IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> n -> IO ()
    forall n. RealFrac n => n -> IO ()
    sleepThreadFor (n
    n n -> n -> n
    forall a. Num a => a -> a -> a
    - n
    n')
        else n -> IO ()
    forall n. RealFrac n => n -> IO ()
    pauseThreadFor n
    n

    {- | Sleep current thread until the given time.
      Divides long sleeps into parts smaller than 'pauseThreadLimit'.
    -}
    sleepThreadUntilTime :: RealFrac n => n -> IO ()
    sleepThreadUntilTime :: forall n. RealFrac n => n -> IO ()
    sleepThreadUntilTime n
    t = n -> IO ()
    forall n. RealFrac n => n -> IO ()
    sleepThreadFor (n -> IO ()) -> (NtpReal -> n) -> NtpReal -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (n
    t n -> n -> n
    forall a. Num a => a -> a -> a
    -) (n -> n) -> (NtpReal -> n) -> NtpReal -> n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NtpReal -> n
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (NtpReal -> IO ()) -> IO NtpReal -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< IO NtpReal
    Time.currentTime