module Engine.Sound.Source where
import RIO
import Sound.OpenAL.FFI.AL qualified as AL
import UnliftIO.Resource qualified as Resource
import Foreign qualified
class HasSource a where
getSource :: a -> AL.Source
instance HasSource AL.Source where
getSource :: Source -> Source
getSource = Source -> Source
forall a. a -> a
id
instance HasSource (a, AL.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
[Source] -> (Int -> Ptr Source -> IO ()) -> IO ()
forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
Foreign.withArrayLen ((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) \Int
num ->
CInt -> Ptr Source -> IO ()
AL.alDeleteSources (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
num)
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 (t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [a]
sources) =
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$
[Source] -> (Int -> Ptr Source -> IO ()) -> IO ()
forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
Foreign.withArrayLen ((a -> Source) -> [a] -> [Source]
forall a b. (a -> b) -> [a] -> [b]
map a -> Source
forall a. HasSource a => a -> Source
getSource [a]
sources) \Int
num ->
CInt -> Ptr Source -> IO ()
AL.alSourcePlayv (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
num)
{-# 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 (t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [a]
sources) =
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$
[Source] -> (Int -> Ptr Source -> IO ()) -> IO ()
forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
Foreign.withArrayLen ((a -> Source) -> [a] -> [Source]
forall a b. (a -> b) -> [a] -> [b]
map a -> Source
forall a. HasSource a => a -> Source
getSource [a]
sources) \Int
num ->
CInt -> Ptr Source -> IO ()
AL.alSourceStopv (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
num)
{-# INLINE toggle #-}
toggle :: (HasSource a, MonadIO m) => Bool -> a -> m ()
toggle :: Bool -> a -> m ()
toggle Bool
active a
src =
if Bool
active then
a -> m ()
forall a (m :: * -> *). (HasSource a, MonadIO m) => a -> m ()
play1 a
src
else
a -> m ()
forall a (m :: * -> *). (HasSource a, MonadIO m) => a -> m ()
stop1 a
src