RipCDDialog: no longer forces Cdda* to emit signals

- CddaDevice: Removed LoadSongs() method (then renamed ForceLoadSongs to LoadSongs)
- CddaDevice: added songs() method to get currently song list
- CddaSongLoader: cached_tracks is now thread-safe
This commit is contained in:
Lukas Prediger 2021-08-23 19:15:23 +03:00 committed by John Maguire
parent 2936578fa4
commit fd585e8aa4
5 changed files with 44 additions and 35 deletions

View File

@ -52,7 +52,7 @@ bool CddaDevice::Init() {
if (!cdio_) { if (!cdio_) {
cdio_ = cdio_open(url_.path().toLocal8Bit().constData(), DRIVER_DEVICE); cdio_ = cdio_open(url_.path().toLocal8Bit().constData(), DRIVER_DEVICE);
if (!cdio_) return false; if (!cdio_) return false;
ForceLoadSongs(); LoadSongs();
WatchForDiscChanges(true); WatchForDiscChanges(true);
} }
return true; return true;
@ -71,16 +71,11 @@ void CddaDevice::WatchForDiscChanges(bool watch) {
disc_changed_timer_.stop(); disc_changed_timer_.stop();
} }
void CddaDevice::ForceLoadSongs() { void CddaDevice::LoadSongs() {
cdda_song_loader_.LoadSongs(); cdda_song_loader_.LoadSongs();
disc_changed_timer_.stop(); disc_changed_timer_.stop();
} }
void CddaDevice::LoadSongs() {
SongList songs = cdda_song_loader_.cached_tracks();
SongsLoaded(songs);
}
void CddaDevice::SongsLoaded(const SongList& songs) { void CddaDevice::SongsLoaded(const SongList& songs) {
model_->Reset(); model_->Reset();
song_count_ = songs.size(); song_count_ = songs.size();
@ -111,6 +106,8 @@ void CddaDevice::CheckDiscChanged() {
song_count_ = 0; song_count_ = 0;
SongList no_songs; SongList no_songs;
SongsLoaded(no_songs); SongsLoaded(no_songs);
ForceLoadSongs(); LoadSongs();
} }
} }
SongList CddaDevice::songs() const { return cdda_song_loader_.cached_tracks(); }

View File

@ -54,7 +54,7 @@ class CddaDevice : public ConnectedDevice {
// Check whether a valid device handle was opened. // Check whether a valid device handle was opened.
bool IsValid() const; bool IsValid() const;
void WatchForDiscChanges(bool watch); void WatchForDiscChanges(bool watch);
void LoadSongs(); SongList songs() const;
static QStringList url_schemes() { return QStringList() << "cdda"; } static QStringList url_schemes() { return QStringList() << "cdda"; }
@ -79,7 +79,7 @@ class CddaDevice : public ConnectedDevice {
void CheckDiscChanged(); void CheckDiscChanged();
private: private:
void ForceLoadSongs(); void LoadSongs();
CdIo_t* cdio_; CdIo_t* cdio_;
QTimer disc_changed_timer_; QTimer disc_changed_timer_;

View File

@ -68,6 +68,7 @@ bool CddaSongLoader::IsActive() const { return loading_future_.isRunning(); }
void CddaSongLoader::LoadSongs() { void CddaSongLoader::LoadSongs() {
// only dispatch a new thread for loading tracks if not already running. // only dispatch a new thread for loading tracks if not already running.
if (!IsActive()) { if (!IsActive()) {
QMutexLocker lock(&disc_mutex_);
disc_ = Disc(); disc_ = Disc();
loading_future_ = loading_future_ =
QtConcurrent::run(this, &CddaSongLoader::LoadSongsFromCdda); QtConcurrent::run(this, &CddaSongLoader::LoadSongsFromCdda);
@ -350,37 +351,45 @@ void CddaSongLoader::ProcessMusicBrainzResponse(
return; return;
} }
if (disc_.tracks.length() != results.length()) { {
qLog(Warning) << "Number of tracks in metadata does not match number of " QMutexLocker lock(&disc_mutex_);
"songs on disc!";
// no idea how to recover; signal that no further updates will follow now if (disc_.tracks.length() != results.length()) {
emit Finished(); qLog(Warning) << "Number of tracks in metadata does not match number of "
return; "songs on disc!";
// no idea how to recover; signal that no further updates will follow now
emit Finished();
return;
}
for (int i = 0; i < results.length(); ++i) {
const MusicBrainzClient::Result& new_song_info = results[i];
Song& song = disc_.tracks[i];
if (!disc_.has_titles) song.set_title(new_song_info.title_);
if (song.album().isEmpty()) song.set_album(album);
if (song.artist().isEmpty()) song.set_artist(artist);
if (song.length_nanosec() == -1)
song.set_length_nanosec(new_song_info.duration_msec_ * kNsecPerMsec);
if (song.track() < 1) song.set_track(new_song_info.track_);
if (song.year() == -1) song.set_year(new_song_info.year_);
}
disc_.has_titles = true;
} }
for (int i = 0; i < results.length(); ++i) {
const MusicBrainzClient::Result& new_song_info = results[i];
Song& song = disc_.tracks[i];
if (!disc_.has_titles) song.set_title(new_song_info.title_);
if (song.album().isEmpty()) song.set_album(album);
if (song.artist().isEmpty()) song.set_artist(artist);
if (song.length_nanosec() == -1)
song.set_length_nanosec(new_song_info.duration_msec_ * kNsecPerMsec);
if (song.track() < 1) song.set_track(new_song_info.track_);
if (song.year() == -1) song.set_year(new_song_info.year_);
}
disc_.has_titles = true;
emit SongsMetadataLoaded(disc_.tracks); emit SongsMetadataLoaded(disc_.tracks);
emit Finished(); // no further updates will follow emit Finished(); // no further updates will follow
} }
void CddaSongLoader::SetDiscTracks(const SongList& songs, bool has_titles) { void CddaSongLoader::SetDiscTracks(const SongList& songs, bool has_titles) {
QMutexLocker lock(&disc_mutex_);
disc_.tracks = songs; disc_.tracks = songs;
disc_.has_titles = has_titles; disc_.has_titles = has_titles;
emit SongsUpdated(disc_.tracks); emit SongsUpdated(disc_.tracks);
} }
SongList CddaSongLoader::cached_tracks() const { return disc_.tracks; } SongList CddaSongLoader::cached_tracks() const {
QMutexLocker lock(&disc_mutex_);
return disc_.tracks;
}

View File

@ -48,8 +48,8 @@ class CddaSongLoader : public QObject {
void LoadSongs(); void LoadSongs();
bool IsActive() const; bool IsActive() const;
// The list of currently cached tracks. This gets updated during calls // The list of currently cached tracks. This gets updated when
// LoadSongs() is called. Not thread-safe. // LoadSongs() is called.
SongList cached_tracks() const; SongList cached_tracks() const;
signals: signals:
@ -110,6 +110,7 @@ class CddaSongLoader : public QObject {
QFuture<void> loading_future_; QFuture<void> loading_future_;
std::atomic<bool> may_load_; std::atomic<bool> may_load_;
Disc disc_; Disc disc_;
mutable QMutex disc_mutex_;
}; };
#endif // CDDASONGLOADER_H #endif // CDDASONGLOADER_H

View File

@ -335,10 +335,12 @@ void RipCDDialog::DeviceSelected(int device_index) {
return; return;
} }
SongList songs = cdda_device_->songs();
SongsLoaded(songs);
connect(cdda_device_.get(), SIGNAL(DiscChanged()), SLOT(DiscChanged())); connect(cdda_device_.get(), SIGNAL(DiscChanged()), SLOT(DiscChanged()));
connect(cdda_device_.get(), SIGNAL(SongsDiscovered(SongList)), connect(cdda_device_.get(), SIGNAL(SongsDiscovered(SongList)),
SLOT(SongsLoaded(SongList))); SLOT(SongsLoaded(SongList)));
cdda_device_->LoadSongs();
} }
void RipCDDialog::Finished(Ripper* ripper) { void RipCDDialog::Finished(Ripper* ripper) {