--- a/upqo/ohplaylist_qo.h
+++ b/upqo/ohplaylist_qo.h
@@ -29,6 +29,8 @@
#include "libupnpp/control/cdircontent.hxx"
#include "libupnpp/soaphelp.hxx"
+#include "ohpool.h"
+
class OHPLMetadata {
public:
virtual std::string getDidl() const = 0;
@@ -92,13 +94,21 @@
}
public slots:
- virtual void sync() {
- //qDebug() << "OHPL::sync";
+
+ /// Read state from the remote. Used when starting up, to avoid
+ /// having to wait for events.
+ virtual void fetchState() {
std::vector<int> ids;
- int tp;
- if (idArray(&ids, &tp)) {
+ int tok;
+ if (idArray(&ids, &tok))
onIdArrayChanged(ids);
- }
+ if (m_srv->id(&tok) == 0) {
+ m_curid = tok;
+ emit currentTrackId(tok);
+ }
+ UPnPClient::OHPlaylist::TPState tpst;
+ if (m_srv->transportState(&tpst) == 0)
+ emit tpStateChanged(tpst);
}
// Ping renderer to check it's still there.
@@ -188,20 +198,6 @@
return ret == 0;
}
- /// Read state from the remote. Used when starting up, to avoid
- /// having to wait for events.
- virtual void fetchState() {
- std::vector<int> ids;
- int tok;
- m_srv->idArray(&ids, &tok);
- onIdArrayChanged(ids);
- if (m_srv->id(&tok) == 0)
- emit currentTrackId(tok);
- UPnPClient::OHPlaylist::TPState tpst;
- if (m_srv->transportState(&tpst) == 0)
- emit tpStateChanged(tpst);
- }
-
signals:
void currentTrackId(int);
void trackArrayChanged();
@@ -216,91 +212,16 @@
private slots:
void onIdArrayChanged(std::vector<int> nids) {
- //qDebug() << "OHPL::onIdArrayChanged: " << vtos(nids).c_str();
-
- // We used to do nothing if the id array was unchanged, but
- // this gained very little, and going through lets us
- // re-read the current title metadata further on. This could
- // have changed without an id change, for example if the renderer
- // is upmpdcli and mpd is playing an internet radio (no qvers
- // update when the title changes).
-#if 0
- if (!m_forceUpdate && nids == m_idsv) {
- //qDebug() << "OHPL::onIdArrayChanged: unchanged";
+ m_forceUpdate = false;
+ m_idsv = nids;
+
+ if (!ohupdmetapool(nids, m_curid, m_metapool, m_srv))
return;
- }
-#endif
- m_forceUpdate = false;
-
- // Clean up metapool entries not in ids. We build a set with
- // the new ids list first. For small lists it does not matter,
- // for big ones, this will prevent what would otherwise be a
- // linear search the repeated search to make this
- // quadratic. We're sort of O(n * log(n)) instead.
- if (!m_metapool.empty() && !nids.empty()){
- STD_UNORDERED_SET<int> tmpset(nids.begin(), nids.end());
- for (STD_UNORDERED_MAP<int, UPnPClient::UPnPDirObject>::iterator it
- = m_metapool.begin(); it != m_metapool.end(); ) {
- if (tmpset.find(it->first) == tmpset.end()) {
- it = m_metapool.erase(it);
- } else {
- it++;
- }
- }
- }
-
- // Find ids for which we have no metadata. Always re-read current title
- std::vector<int> unids; // unknown
- for (std::vector<int>::iterator it = nids.begin();
- it != nids.end(); it++) {
- if (m_metapool.find(*it) == m_metapool.end() || m_curid == *it)
- unids.push_back(*it);
- }
- if (!unids.empty()) {
- //qDebug() << "OHPL::onIdArrayChanged: need metadata for: "
- // << vtos(unids).c_str();
- }
- // Fetch needed metadata, 10 entries at a time
- const unsigned int batchsize(10);
- for (unsigned int i = 0; i < unids.size();) {
- unsigned int j = 0;
- std::vector<int> metaslice;
- for (; j < batchsize && (i+j) < unids.size(); j++) {
- metaslice.push_back(unids[i+j]);
- }
-
- //qDebug() << "OHPL::onIdArrayChanged: Requesting metadata for "
- //<< vtos(metaslice).c_str();
- std::vector<UPnPClient::OHPlaylist::TrackListEntry> entries;
- int ret;
- if ((ret = m_srv->readList(metaslice, &entries))) {
- qDebug() << "OHPL: readList failed: " << ret;
- goto out;
- }
- for (std::vector<UPnPClient::OHPlaylist::TrackListEntry>::iterator
- it = entries.begin(); it != entries.end(); it++) {
- //qDebug() << "OHPL: data for " << it->id << " " <<
- // it->dirent.m_title.c_str();
- // Kazoo for example does not set a resource (uri)
- // inside the dirent. Set it from the uri field in
- // this case.
- if (it->dirent.m_resources.empty()) {
- UPnPClient::UPnPResource res;
- res.m_uri = it->url;
- it->dirent.m_resources.push_back(res);
- }
- m_metapool[it->id] = it->dirent;
- }
- i += j;
- }
-
- m_idsv = nids;
+
qDebug() << "OHPL::onIdArrayChanged: emit trackArrayChanged(). " <<
"idsv size" << m_idsv.size() << " pool size " << m_metapool.size();
emit trackArrayChanged();
emit currentTrackId(m_curid);
- out:
- return;
}
protected:
@@ -310,15 +231,6 @@
bool m_forceUpdate;
bool m_discardArrayEvents;
- std::string vtos(std::vector<int> nids) {
- std::string sids;
- for (std::vector<int>::iterator it = nids.begin();
- it != nids.end(); it++)
- sids += UPnPP::SoapHelp::i2s(*it) + " ";
- return sids;
- }
-
-
private:
virtual bool idArray(std::vector<int> *ids, int *tokp) {
return m_srv->idArray(ids, tokp) == 0;