package radio import ( "encoding/json" "sync" "time" ) // Song_ stores artist and title of a song, a timestamp of when it started, and // a maximum number of listeners. type Song_ struct { Artist string Title string MaxListeners int StartAt time.Time } func (s *Song_) ArtistTitle() string { return s.Artist + " - " + s.Title } func (s *Song_) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { Artist string `json:"artist"` Title string `json:"title"` MaxListeners int `json:"listeners"` StartAt string `json:"start_at"` }{ Artist: s.Artist, Title: s.Title, MaxListeners: s.MaxListeners, StartAt: s.StartAt.UTC().Format(time.RFC3339)}) } type SongList struct { mut sync.Mutex current Song_ lastSongs []Song_ listMaxLen int } func NewSongList(length int) *SongList { return &SongList{listMaxLen: length, lastSongs: make([]Song_, 0, length)} } // Add a new song that is currently playing and update a list. func (sl *SongList) Add(newSong Song_) { sl.mut.Lock() defer sl.mut.Unlock() if len(sl.lastSongs) == sl.listMaxLen { sl.lastSongs = append(sl.lastSongs[1:], sl.current) } else { sl.lastSongs = append(sl.lastSongs, sl.current) } sl.current = newSong } // Current returns a current playing song. func (sl *SongList) Current() *Song_ { sl.mut.Lock() defer sl.mut.Unlock() return &sl.current } // List returns a list of lastly played songs. func (sl *SongList) List() []Song_ { sl.mut.Lock() defer sl.mut.Unlock() return sl.lastSongs }