From 30a82076ba50a21c4df5fe4c46c8fc2ed25a7486 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 21 Feb 2014 08:55:52 +0100 Subject: [PATCH] PlayerListener: new interface to replace GlobalEvents access --- Makefile.am | 1 + src/Partition.cxx | 13 +++++++++++++ src/Partition.hxx | 9 +++++++-- src/PlayerControl.cxx | 5 +++-- src/PlayerControl.hxx | 10 +++++++--- src/PlayerListener.hxx | 36 ++++++++++++++++++++++++++++++++++++ src/PlayerThread.cxx | 8 ++++---- test/run_output.cxx | 8 +++++--- 8 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 src/PlayerListener.hxx diff --git a/Makefile.am b/Makefile.am index eb29477d2..44d70411e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -137,6 +137,7 @@ libmpd_a_SOURCES = \ src/Permission.cxx src/Permission.hxx \ src/PlayerThread.cxx src/PlayerThread.hxx \ src/PlayerControl.cxx src/PlayerControl.hxx \ + src/PlayerListener.hxx \ src/Playlist.cxx src/Playlist.hxx \ src/PlaylistError.cxx src/PlaylistError.hxx \ src/PlaylistGlobal.cxx src/PlaylistGlobal.hxx \ diff --git a/src/Partition.cxx b/src/Partition.cxx index 512912f96..de1170557 100644 --- a/src/Partition.cxx +++ b/src/Partition.cxx @@ -23,6 +23,7 @@ #include "output/MultipleOutputs.hxx" #include "mixer/Volume.hxx" #include "Idle.hxx" +#include "GlobalEvents.hxx" #ifdef ENABLE_DATABASE @@ -50,6 +51,18 @@ Partition::SyncWithPlayer() playlist.SyncWithPlayer(pc); } +void +Partition::OnPlayerSync() +{ + GlobalEvents::Emit(GlobalEvents::PLAYLIST); +} + +void +Partition::OnPlayerTagModified() +{ + GlobalEvents::Emit(GlobalEvents::TAG); +} + void Partition::OnMixerVolumeChanged(gcc_unused Mixer &mixer, gcc_unused int volume) { diff --git a/src/Partition.hxx b/src/Partition.hxx index cbdce2e86..991234a50 100644 --- a/src/Partition.hxx +++ b/src/Partition.hxx @@ -24,6 +24,7 @@ #include "output/MultipleOutputs.hxx" #include "mixer/Listener.hxx" #include "PlayerControl.hxx" +#include "PlayerListener.hxx" struct Instance; class MultipleOutputs; @@ -33,7 +34,7 @@ class SongLoader; * A partition of the Music Player Daemon. It is a separate unit with * a playlist, a player, outputs etc. */ -struct Partition final : private MixerListener { +struct Partition final : private PlayerListener, private MixerListener { Instance &instance; struct playlist playlist; @@ -48,7 +49,7 @@ struct Partition final : private MixerListener { unsigned buffered_before_play) :instance(_instance), playlist(max_length), outputs(*this), - pc(outputs, buffer_chunks, buffered_before_play) {} + pc(*this, outputs, buffer_chunks, buffered_before_play) {} void ClearQueue() { playlist.Clear(pc); @@ -192,6 +193,10 @@ struct Partition final : private MixerListener { void SyncWithPlayer(); private: + /* virtual methods from class PlayerListener */ + virtual void OnPlayerSync() override; + virtual void OnPlayerTagModified() override; + /* virtual methods from class MixerListener */ virtual void OnMixerVolumeChanged(Mixer &mixer, int volume) override; }; diff --git a/src/PlayerControl.cxx b/src/PlayerControl.cxx index bca3cc937..244b64f5c 100644 --- a/src/PlayerControl.cxx +++ b/src/PlayerControl.cxx @@ -26,10 +26,11 @@ #include -PlayerControl::PlayerControl(MultipleOutputs &_outputs, +PlayerControl::PlayerControl(PlayerListener &_listener, + MultipleOutputs &_outputs, unsigned _buffer_chunks, unsigned _buffered_before_play) - :outputs(_outputs), + :listener(_listener), outputs(_outputs), buffer_chunks(_buffer_chunks), buffered_before_play(_buffered_before_play), command(PlayerCommand::NONE), diff --git a/src/PlayerControl.hxx b/src/PlayerControl.hxx index 4eeccdb6c..b60227d23 100644 --- a/src/PlayerControl.hxx +++ b/src/PlayerControl.hxx @@ -29,6 +29,7 @@ #include +class PlayerListener; class MultipleOutputs; class DetachedSong; @@ -92,6 +93,8 @@ struct player_status { }; struct PlayerControl { + PlayerListener &listener; + MultipleOutputs &outputs; unsigned buffer_chunks; @@ -137,8 +140,8 @@ struct PlayerControl { * A copy of the current #DetachedSong after its tags have * been updated by the decoder (for example, a radio stream * that has sent a new tag after switching to the next song). - * This shall be used by the GlobalEvents::TAG handler to - * update the current #DetachedSong in the queue. + * This shall be used by PlayerListener::OnPlayerTagModified() + * to update the current #DetachedSong in the queue. * * Protected by #mutex. Set by the PlayerThread and consumed * by the main thread. @@ -173,7 +176,8 @@ struct PlayerControl { */ bool border_pause; - PlayerControl(MultipleOutputs &_outputs, + PlayerControl(PlayerListener &_listener, + MultipleOutputs &_outputs, unsigned buffer_chunks, unsigned buffered_before_play); ~PlayerControl(); diff --git a/src/PlayerListener.hxx b/src/PlayerListener.hxx new file mode 100644 index 000000000..06f00a4f5 --- /dev/null +++ b/src/PlayerListener.hxx @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_PLAYER_LISTENER_HXX +#define MPD_PLAYER_LISTENER_HXX + +class PlayerListener { +public: + /** + * Must call playlist_sync(). + */ + virtual void OnPlayerSync() = 0; + + /** + * The current song's tag has changed. + */ + virtual void OnPlayerTagModified() = 0; +}; + +#endif diff --git a/src/PlayerThread.cxx b/src/PlayerThread.cxx index d90f281c6..9f342ad5d 100644 --- a/src/PlayerThread.cxx +++ b/src/PlayerThread.cxx @@ -19,6 +19,7 @@ #include "config.h" #include "PlayerThread.hxx" +#include "PlayerListener.hxx" #include "decoder/DecoderThread.hxx" #include "decoder/DecoderControl.hxx" #include "MusicPipe.hxx" @@ -31,7 +32,6 @@ #include "output/MultipleOutputs.hxx" #include "tag/Tag.hxx" #include "Idle.hxx" -#include "GlobalEvents.hxx" #include "util/Domain.hxx" #include "thread/Name.hxx" #include "Log.hxx" @@ -359,7 +359,7 @@ Player::WaitForDecoder() pc.Unlock(); /* call syncPlaylistWithQueue() in the main thread */ - GlobalEvents::Emit(GlobalEvents::PLAYLIST); + pc.listener.OnPlayerSync(); return true; } @@ -696,7 +696,7 @@ update_song_tag(PlayerControl &pc, DetachedSong &song, const Tag &new_tag) /* the main thread will update the playlist version when he receives this event */ - GlobalEvents::Emit(GlobalEvents::TAG); + pc.listener.OnPlayerTagModified(); /* notify all clients that the tag of the current song has changed */ @@ -1124,7 +1124,7 @@ player_task(void *arg) pc.Unlock(); do_play(pc, dc, buffer); - GlobalEvents::Emit(GlobalEvents::PLAYLIST); + pc.listener.OnPlayerSync(); pc.Lock(); break; diff --git a/test/run_output.cxx b/test/run_output.cxx index fca5146df..15383fd2a 100644 --- a/test/run_output.cxx +++ b/test/run_output.cxx @@ -53,10 +53,11 @@ filter_plugin_by_name(gcc_unused const char *name) return NULL; } -PlayerControl::PlayerControl(gcc_unused MultipleOutputs &_outputs, +PlayerControl::PlayerControl(PlayerListener &_listener, + MultipleOutputs &_outputs, gcc_unused unsigned _buffer_chunks, gcc_unused unsigned _buffered_before_play) - :outputs(_outputs) {} + :listener(_listener), outputs(_outputs) {} PlayerControl::~PlayerControl() {} static AudioOutput * @@ -69,7 +70,8 @@ load_audio_output(EventLoop &event_loop, const char *name) return nullptr; } - static struct PlayerControl dummy_player_control(*(MultipleOutputs *)nullptr, + static struct PlayerControl dummy_player_control(*(PlayerListener *)nullptr, + *(MultipleOutputs *)nullptr, 32, 4); Error error;