Switch to unified view

a/dirbrowser/randplayer.cpp b/dirbrowser/randplayer.cpp
...
...
41
RandPlayer::~RandPlayer()
41
RandPlayer::~RandPlayer()
42
{
42
{
43
    emit sig_next_group_html("");
43
    emit sig_next_group_html("");
44
}
44
}
45
45
46
static bool sameValues(const string& alb, const string& ctp,
46
static bool sameValues(UPnPClient::UPnPDirObject& ref,
47
                       UPnPClient::UPnPDirObject& e)
47
                       UPnPClient::UPnPDirObject& e)
48
{
48
{
49
    return !e.f2s("upnp:album", false).compare(alb) &&
49
    return !e.f2s("upnp:album", false).compare(ref.f2s("upnp:album", false)) &&
50
        !e.f2s("upplay:ctpath", false).compare(ctp);
50
        !e.f2s("upplay:ctpath", false).compare(ref.f2s("upplay:ctpath", false));
51
}
52
53
// When playing by groups, if we just select random tracks and play
54
// the group they're in, big groups get selected more probably. So we
55
// random select in the group starts instead; And yes it's inefficient
56
// to recompute the group starts each time, we could do it once and
57
// then prune the list in parallel with the main list. But... you
58
// know... so many MIPS! We're only doing this every few minutes, and
59
// doing otherwise is not that simple (all posterior start indices
60
// need to be recomputed after we erase a group etc.)
61
static vector<unsigned int>
62
findGStarts(vector<UPnPClient::UPnPDirObject>& ents)
63
{
64
    vector<unsigned int> out;
65
    UPnPClient::UPnPDirObject ref;
66
    for (unsigned int i = 0; i < ents.size(); i++) {
67
        if (!sameValues(ref, ents[i])) {
68
            out.push_back(i);
69
            ref = ents[i];
70
        }
71
    }
72
    return out;
51
}
73
}
52
74
53
void RandPlayer::selectNextGroup()
75
void RandPlayer::selectNextGroup()
54
{
76
{
55
    m_nextgroup.clear();
77
    m_nextgroup.clear();
56
    if (m_entries.empty())
78
    if (m_entries.empty())
57
        return;
79
        return;
58
    
80
59
    // Pick a random start, seek back to beginning of group, then
81
    vector<unsigned int> vgstarts = findGStarts(m_entries);
60
    // forward to end
82
83
    // Pick a random start
61
    double fstart = (double(qrand()) / double(RAND_MAX)) *
84
    double fstart = (double(qrand()) / double(RAND_MAX)) *
62
        (m_entries.size() - 1);
85
        (vgstarts.size() - 1);
63
    int istart = round(fstart);
86
    int istart = vgstarts[round(fstart)];
64
87
65
    // Reference values
88
    // Reference values
66
    string alb = m_entries[istart].f2s("upnp:album", false);
89
    auto entref = m_entries[istart];
67
    string ctpath = m_entries[istart].f2s("upplay:ctpath", false);
68
    qDebug() << "RandPlayer: albs. istart" << istart << " album " <<
69
        alb.c_str();
70
90
71
    // Look back to beginning of section
91
    // Look back to beginning of section. Not needed any more now that
92
    // we pick up group starts. Just in case we change our minds
72
    while (istart > 0) {
93
    while (istart > 0) {
73
        istart--;
94
        istart--;
74
        if (!sameValues(alb, ctpath, m_entries[istart])) {
95
        if (!sameValues(entref, m_entries[istart])) {
75
            istart++;
96
            istart++;
76
            break;
97
            break;
77
        }
98
        }
78
    }
99
    }
79
    qDebug() << "RandPlayer: albs. final istart" << istart;
80
100
81
    // Look forward to end, and store entries
101
    // Look forward to end, and store entries. Could use the next
102
    // group index instead. Just kept the initial code where we
103
    // selected a random track
82
    vector<UPnPClient::UPnPDirObject>::iterator last =
104
    vector<UPnPClient::UPnPDirObject>::iterator last =
83
        m_entries.begin() + istart;
105
        m_entries.begin() + istart;
84
    while (last != m_entries.end()) {
106
    while (last != m_entries.end()) {
85
        if (!sameValues(alb, ctpath, *last)) {
107
        if (!sameValues(entref, *last)) {
86
            break;
108
            break;
87
        }
109
        }
88
        m_nextgroup.push_back(*last++);
110
        m_nextgroup.push_back(*last++);
89
    }
111
    }
90
    // Erase used entries.
112
    // Erase used entries.