{-# options_haddock prune #-}

-- |Description: API and combinators for 'SyncRead'.
module Polysemy.Conc.SyncRead (
  module Polysemy.Conc.SyncRead,
  module Polysemy.Conc.Effect.SyncRead,
) where

import qualified Polysemy.Time as Time
import Polysemy.Time (Time, TimeUnit)

import qualified Polysemy.Conc.Effect.SyncRead as SyncRead
import Polysemy.Conc.Effect.SyncRead (SyncRead, block, empty, try, wait)

-- |Run an action repeatedly until the 'SyncRead' variable is available.
whileEmpty ::
   a r .
  Member (SyncRead a) r =>
  Sem r () ->
  Sem r ()
whileEmpty :: forall a (r :: [(* -> *) -> * -> *]).
Member (SyncRead a) r =>
Sem r () -> Sem r ()
whileEmpty Sem r ()
action =
  Sem r ()
spin
  where
    spin :: Sem r ()
spin = do
      Sem r ()
action
      Sem r Bool -> Sem r () -> Sem r ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (Bool -> Bool
not (Bool -> Bool) -> Sem r Bool -> Sem r Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (SyncRead d) r =>
Sem r Bool
SyncRead.empty @a) Sem r ()
spin

-- |Run an action repeatedly until the 'SyncRead' variable is available, waiting for the specified time between executions.
whileEmptyInterval ::
   a u t d r .
  TimeUnit u =>
  Members [Time t d, SyncRead a] r =>
  u ->
  Sem r () ->
  Sem r ()
whileEmptyInterval :: forall a u t d (r :: [(* -> *) -> * -> *]).
(TimeUnit u, Members '[Time t d, SyncRead a] r) =>
u -> Sem r () -> Sem r ()
whileEmptyInterval u
interval Sem r ()
action =
  Sem r ()
spin
  where
    spin :: Sem r ()
spin = do
      Sem r ()
action
      Sem r Bool -> Sem r () -> Sem r ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (Bool -> Bool
not (Bool -> Bool) -> Sem r Bool -> Sem r Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (SyncRead d) r =>
Sem r Bool
SyncRead.empty @a) (forall t d u (r :: [(* -> *) -> * -> *]).
(TimeUnit u, Member (Time t d) r) =>
u -> Sem r ()
Time.sleep @t @d u
interval Sem r () -> Sem r () -> Sem r ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Sem r ()
spin)