summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2018-08-19 01:04:59 +0100
committerCarl Hetherington <cth@carlh.net>2018-08-19 01:29:04 +0100
commit6c7489e5d778d3e71065d88a094a7383ba2c117d (patch)
treee3f05ad03095d88d297c7d61e03e265d28a97fa3 /src/lib
parent9a27d60ea7888d300a5a2414a477091428589b82 (diff)
Replace May/Done/NotDone signal sets with one signal and extend
this treatment to anything that caused Player::setup_pieces. This should fix out-of-sequence Player emissions caused by setup_pieces being called by one thread while the butler is calling pass().
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/butler.cc59
-rw-r--r--src/lib/butler.h7
-rw-r--r--src/lib/content.cc8
-rw-r--r--src/lib/content.h12
-rw-r--r--src/lib/content_change.cc6
-rw-r--r--src/lib/film.cc20
-rw-r--r--src/lib/film.h10
-rw-r--r--src/lib/player.cc96
-rw-r--r--src/lib/player.h26
-rw-r--r--src/lib/playlist.cc83
-rw-r--r--src/lib/playlist.h14
-rw-r--r--src/lib/types.h7
12 files changed, 135 insertions, 213 deletions
diff --git a/src/lib/butler.cc b/src/lib/butler.cc
index f04b324cd..3a75e67d7 100644
--- a/src/lib/butler.cc
+++ b/src/lib/butler.cc
@@ -65,9 +65,7 @@ Butler::Butler (shared_ptr<Player> player, shared_ptr<Log> log, AudioMapping aud
_player_video_connection = _player->Video.connect (bind (&Butler::video, this, _1, _2));
_player_audio_connection = _player->Audio.connect (bind (&Butler::audio, this, _1, _2));
_player_text_connection = _player->Text.connect (bind (&Butler::text, this, _1, _2, _3));
- _player_may_change_connection = _player->MayChange.connect (bind (&Butler::suspend, this));
- _player_changed_connection = _player->Changed.connect (bind (&Butler::return_seek, this, _2));
- _player_not_changed_connection = _player->NotChanged.connect (bind (&Butler::return_seek, this, false));
+ _player_change_connection = _player->Change.connect (bind (&Butler::player_change, this, _1, _3));
_thread = new boost::thread (bind (&Butler::thread, this));
#ifdef DCPOMATIC_LINUX
pthread_setname_np (_thread->native_handle(), "butler");
@@ -107,10 +105,6 @@ Butler::~Butler ()
bool
Butler::should_run () const
{
- if (_suspended) {
- return false;
- }
-
if (_video.size() >= MAXIMUM_VIDEO_READAHEAD * 10) {
/* This is way too big */
throw ProgrammingError
@@ -131,7 +125,7 @@ Butler::should_run () const
LOG_WARNING ("Butler audio buffers reached %1 frames (video is %2)", _audio.size(), _video.size());
}
- if (_stop_thread || _finished || _died) {
+ if (_stop_thread || _finished || _died || _suspended) {
/* Definitely do not run */
return false;
}
@@ -198,7 +192,7 @@ Butler::get_video ()
boost::mutex::scoped_lock lm (_mutex);
/* Wait for data if we have none */
- while (_video.empty() && !_finished && !_died) {
+ while (_video.empty() && !_finished && !_died && !_suspended) {
_arrived.wait (lm);
}
@@ -316,27 +310,33 @@ Butler::memory_used () const
}
void
-Butler::return_seek (bool frequent)
+Butler::player_change (ChangeType type, bool frequent)
{
boost::mutex::scoped_lock lm (_mutex);
- if (_died || _pending_seek_position || frequent) {
- return;
- }
- DCPTime seek_to;
- DCPTime next = _video.get().second;
- if (_awaiting && _awaiting > next) {
- /* We have recently done a player_changed seek and our buffers haven't been refilled yet,
- so assume that we're seeking to the same place as last time.
- */
- seek_to = *_awaiting;
- } else {
- seek_to = next;
- }
+ if (type == CHANGE_TYPE_PENDING) {
+ _suspended = true;
+ } else if (type == CHANGE_TYPE_DONE) {
+
+ if (_died || _pending_seek_position || frequent) {
+ return;
+ }
+
+ DCPTime seek_to;
+ DCPTime next = _video.get().second;
+ if (_awaiting && _awaiting > next) {
+ /* We have recently done a player_changed seek and our buffers haven't been refilled yet,
+ so assume that we're seeking to the same place as last time.
+ */
+ seek_to = *_awaiting;
+ } else {
+ seek_to = next;
+ }
- seek_unlocked (seek_to, true);
- _suspended = false;
- _awaiting = seek_to;
+ seek_unlocked (seek_to, true);
+ _suspended = false;
+ _awaiting = seek_to;
+ }
}
void
@@ -349,10 +349,3 @@ Butler::text (PlayerText pt, TextType type, DCPTimePeriod period)
boost::mutex::scoped_lock lm2 (_buffers_mutex);
_closed_caption.put (make_pair(pt, period));
}
-
-void
-Butler::suspend ()
-{
- boost::mutex::scoped_lock lm (_mutex);
- _suspended = true;
-}
diff --git a/src/lib/butler.h b/src/lib/butler.h
index 6a13ed2d7..513176821 100644
--- a/src/lib/butler.h
+++ b/src/lib/butler.h
@@ -56,8 +56,7 @@ private:
void text (PlayerText pt, TextType type, DCPTimePeriod period);
bool should_run () const;
void prepare (boost::weak_ptr<PlayerVideo> video) const;
- void suspend ();
- void return_seek (bool frequent);
+ void player_change (ChangeType type, bool frequent);
void seek_unlocked (DCPTime position, bool accurate);
boost::shared_ptr<Player> _player;
@@ -102,7 +101,5 @@ private:
boost::signals2::scoped_connection _player_video_connection;
boost::signals2::scoped_connection _player_audio_connection;
boost::signals2::scoped_connection _player_text_connection;
- boost::signals2::scoped_connection _player_may_change_connection;
- boost::signals2::scoped_connection _player_changed_connection;
- boost::signals2::scoped_connection _player_not_changed_connection;
+ boost::signals2::scoped_connection _player_change_connection;
};
diff --git a/src/lib/content.cc b/src/lib/content.cc
index 8fd36a1d8..ae0b08dcc 100644
--- a/src/lib/content.cc
+++ b/src/lib/content.cc
@@ -179,10 +179,14 @@ Content::examine (shared_ptr<Job> job)
}
void
-Content::signal_changed (int p)
+Content::signal_change (ChangeType c, int p)
{
try {
- emit (boost::bind (boost::ref(Changed), shared_from_this(), p, _change_signals_frequent));
+ if (c == CHANGE_TYPE_PENDING || c == CHANGE_TYPE_CANCELLED) {
+ Change (c, shared_from_this(), p, _change_signals_frequent);
+ } else {
+ emit (boost::bind (boost::ref(Change), c, shared_from_this(), p, _change_signals_frequent));
+ }
} catch (boost::bad_weak_ptr) {
/* This must be during construction; never mind */
}
diff --git a/src/lib/content.h b/src/lib/content.h
index c9edf6e22..e8710ccb7 100644
--- a/src/lib/content.h
+++ b/src/lib/content.h
@@ -178,14 +178,8 @@ public:
std::list<UserProperty> user_properties () const;
- /* May be emitted from any thread */
- boost::signals2::signal<void ()> MayChange;
-
- /* Emitted from the GUI thread */
- boost::signals2::signal<void (boost::weak_ptr<Content>, int, bool)> Changed;
-
- /* May be emitted from any thread */
- boost::signals2::signal<void ()> NotChanged;
+ /* CHANGE_PENDING and CHANGE_CANCELLED may be emitted from any thread; CHANGE_DONE always from GUI thread */
+ boost::signals2::signal<void (ChangeType, boost::weak_ptr<Content>, int, bool)> Change;
boost::shared_ptr<VideoContent> video;
boost::shared_ptr<AudioContent> audio;
@@ -215,7 +209,7 @@ private:
friend struct audio_sampling_rate_test;
friend class ContentChange;
- void signal_changed (int);
+ void signal_change (ChangeType, int);
std::string _digest;
DCPTime _position;
diff --git a/src/lib/content_change.cc b/src/lib/content_change.cc
index c286f80eb..6e390dc76 100644
--- a/src/lib/content_change.cc
+++ b/src/lib/content_change.cc
@@ -26,16 +26,16 @@ ContentChange::ContentChange (Content* c, int p)
, _property (p)
, _done (true)
{
- _content->MayChange ();
+ _content->signal_change (CHANGE_TYPE_PENDING, _property);
}
ContentChange::~ContentChange ()
{
if (_done) {
- _content->signal_changed (_property);
+ _content->signal_change (CHANGE_TYPE_DONE, _property);
} else {
- _content->NotChanged ();
+ _content->signal_change (CHANGE_TYPE_CANCELLED, _property);
}
}
diff --git a/src/lib/film.cc b/src/lib/film.cc
index ba97f833e..846e8ac51 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -160,9 +160,9 @@ Film::Film (optional<boost::filesystem::path> dir)
{
set_isdcf_date_today ();
- _playlist_changed_connection = _playlist->Changed.connect (bind (&Film::playlist_changed, this));
+ _playlist_change_connection = _playlist->Change.connect (bind (&Film::playlist_change, this, _1));
_playlist_order_changed_connection = _playlist->OrderChanged.connect (bind (&Film::playlist_order_changed, this));
- _playlist_content_changed_connection = _playlist->ContentChanged.connect (bind (&Film::playlist_content_changed, this, _1, _2, _3));
+ _playlist_content_change_connection = _playlist->ContentChange.connect (bind (&Film::playlist_content_change, this, _1, _2, _3, _4));
if (dir) {
/* Make state.directory a complete path without ..s (where possible)
@@ -1154,8 +1154,12 @@ Film::active_frame_rate_change (DCPTime t) const
}
void
-Film::playlist_content_changed (weak_ptr<Content> c, int p, bool frequent)
+Film::playlist_content_change (ChangeType type, weak_ptr<Content> c, int p, bool frequent)
{
+ if (type != CHANGE_TYPE_DONE) {
+ return;
+ }
+
_dirty = true;
if (p == ContentProperty::VIDEO_FRAME_RATE) {
@@ -1164,14 +1168,16 @@ Film::playlist_content_changed (weak_ptr<Content> c, int p, bool frequent)
signal_changed (NAME);
}
- emit (boost::bind (boost::ref (ContentChanged), c, p, frequent));
+ emit (boost::bind (boost::ref (ContentChange), type, c, p, frequent));
}
void
-Film::playlist_changed ()
+Film::playlist_change (ChangeType type)
{
- signal_changed (CONTENT);
- signal_changed (NAME);
+ if (type == CHANGE_TYPE_DONE) {
+ signal_changed (CONTENT);
+ signal_changed (NAME);
+ }
}
void
diff --git a/src/lib/film.h b/src/lib/film.h
index 20a1e2ca6..c6c8403cb 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -327,7 +327,7 @@ public:
mutable boost::signals2::signal<void (Property)> Changed;
/** Emitted when some property of our content has changed */
- mutable boost::signals2::signal<void (boost::weak_ptr<Content>, int, bool)> ContentChanged;
+ mutable boost::signals2::signal<void (ChangeType, boost::weak_ptr<Content>, int, bool)> ContentChange;
/** Current version number of the state file */
static int const current_state_version;
@@ -338,9 +338,9 @@ private:
void signal_changed (Property);
std::string video_identifier () const;
- void playlist_changed ();
+ void playlist_change (ChangeType);
void playlist_order_changed ();
- void playlist_content_changed (boost::weak_ptr<Content>, int, bool frequent);
+ void playlist_content_change (ChangeType type, boost::weak_ptr<Content>, int, bool frequent);
void maybe_add_content (boost::weak_ptr<Job>, boost::weak_ptr<Content>, bool disable_audio_analysis);
void audio_analysis_finished ();
@@ -401,9 +401,9 @@ private:
/** film being used as a template, or 0 */
boost::shared_ptr<Film> _template_film;
- boost::signals2::scoped_connection _playlist_changed_connection;
+ boost::signals2::scoped_connection _playlist_change_connection;
boost::signals2::scoped_connection _playlist_order_changed_connection;
- boost::signals2::scoped_connection _playlist_content_changed_connection;
+ boost::signals2::scoped_connection _playlist_content_change_connection;
std::list<boost::signals2::connection> _job_connections;
std::list<boost::signals2::connection> _audio_analysis_connections;
diff --git a/src/lib/player.cc b/src/lib/player.cc
index df8c47cf9..0c3aea028 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -98,10 +98,8 @@ Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist
, _shuffler (0)
{
_film_changed_connection = _film->Changed.connect (bind (&Player::film_changed, this, _1));
- _playlist_changed_connection = _playlist->Changed.connect (bind (&Player::playlist_changed, this));
- _playlist_content_may_change_connection = _playlist->ContentMayChange.connect (bind(&Player::playlist_content_may_change, this));
- _playlist_content_changed_connection = _playlist->ContentChanged.connect (bind(&Player::playlist_content_changed, this, _1, _2, _3));
- _playlist_content_not_changed_connection = _playlist->ContentNotChanged.connect (bind(&Player::playlist_content_not_changed, this));
+ _playlist_change_connection = _playlist->Change.connect (bind (&Player::playlist_change, this, _1));
+ _playlist_content_change_connection = _playlist->ContentChange.connect (bind(&Player::playlist_content_change, this, _1, _3, _4));
set_video_container_size (_film->frame_size ());
film_changed (Film::AUDIO_PROCESSOR);
@@ -224,78 +222,21 @@ Player::setup_pieces_unlocked ()
}
void
-Player::playlist_content_may_change ()
+Player::playlist_content_change (ChangeType type, int property, bool frequent)
{
- {
+ if (type == CHANGE_TYPE_PENDING) {
boost::mutex::scoped_lock lm (_mutex);
/* The player content is probably about to change, so we can't carry on
until that has happened and we've rebuilt our pieces. Stop pass()
and seek() from working until then.
*/
_suspended = true;
+ } else if (type == CHANGE_TYPE_DONE) {
+ /* A change in our content has gone through. Re-build our pieces. */
+ setup_pieces ();
}
- MayChange ();
-}
-
-void
-Player::playlist_content_changed (weak_ptr<Content> w, int property, bool frequent)
-{
- /* A change in our content has gone through. Re-build our pieces and signal
- it to anybody that is interested.
- */
-
- shared_ptr<Content> c = w.lock ();
- if (!c) {
- return;
- }
-
- setup_pieces ();
-
- if (
- property == ContentProperty::POSITION ||
- property == ContentProperty::LENGTH ||
- property == ContentProperty::TRIM_START ||
- property == ContentProperty::TRIM_END ||
- property == ContentProperty::PATH ||
- property == VideoContentProperty::FRAME_TYPE ||
- property == VideoContentProperty::COLOUR_CONVERSION ||
- property == AudioContentProperty::STREAMS ||
- property == DCPContentProperty::NEEDS_ASSETS ||
- property == DCPContentProperty::NEEDS_KDM ||
- property == DCPContentProperty::CPL ||
- property == TextContentProperty::COLOUR ||
- property == TextContentProperty::EFFECT ||
- property == TextContentProperty::EFFECT_COLOUR ||
- property == FFmpegContentProperty::SUBTITLE_STREAM ||
- property == FFmpegContentProperty::FILTERS ||
- property == TextContentProperty::LINE_SPACING ||
- property == TextContentProperty::OUTLINE_WIDTH ||
- property == TextContentProperty::Y_SCALE ||
- property == TextContentProperty::FADE_IN ||
- property == TextContentProperty::FADE_OUT ||
- property == ContentProperty::VIDEO_FRAME_RATE ||
- property == TextContentProperty::USE ||
- property == TextContentProperty::X_OFFSET ||
- property == TextContentProperty::Y_OFFSET ||
- property == TextContentProperty::X_SCALE ||
- property == TextContentProperty::FONTS ||
- property == TextContentProperty::TYPE ||
- property == VideoContentProperty::CROP ||
- property == VideoContentProperty::SCALE ||
- property == VideoContentProperty::FADE_IN ||
- property == VideoContentProperty::FADE_OUT
- ) {
-
- Changed (property, frequent);
- }
-}
-
-void
-Player::playlist_content_not_changed ()
-{
- /* A possible content change did end up happening for some reason */
- NotChanged ();
+ Change (type, property, frequent);
}
void
@@ -314,14 +255,16 @@ Player::set_video_container_size (dcp::Size s)
_black_image->make_black ();
}
- Changed (PlayerProperty::VIDEO_CONTAINER_SIZE, false);
+ Change (CHANGE_TYPE_DONE, PlayerProperty::VIDEO_CONTAINER_SIZE, false);
}
void
-Player::playlist_changed ()
+Player::playlist_change (ChangeType type)
{
- setup_pieces ();
- Changed (PlayerProperty::PLAYLIST, false);
+ if (type == CHANGE_TYPE_DONE) {
+ setup_pieces ();
+ }
+ Change (type, PlayerProperty::PLAYLIST, false);
}
void
@@ -333,13 +276,14 @@ Player::film_changed (Film::Property p)
*/
if (p == Film::CONTAINER) {
- Changed (PlayerProperty::FILM_CONTAINER, false);
+ Change (CHANGE_TYPE_PENDING, PlayerProperty::FILM_CONTAINER, false);
} else if (p == Film::VIDEO_FRAME_RATE) {
/* Pieces contain a FrameRateChange which contains the DCP frame rate,
so we need new pieces here.
*/
+ /* XXX: missing PENDING! */
setup_pieces ();
- Changed (PlayerProperty::FILM_VIDEO_FRAME_RATE, false);
+ Change (CHANGE_TYPE_DONE, PlayerProperty::FILM_VIDEO_FRAME_RATE, false);
} else if (p == Film::AUDIO_PROCESSOR) {
if (_film->audio_processor ()) {
boost::mutex::scoped_lock lm (_mutex);
@@ -1187,10 +1131,14 @@ Player::discard_audio (shared_ptr<const AudioBuffers> audio, DCPTime time, DCPTi
void
Player::set_dcp_decode_reduction (optional<int> reduction)
{
+ Change (CHANGE_TYPE_PENDING, PlayerProperty::DCP_DECODE_REDUCTION, false);
+
{
boost::mutex::scoped_lock lm (_mutex);
if (reduction == _dcp_decode_reduction) {
+ lm.unlock ();
+ Change (CHANGE_TYPE_CANCELLED, PlayerProperty::DCP_DECODE_REDUCTION, false);
return;
}
@@ -1198,7 +1146,7 @@ Player::set_dcp_decode_reduction (optional<int> reduction)
setup_pieces_unlocked ();
}
- Changed (PlayerProperty::DCP_DECODE_REDUCTION, false);
+ Change (CHANGE_TYPE_DONE, PlayerProperty::DCP_DECODE_REDUCTION, false);
}
optional<DCPTime>
diff --git a/src/lib/player.h b/src/lib/player.h
index f7ab1000d..165820799 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -88,19 +88,7 @@ public:
boost::optional<DCPTime> content_time_to_dcp (boost::shared_ptr<Content> content, ContentTime t);
- /* The player's internal state may be about to change such so
- that its emissions from Video and Audio will suddenly be
- from an undefined position. Listeners should prepare
- themselves for this possibility.
- */
- boost::signals2::signal<void ()> MayChange;
-
- /** The player's internal state has now changed.
- *
- * The first parameter is what changed.
- * The second parameter is true if these signals are currently likely to be frequent.
- */
- boost::signals2::signal<void (int, bool)> Changed;
+ boost::signals2::signal<void (ChangeType, int, bool)> Change;
/** The change suggested by a MayChange did not happen */
boost::signals2::signal<void ()> NotChanged;
@@ -125,10 +113,8 @@ private:
void setup_pieces_unlocked ();
void flush ();
void film_changed (Film::Property);
- void playlist_changed ();
- void playlist_content_may_change ();
- void playlist_content_changed (boost::weak_ptr<Content>, int, bool);
- void playlist_content_not_changed ();
+ void playlist_change (ChangeType);
+ void playlist_content_change (ChangeType, int, bool);
std::list<PositionImage> transform_bitmap_texts (std::list<BitmapText>) const;
Frame dcp_to_content_video (boost::shared_ptr<const Piece> piece, DCPTime t) const;
DCPTime content_video_to_dcp (boost::shared_ptr<const Piece> piece, Frame f) const;
@@ -217,10 +203,8 @@ private:
boost::shared_ptr<AudioProcessor> _audio_processor;
boost::signals2::scoped_connection _film_changed_connection;
- boost::signals2::scoped_connection _playlist_changed_connection;
- boost::signals2::scoped_connection _playlist_content_may_change_connection;
- boost::signals2::scoped_connection _playlist_content_changed_connection;
- boost::signals2::scoped_connection _playlist_content_not_changed_connection;
+ boost::signals2::scoped_connection _playlist_change_connection;
+ boost::signals2::scoped_connection _playlist_content_change_connection;
};
#endif
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index 1bb0ad0d6..e4fc0f072 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -65,48 +65,38 @@ Playlist::~Playlist ()
}
void
-Playlist::content_may_change ()
+Playlist::content_change (ChangeType type, weak_ptr<Content> content, int property, bool frequent)
{
- ContentMayChange ();
-}
+ if (type == CHANGE_TYPE_DONE) {
+ if (
+ property == ContentProperty::TRIM_START ||
+ property == ContentProperty::TRIM_END ||
+ property == ContentProperty::LENGTH ||
+ property == VideoContentProperty::FRAME_TYPE
+ ) {
+ /* Don't respond to position changes here, as:
+ - sequencing after earlier/later changes is handled by move_earlier/move_later
+ - any other position changes will be timeline drags which should not result in content
+ being sequenced.
+ */
+ maybe_sequence ();
+ }
-void
-Playlist::content_not_changed ()
-{
- ContentNotChanged ();
-}
+ if (
+ property == ContentProperty::POSITION ||
+ property == ContentProperty::LENGTH ||
+ property == ContentProperty::TRIM_START ||
+ property == ContentProperty::TRIM_END) {
-void
-Playlist::content_changed (weak_ptr<Content> content, int property, bool frequent)
-{
- if (
- property == ContentProperty::TRIM_START ||
- property == ContentProperty::TRIM_END ||
- property == ContentProperty::LENGTH ||
- property == VideoContentProperty::FRAME_TYPE
- ) {
- /* Don't respond to position changes here, as:
- - sequencing after earlier/later changes is handled by move_earlier/move_later
- - any other position changes will be timeline drags which should not result in content
- being sequenced.
- */
- maybe_sequence ();
- }
-
- if (
- property == ContentProperty::POSITION ||
- property == ContentProperty::LENGTH ||
- property == ContentProperty::TRIM_START ||
- property == ContentProperty::TRIM_END) {
-
- ContentList old = _content;
- sort (_content.begin(), _content.end(), ContentSorter ());
- if (_content != old) {
- OrderChanged ();
+ ContentList old = _content;
+ sort (_content.begin(), _content.end(), ContentSorter ());
+ if (_content != old) {
+ OrderChanged ();
+ }
}
}
- ContentChanged (content, property, frequent);
+ ContentChange (type, content, property, frequent);
}
void
@@ -215,15 +205,18 @@ Playlist::as_xml (xmlpp::Node* node, bool with_content_paths)
void
Playlist::add (shared_ptr<Content> c)
{
+ Change (CHANGE_TYPE_PENDING);
_content.push_back (c);
sort (_content.begin(), _content.end(), ContentSorter ());
reconnect ();
- Changed ();
+ Change (CHANGE_TYPE_DONE);
}
void
Playlist::remove (shared_ptr<Content> c)
{
+ Change (CHANGE_TYPE_PENDING);
+
ContentList::iterator i = _content.begin ();
while (i != _content.end() && *i != c) {
++i;
@@ -231,7 +224,9 @@ Playlist::remove (shared_ptr<Content> c)
if (i != _content.end ()) {
_content.erase (i);
- Changed ();
+ Change (CHANGE_TYPE_DONE);
+ } else {
+ Change (CHANGE_TYPE_CANCELLED);
}
/* This won't change order, so it does not need a sort */
@@ -240,6 +235,8 @@ Playlist::remove (shared_ptr<Content> c)
void
Playlist::remove (ContentList c)
{
+ Change (CHANGE_TYPE_PENDING);
+
BOOST_FOREACH (shared_ptr<Content> i, c) {
ContentList::iterator j = _content.begin ();
while (j != _content.end() && *j != i) {
@@ -253,7 +250,7 @@ Playlist::remove (ContentList c)
/* This won't change order, so it does not need a sort */
- Changed ();
+ Change (CHANGE_TYPE_DONE);
}
class FrameRateCandidate
@@ -362,9 +359,7 @@ Playlist::reconnect ()
_content_connections.clear ();
BOOST_FOREACH (shared_ptr<Content> i, _content) {
- _content_connections.push_back (i->MayChange.connect(boost::bind(&Playlist::content_may_change, this)));
- _content_connections.push_back (i->Changed.connect(boost::bind(&Playlist::content_changed, this, _1, _2, _3)));
- _content_connections.push_back (i->NotChanged.connect(boost::bind(&Playlist::content_not_changed, this)));
+ _content_connections.push_back (i->Change.connect(boost::bind(&Playlist::content_change, this, _1, _2, _3, _4)));
}
}
@@ -461,6 +456,8 @@ Playlist::repeat (ContentList c, int n)
range.second = max (range.second, i->end ());
}
+ Change (CHANGE_TYPE_PENDING);
+
DCPTime pos = range.second;
for (int i = 0; i < n; ++i) {
BOOST_FOREACH (shared_ptr<Content> j, c) {
@@ -474,7 +471,7 @@ Playlist::repeat (ContentList c, int n)
sort (_content.begin(), _content.end(), ContentSorter ());
reconnect ();
- Changed ();
+ Change (CHANGE_TYPE_DONE);
}
void
diff --git a/src/lib/playlist.h b/src/lib/playlist.h
index 649887f72..d55232dad 100644
--- a/src/lib/playlist.h
+++ b/src/lib/playlist.h
@@ -75,21 +75,13 @@ public:
void repeat (ContentList, int);
/** Emitted when content has been added to or removed from the playlist; implies OrderChanged */
- mutable boost::signals2::signal<void ()> Changed;
+ mutable boost::signals2::signal<void (ChangeType)> Change;
mutable boost::signals2::signal<void ()> OrderChanged;
- mutable boost::signals2::signal<void ()> ContentMayChange;
- /** Emitted when something about a piece of our content has changed;
- * these emissions include when the position of the content changes.
- * Third parameter is true if signals are currently being emitted frequently.
- */
- mutable boost::signals2::signal<void (boost::weak_ptr<Content>, int, bool)> ContentChanged;
- mutable boost::signals2::signal<void ()> ContentNotChanged;
+ mutable boost::signals2::signal<void (ChangeType, boost::weak_ptr<Content>, int, bool)> ContentChange;
private:
- void content_may_change ();
- void content_changed (boost::weak_ptr<Content>, int, bool);
- void content_not_changed ();
+ void content_change (ChangeType, boost::weak_ptr<Content>, int, bool);
void reconnect ();
/** List of content. Kept sorted in position order. */
diff --git a/src/lib/types.h b/src/lib/types.h
index 42e2e3eec..22d652b3f 100644
--- a/src/lib/types.h
+++ b/src/lib/types.h
@@ -129,6 +129,13 @@ enum ReelType
REELTYPE_BY_LENGTH
};
+enum ChangeType
+{
+ CHANGE_TYPE_PENDING,
+ CHANGE_TYPE_DONE,
+ CHANGE_TYPE_CANCELLED
+};
+
/** Type of captions.
*
* The generally accepted definitions seem to be: