module Engine.Events ( Sink(..) , spawn , registerMany ) where import RIO import UnliftIO.Resource (MonadResource, ReleaseKey) import UnliftIO.Resource qualified as Resource import Engine.Events.Sink (MonadSink, Sink) import Engine.Events.Sink qualified as Sink spawn :: MonadSink st m => (event -> m ()) -> [Sink event st -> m ReleaseKey] -> m (ReleaseKey, Sink event st) spawn :: forall st (m :: * -> *) event. MonadSink st m => (event -> m ()) -> [Sink event st -> m ReleaseKey] -> m (ReleaseKey, Sink event st) spawn event -> m () handleEvent [Sink event st -> m ReleaseKey] sources = do (ReleaseKey sinkKey, Sink event st sink) <- forall rs (m :: * -> *) event. MonadSink rs m => (event -> m ()) -> m (ReleaseKey, Sink event rs) Sink.spawn event -> m () handleEvent ReleaseKey key <- forall (m :: * -> *). MonadResource m => [m ReleaseKey] -> m ReleaseKey registerMany forall a b. (a -> b) -> a -> b $ forall (f :: * -> *) a. Applicative f => a -> f a pure ReleaseKey sinkKey forall a. a -> [a] -> [a] : forall a b. (a -> b) -> [a] -> [b] map (forall a b. (a -> b) -> a -> b $ Sink event st sink) [Sink event st -> m ReleaseKey] sources pure (ReleaseKey key, Sink event st sink) registerMany :: MonadResource m => [m ReleaseKey] -> m ReleaseKey registerMany :: forall (m :: * -> *). MonadResource m => [m ReleaseKey] -> m ReleaseKey registerMany [m ReleaseKey] actions = forall (t :: * -> *) (f :: * -> *) a. (Traversable t, Applicative f) => t (f a) -> f (t a) sequenceA [m ReleaseKey] actions forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= forall (m :: * -> *). MonadResource m => IO () -> m ReleaseKey Resource.register forall b c a. (b -> c) -> (a -> b) -> a -> c . forall (t :: * -> *) (f :: * -> *) a b. (Foldable t, Applicative f) => (a -> f b) -> t a -> f () traverse_ forall (m :: * -> *). MonadIO m => ReleaseKey -> m () Resource.release