From 2a16dcba5a31a45a12853a15254719c357baae6d Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Wed, 31 May 2023 20:53:12 +0200 Subject: use an atomic pointer to track the current song Also fix showing finished songs as current playing on new clients. --- main.go | 6 +++++- player.go | 4 ++-- web/client.html | 10 ++++++++-- wrms.go | 17 +++++++++-------- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 0539e1a..53dc440 100644 --- a/main.go +++ b/main.go @@ -232,7 +232,11 @@ func wsEndpoint(w http.ResponseWriter, r *http.Request) { initialCmds := [][]byte{} if wrms.Playing { - data, err := json.Marshal(newEvent("play", []Song{wrms.CurrentSong})) + var songs []Song + if currentSong := wrms.CurrentSong.Load(); currentSong != nil { + songs = []Song{*currentSong} + } + data, err := json.Marshal(newEvent("play", songs)) if err != nil { llog.Error("Encoding the play event failed with %s", err) return diff --git a/player.go b/player.go index db1936a..db4457c 100644 --- a/player.go +++ b/player.go @@ -68,12 +68,12 @@ func (player *Player) runMpv() { llog.Fatal("Mpv failed with: %s", err.Error()) } - wrms := player.wrms + currentSong := wrms.CurrentSong.Load() llog.Info("mpv finished. Resetting mpv, and calling next") player.mpv = nil - player.Backends[wrms.CurrentSong.Source].OnSongFinished(&wrms.CurrentSong) + player.Backends[currentSong.Source].OnSongFinished(currentSong) wrms.Next() } diff --git a/web/client.html b/web/client.html index 91ce11d..c0aef1f 100644 --- a/web/client.html +++ b/web/client.html @@ -202,9 +202,15 @@ playing = document.getElementById("playing").innerHTML = ""; } - function handlePlay(currentSong) { + function handlePlay(_currentSongs) { {{if .IsAdmin}} document.getElementById("ppbutton").innerHTML = 'Pause'; {{end}} + if (_currentSongs == null || _currentSongs.length == 0) { + return; + } + + const currentSong = _currentSongs[0] + idx = -1; songs.forEach(function(s, i, a) { if (s.uri == currentSong.uri) idx = i; }); if (idx != -1) { @@ -251,7 +257,7 @@ handleStop() break; case "play": - handlePlay(cmd.songs[0]) + handlePlay(cmd.songs) break; case "upvoted": handleVotes("up", cmd.songs) diff --git a/wrms.go b/wrms.go index 0a844cb..fd1d10f 100644 --- a/wrms.go +++ b/wrms.go @@ -112,7 +112,7 @@ type Wrms struct { Connections sync.Map Songs []Song queue Playlist - CurrentSong Song + CurrentSong atomic.Pointer[Song] Player Player Playing bool Config Config @@ -149,12 +149,13 @@ func (wrms *Wrms) Broadcast(ev Event) { } func (wrms *Wrms) startPlaying() { - wrms.Broadcast(newEvent("play", []Song{wrms.CurrentSong})) - wrms.Player.Play(&wrms.CurrentSong) + currentSong := wrms.CurrentSong.Load() + wrms.Broadcast(newEvent("play", []Song{*currentSong})) + wrms.Player.Play(currentSong) } func (wrms *Wrms) AddSong(song Song) { - startPlayingAgain := wrms.Playing && wrms.CurrentSong.Uri == "" + startPlayingAgain := wrms.Playing && wrms.CurrentSong.Load() == nil wrms.Songs = append(wrms.Songs, song) s := &wrms.Songs[len(wrms.Songs)-1] wrms.queue.Add(s) @@ -187,17 +188,17 @@ func (wrms *Wrms) Next() { next := wrms.queue.PopSong() if next == nil { - wrms.CurrentSong.Uri = "" + wrms.CurrentSong.Store(nil) wrms.Broadcast(newNotification("stop")) return } - wrms.CurrentSong = *next + wrms.CurrentSong.Store(next) llog.Info("popped next song and removing it from the song list %v", next) for i, s := range wrms.Songs { - if s.Uri == wrms.CurrentSong.Uri { + if s.Uri == next.Uri { wrms.Songs[i] = wrms.Songs[len(wrms.Songs)-1] wrms.Songs = wrms.Songs[:len(wrms.Songs)-1] break @@ -213,7 +214,7 @@ func (wrms *Wrms) PlayPause() { wrms.Playing = !wrms.Playing if wrms.Playing { - if wrms.CurrentSong.Uri == "" { + if wrms.CurrentSong.Load() == nil { llog.Info("No song currently playing play the next") wrms.Next() } else { -- cgit v1.2.3