Skip to content

Instantly share code, notes, and snippets.

@supki
Created May 18, 2013 18:11
Show Gist options
  • Save supki/5605322 to your computer and use it in GitHub Desktop.
Save supki/5605322 to your computer and use it in GitHub Desktop.
M
-- | Look for player state changes over time
candidate :: Wire Error Y.MPD Int64 Change
candidate = mkStateM NotPlaying $ \_dt (t, s) ->
Y.stState `fmap` Y.status >>= \s' -> case (s, s') of
-- If we were not playing and are not playing now there is no candidate to send
(NotPlaying, Y.Stopped) -> return (Left NoCandidate, NotPlaying)
(NotPlaying, Y.Paused) -> return (Left NoCandidate, NotPlaying)
-- If we started playing just now there is a candidate to send
(NotPlaying, Y.Playing) -> do
Just song <- Y.currentSong
return (Right (Just (fetchTrackData song & timestamp .~ t)), Playing song t)
-- If we were playing and are not playing now we send that change
(Playing _ _, Y.Stopped) -> return (Right Nothing, NotPlaying)
(Playing _ _, Y.Paused) -> return (Right Nothing, NotPlaying)
-- If we were playing and are playing everything become complicated
(Playing song ts, Y.Playing) -> do
Just song' <- Y.currentSong
-- If the songs are different, then new song is a candidate to send
if song /= song' then
return (Right (Just (fetchTrackData song' & timestamp .~ t)), Playing song' t)
else
-- Otherwise, if song has been played more then its duration
-- it means that its looped, so we send it as candidate once again
let ts' = ts + fromIntegral (Y.sgLength song)
in if ts + fromIntegral (Y.sgLength song) < t
then return (Right (Just (fetchTrackData song' & timestamp .~ ts')), Playing song' ts')
-- Otherwise, there is no candidate to send
else return (Left NoCandidate, s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment