Add code to try and make sure second votable track is different from first. Implement code to handle skip requests in player.

This commit is contained in:
Kevin Whitaker
2017-02-13 21:47:52 -05:00
parent 41fa567f82
commit 7668a923d8
2 changed files with 64 additions and 17 deletions

View File

@@ -128,10 +128,10 @@ std::list<AudioTrack> GroovePlayerMgr::getNextVoteBatch(Wt::Dbo::Session* sessio
{ {
//Pick item from genre //Pick item from genre
Wt::Dbo::ptr<AudioTrack> eligibleTrack = session->find<AudioTrack>().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(currentTrack.trackGenre); Wt::Dbo::ptr<AudioTrack> eligibleTrack = session->find<AudioTrack>().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(currentTrack.trackGenre);
//Try to make sure same track isn't up to vote again //Try to make sure same track isn't up to vote again and isn't the same as first votable track.
if((*eligibleTrack).trackFingerprint == currentTrack.trackFingerprint && trackGenreCount > 1) if(((*eligibleTrack).trackFingerprint == currentTrack.trackFingerprint || (*eligibleTrack).trackFingerprint == selectedTracks.front().trackFingerprint) && trackGenreCount > 2)
{ {
while((*eligibleTrack).trackFingerprint == currentTrack.trackFingerprint) while((*eligibleTrack).trackFingerprint == currentTrack.trackFingerprint || (*eligibleTrack).trackFingerprint == selectedTracks.front().trackFingerprint)
{ {
eligibleTrack = session->find<AudioTrack>().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(currentTrack.trackGenre); eligibleTrack = session->find<AudioTrack>().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(currentTrack.trackGenre);
} }
@@ -241,6 +241,7 @@ void GroovePlayerMgr::grooveEventLoop()
} }
else if(event.eventType == GROOVE_NOWPLAYING) else if(event.eventType == GROOVE_NOWPLAYING)
{ {
currentSkipRequester.clear();
currentTrack = getCurrentTrackDB(&sqlSession); currentTrack = getCurrentTrackDB(&sqlSession);
//Pick new batch of tracks to vote on and inform UI of update. //Pick new batch of tracks to vote on and inform UI of update.
currentVoteBatch = getNextVoteBatch(&sqlSession); currentVoteBatch = getNextVoteBatch(&sqlSession);
@@ -403,8 +404,8 @@ void GroovePlayerMgr::grooveEventLoop()
//Update vote display on all clients. //Update vote display on all clients.
Wt::WServer::instance()->postAll([event]() { Wt::WServer::instance()->postAll([event]() {
Wt::WApplication* app = Wt::WApplication::instance(); Wt::WApplication* app = Wt::WApplication::instance();
if(app != nullptr) if(app != nullptr)
{ {
static_cast<WebInterface*>(app)->playPauseActionFromServer(event.userInvolved, true); static_cast<WebInterface*>(app)->playPauseActionFromServer(event.userInvolved, true);
} }
@@ -427,8 +428,8 @@ void GroovePlayerMgr::grooveEventLoop()
//Update vote display on all clients. //Update vote display on all clients.
Wt::WServer::instance()->postAll([event]() { Wt::WServer::instance()->postAll([event]() {
Wt::WApplication* app = Wt::WApplication::instance(); Wt::WApplication* app = Wt::WApplication::instance();
if(app != nullptr) if(app != nullptr)
{ {
static_cast<WebInterface*>(app)->playPauseActionFromServer(event.userInvolved, false); static_cast<WebInterface*>(app)->playPauseActionFromServer(event.userInvolved, false);
} }
@@ -437,23 +438,55 @@ void GroovePlayerMgr::grooveEventLoop()
} }
else if(event.eventType == SKIP_REQUESTED) else if(event.eventType == SKIP_REQUESTED)
{ {
//TODO if(!voteEndedButNotNextTrackYet)
{
currentSkipRequester.push_back(event.userInvolved);
skipRequestedAt = std::chrono::steady_clock::now();
Wt::Dbo::Transaction skipTransaction(sqlSession);
UserAction* action = new UserAction();
action->action = UserAction::UAction::RequestSkip;
action->user = Wt::Dbo::ptr<User>(&event.userInvolved);
action->trackInvolved = Wt::Dbo::ptr<AudioTrack>(&event.tracksInvolved.front());
action->datetime = Wt::WDateTime::currentDateTime();
sqlSession.add(action);
skipTransaction.commit();
//Display skip request on all clients.
Wt::WServer::instance()->postAll([event]() {
Wt::WApplication* app = Wt::WApplication::instance();
if(app != nullptr)
{
static_cast<WebInterface*>(app)->skipVotedFromServer(event.userInvolved);
}
}
);
}
} }
else if(event.eventType == SKIP_VOTE_CAST_AGAINST) else if(event.eventType == SKIP_VOTE_CAST_AGAINST)
{ {
//TODO if(!voteEndedButNotNextTrackYet)
{
currentSkipRequester.clear();
//Display skip request on all clients.
Wt::WServer::instance()->postAll([event]() {
Wt::WApplication* app = Wt::WApplication::instance();
if(app != nullptr)
{
static_cast<WebInterface*>(app)->skipVoteUpdateFromServer(event.userInvolved, false);
}
}
);
}
} }
else if(event.eventType == SKIP_VOTING_ENDED) else if(event.eventType == SKIP_VOTING_ENDED)
{
//TODO
}
else if(event.eventType == ADMIN_FORCE_SKIP)
{ {
//Don't skip without first determining next track //Don't skip without first determining next track
if(!voteEndedButNotNextTrackYet) if(!voteEndedButNotNextTrackYet)
{ {
voteEndedButNotNextTrackYet = true; voteEndedButNotNextTrackYet = true;
lastInternalEvents.push_front(PlayerEvent() = {PlayerEventType::ADMIN_FORCE_SKIP}); lastInternalEvents.push_front(PlayerEvent() = {PlayerEventType::SKIP_VOTING_ENDED});
lastInternalEvents.push_front(PlayerEvent() = {PlayerEventType::VOTING_ENDED}); lastInternalEvents.push_front(PlayerEvent() = {PlayerEventType::VOTING_ENDED});
} }
else else
@@ -463,6 +496,13 @@ void GroovePlayerMgr::grooveEventLoop()
groove_playlist_seek(currentPlaylist, item->next, 0.0); groove_playlist_seek(currentPlaylist, item->next, 0.0);
} }
} }
else if(event.eventType == ADMIN_FORCE_SKIP)
{
if(!voteEndedButNotNextTrackYet)
{
lastInternalEvents.push_front(PlayerEvent() = {PlayerEventType::SKIP_VOTING_ENDED});
}
}
} }
currentPlaylist = nullptr; currentPlaylist = nullptr;
@@ -495,6 +535,11 @@ GroovePlayerMgr::PlayerEvent GroovePlayerMgr::getNextPlayerEvent(Wt::Dbo::Sessio
return PlayerEvent() = {PlayerEventType::GROOVE_NOWPLAYING}; return PlayerEvent() = {PlayerEventType::GROOVE_NOWPLAYING};
} }
} }
if(!voteEndedButNotNextTrackYet && currentSkipRequester.size() > 0 && skipRequestedAt+std::chrono::seconds(5) < std::chrono::steady_clock::now())
{
//Skip succeeded. Time to skip song.
lastInternalEvents.push_front(PlayerEvent() = {PlayerEventType::SKIP_VOTING_ENDED});
}
if(lastInternalEvents.size() > 0) if(lastInternalEvents.size() > 0)
{ {
PlayerEvent event = lastInternalEvents.front(); PlayerEvent event = lastInternalEvents.front();

View File

@@ -25,6 +25,7 @@
#include <Wt/Dbo/FixedSqlConnectionPool> #include <Wt/Dbo/FixedSqlConnectionPool>
#include <list> #include <list>
#include <thread> #include <thread>
#include <chrono>
#include "db/User.h" #include "db/User.h"
#include "db/AudioTrack.h" #include "db/AudioTrack.h"
#include <groove/groove.h> #include <groove/groove.h>
@@ -51,6 +52,8 @@ public:
std::list<AudioTrack> currentVoteBatch; std::list<AudioTrack> currentVoteBatch;
std::list<std::pair<AudioTrack, int>> currentVoteStatus; std::list<std::pair<AudioTrack, int>> currentVoteStatus;
bool voteEndedButNotNextTrackYet = false; bool voteEndedButNotNextTrackYet = false;
std::list<User> currentSkipRequester;
std::chrono::steady_clock::time_point skipRequestedAt;
enum ScanResults {ACCEPTED = true, MISSING_ARTIST_TAG = false, MISSING_ALBUM_TAG = false, MISSING_TITLE_TAG = false, MISSING_GENRE_TAG = false, DUPLICATE_TRACK = false, MISSING_COVERART_TAG = false, MISSING_MULTIPLE_TAGS = false}; enum ScanResults {ACCEPTED = true, MISSING_ARTIST_TAG = false, MISSING_ALBUM_TAG = false, MISSING_TITLE_TAG = false, MISSING_GENRE_TAG = false, DUPLICATE_TRACK = false, MISSING_COVERART_TAG = false, MISSING_MULTIPLE_TAGS = false};
ScanResults addFileToTrackDBIfTagged(Wt::Dbo::Session* session, std::filesystem::path file); ScanResults addFileToTrackDBIfTagged(Wt::Dbo::Session* session, std::filesystem::path file);
@@ -61,6 +64,8 @@ public:
User userInvolved; User userInvolved;
std::list<AudioTrack> tracksInvolved; std::list<AudioTrack> tracksInvolved;
}; };
std::list<AudioTrack> requestQueue;
std::list<PlayerEvent> lastInternalEvents;
private: private:
GroovePlayerMgr (std::string dbFile); GroovePlayerMgr (std::string dbFile);
~GroovePlayerMgr(); ~GroovePlayerMgr();
@@ -68,9 +73,6 @@ private:
Wt::Dbo::FixedSqlConnectionPool* connectionPool; Wt::Dbo::FixedSqlConnectionPool* connectionPool;
bool continueEventLoop = true; bool continueEventLoop = true;
std::list<AudioTrack> requestQueue;
std::list<PlayerEvent> lastInternalEvents;
std::thread* grooveEvents; std::thread* grooveEvents;
void grooveEventLoop(); void grooveEventLoop();
std::list<AudioTrack> getNextVoteBatch(Wt::Dbo::Session* session); std::list<AudioTrack> getNextVoteBatch(Wt::Dbo::Session* session);