module Engine.Sound.Source where import RIO import Sound.OpenAL qualified as OpenAL import UnliftIO.Resource qualified as Resource class HasSource a where getSource :: a -> OpenAL.Source instance HasSource OpenAL.Source where getSource :: Source -> Source getSource = Source -> Source forall a. a -> a id instance HasSource (a, OpenAL.Source) where getSource :: (a, Source) -> Source getSource = (a, Source) -> Source forall a b. (a, b) -> b snd allocateCollectionWith :: ( Resource.MonadResource m , Traversable t , HasSource o ) => (i -> m o) -> t i -> m (Resource.ReleaseKey, t o) allocateCollectionWith :: (i -> m o) -> t i -> m (ReleaseKey, t o) allocateCollectionWith i -> m o action t i collection = do t o loaded <- (i -> m o) -> t i -> m (t o) forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traverse i -> m o action t i collection ReleaseKey key <- IO () -> m ReleaseKey forall (m :: * -> *). MonadResource m => IO () -> m ReleaseKey Resource.register do let sources :: [Source] sources = (o -> Source) -> [o] -> [Source] forall a b. (a -> b) -> [a] -> [b] map o -> Source forall a. HasSource a => a -> Source getSource ([o] -> [Source]) -> [o] -> [Source] forall a b. (a -> b) -> a -> b $ t o -> [o] forall (t :: * -> *) a. Foldable t => t a -> [a] toList t o loaded [Source] -> IO () forall (m :: * -> *). MonadIO m => [Source] -> m () OpenAL.stop [Source] sources [Source] -> (Source -> IO ()) -> IO () forall (t :: * -> *) (f :: * -> *) a b. (Foldable t, Applicative f) => t a -> (a -> f b) -> f () for_ [Source] sources \Source source -> Source -> StateVar (Maybe Buffer) OpenAL.buffer Source source StateVar (Maybe Buffer) -> Maybe Buffer -> IO () forall t a (m :: * -> *). (HasSetter t a, MonadIO m) => t -> a -> m () OpenAL.$= Maybe Buffer forall a. Maybe a Nothing [Source] -> IO () forall a (m :: * -> *). (ObjectName a, MonadIO m) => [a] -> m () OpenAL.deleteObjectNames [Source] sources pure (ReleaseKey key, t o loaded) {-# INLINE play1 #-} play1 :: (HasSource a, MonadIO m) => a -> m () play1 :: a -> m () play1 a src = [a] -> m () forall (t :: * -> *) a (m :: * -> *). (Foldable t, HasSource a, MonadIO m) => t a -> m () play [a src] {-# INLINE play #-} play :: (Foldable t, HasSource a, MonadIO m) => t a -> m () play :: t a -> m () play = [Source] -> m () forall (m :: * -> *). MonadIO m => [Source] -> m () OpenAL.play ([Source] -> m ()) -> (t a -> [Source]) -> t a -> m () forall b c a. (b -> c) -> (a -> b) -> a -> c . (a -> Source) -> [a] -> [Source] forall a b. (a -> b) -> [a] -> [b] map a -> Source forall a. HasSource a => a -> Source getSource ([a] -> [Source]) -> (t a -> [a]) -> t a -> [Source] forall b c a. (b -> c) -> (a -> b) -> a -> c . t a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList {-# INLINE stop1 #-} stop1 :: (HasSource a, MonadIO m) => a -> m () stop1 :: a -> m () stop1 a src = [a] -> m () forall (t :: * -> *) a (m :: * -> *). (Foldable t, HasSource a, MonadIO m) => t a -> m () stop [a src] {-# INLINE stop #-} stop :: (Foldable t, HasSource a, MonadIO m) => t a -> m () stop :: t a -> m () stop = [Source] -> m () forall (m :: * -> *). MonadIO m => [Source] -> m () OpenAL.stop ([Source] -> m ()) -> (t a -> [Source]) -> t a -> m () forall b c a. (b -> c) -> (a -> b) -> a -> c . (a -> Source) -> [a] -> [Source] forall a b. (a -> b) -> [a] -> [b] map a -> Source forall a. HasSource a => a -> Source getSource ([a] -> [Source]) -> (t a -> [a]) -> t a -> [Source] forall b c a. (b -> c) -> (a -> b) -> a -> c . t a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList {-# INLINE toggle #-} toggle :: (HasSource a, MonadIO m) => Bool -> a -> m () toggle :: Bool -> a -> m () toggle Bool active a src = if Bool active then [Source] -> m () forall (m :: * -> *). MonadIO m => [Source] -> m () OpenAL.play [Source] srcs else [Source] -> m () forall (m :: * -> *). MonadIO m => [Source] -> m () OpenAL.stop [Source] srcs where srcs :: [Source] srcs = [a -> Source forall a. HasSource a => a -> Source getSource a src]