{-# options_haddock prune #-}
-- |Description: Events/Consume Effects, Internal
module Polysemy.Conc.Effect.Events where

import Polysemy.Conc.Effect.Scoped (Scoped, scoped)

-- |Consume events emitted by 'Events'.
data Consume (e :: Type) :: Effect where
  Consume :: Consume e m e

makeSem ''Consume

-- |Marker for the 'Scoped' token for 'Events'.
newtype EventToken token =
  EventToken { EventToken token -> token
unEventToken :: token }
  deriving (EventToken token -> EventToken token -> Bool
(EventToken token -> EventToken token -> Bool)
-> (EventToken token -> EventToken token -> Bool)
-> Eq (EventToken token)
forall token.
Eq token =>
EventToken token -> EventToken token -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EventToken token -> EventToken token -> Bool
$c/= :: forall token.
Eq token =>
EventToken token -> EventToken token -> Bool
== :: EventToken token -> EventToken token -> Bool
$c== :: forall token.
Eq token =>
EventToken token -> EventToken token -> Bool
Eq, Int -> EventToken token -> ShowS
[EventToken token] -> ShowS
EventToken token -> String
(Int -> EventToken token -> ShowS)
-> (EventToken token -> String)
-> ([EventToken token] -> ShowS)
-> Show (EventToken token)
forall token. Show token => Int -> EventToken token -> ShowS
forall token. Show token => [EventToken token] -> ShowS
forall token. Show token => EventToken token -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EventToken token] -> ShowS
$cshowList :: forall token. Show token => [EventToken token] -> ShowS
show :: EventToken token -> String
$cshow :: forall token. Show token => EventToken token -> String
showsPrec :: Int -> EventToken token -> ShowS
$cshowsPrec :: forall token. Show token => Int -> EventToken token -> ShowS
Show, (forall x. EventToken token -> Rep (EventToken token) x)
-> (forall x. Rep (EventToken token) x -> EventToken token)
-> Generic (EventToken token)
forall x. Rep (EventToken token) x -> EventToken token
forall x. EventToken token -> Rep (EventToken token) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall token x. Rep (EventToken token) x -> EventToken token
forall token x. EventToken token -> Rep (EventToken token) x
$cto :: forall token x. Rep (EventToken token) x -> EventToken token
$cfrom :: forall token x. EventToken token -> Rep (EventToken token) x
Generic)

-- |An event publisher that can be consumed from multiple threads.
data Events (token :: Type) (e :: Type) :: Effect where
  Publish :: e -> Events token e m ()

makeSem ''Events

-- |Create a new scope for 'Events', causing the nested program to get its own copy of the event stream.
-- To be used with 'Polysemy.Conc.interpretEventsChan'.
subscribe ::
   e token r .
  Member (Scoped (EventToken token) (Consume e)) r =>
  InterpreterFor (Consume e) r
subscribe :: InterpreterFor (Consume e) r
subscribe =
  forall resource (effect :: Effect) (r :: [Effect]).
Member (Scoped resource effect) r =>
InterpreterFor effect r
forall (effect :: Effect) (r :: [Effect]).
Member (Scoped (EventToken token) effect) r =>
InterpreterFor effect r
scoped @(EventToken token)