From 7668a923d88c6421172bbb281fc4b6001e8ef065 Mon Sep 17 00:00:00 2001 From: Kevin Whitaker Date: Mon, 13 Feb 2017 21:47:52 -0500 Subject: [PATCH] Add code to try and make sure second votable track is different from first. Implement code to handle skip requests in player. --- src/GroovePlayer.cpp | 73 +++++++++++++++++++++++++++++++++++--------- src/GroovePlayer.h | 8 +++-- 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/GroovePlayer.cpp b/src/GroovePlayer.cpp index 02c6a67..c14fb5d 100644 --- a/src/GroovePlayer.cpp +++ b/src/GroovePlayer.cpp @@ -128,10 +128,10 @@ std::list GroovePlayerMgr::getNextVoteBatch(Wt::Dbo::Session* sessio { //Pick item from genre Wt::Dbo::ptr eligibleTrack = session->find().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(currentTrack.trackGenre); - //Try to make sure same track isn't up to vote again - if((*eligibleTrack).trackFingerprint == currentTrack.trackFingerprint && trackGenreCount > 1) + //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 || (*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().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(currentTrack.trackGenre); } @@ -241,6 +241,7 @@ void GroovePlayerMgr::grooveEventLoop() } else if(event.eventType == GROOVE_NOWPLAYING) { + currentSkipRequester.clear(); currentTrack = getCurrentTrackDB(&sqlSession); //Pick new batch of tracks to vote on and inform UI of update. currentVoteBatch = getNextVoteBatch(&sqlSession); @@ -403,8 +404,8 @@ void GroovePlayerMgr::grooveEventLoop() //Update vote display on all clients. Wt::WServer::instance()->postAll([event]() { - Wt::WApplication* app = Wt::WApplication::instance(); - if(app != nullptr) + Wt::WApplication* app = Wt::WApplication::instance(); + if(app != nullptr) { static_cast(app)->playPauseActionFromServer(event.userInvolved, true); } @@ -427,8 +428,8 @@ void GroovePlayerMgr::grooveEventLoop() //Update vote display on all clients. Wt::WServer::instance()->postAll([event]() { - Wt::WApplication* app = Wt::WApplication::instance(); - if(app != nullptr) + Wt::WApplication* app = Wt::WApplication::instance(); + if(app != nullptr) { static_cast(app)->playPauseActionFromServer(event.userInvolved, false); } @@ -437,23 +438,55 @@ void GroovePlayerMgr::grooveEventLoop() } 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(&event.userInvolved); + action->trackInvolved = Wt::Dbo::ptr(&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(app)->skipVotedFromServer(event.userInvolved); + } + } + ); + } } 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(app)->skipVoteUpdateFromServer(event.userInvolved, false); + } + } + ); + } } else if(event.eventType == SKIP_VOTING_ENDED) - { - //TODO - } - else if(event.eventType == ADMIN_FORCE_SKIP) { //Don't skip without first determining next track if(!voteEndedButNotNextTrackYet) { 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}); } else @@ -463,6 +496,13 @@ void GroovePlayerMgr::grooveEventLoop() 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; @@ -495,6 +535,11 @@ GroovePlayerMgr::PlayerEvent GroovePlayerMgr::getNextPlayerEvent(Wt::Dbo::Sessio 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) { PlayerEvent event = lastInternalEvents.front(); diff --git a/src/GroovePlayer.h b/src/GroovePlayer.h index 2b6aaec..c683e86 100644 --- a/src/GroovePlayer.h +++ b/src/GroovePlayer.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "db/User.h" #include "db/AudioTrack.h" #include @@ -51,6 +52,8 @@ public: std::list currentVoteBatch; std::list> currentVoteStatus; bool voteEndedButNotNextTrackYet = false; + std::list 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}; ScanResults addFileToTrackDBIfTagged(Wt::Dbo::Session* session, std::filesystem::path file); @@ -61,6 +64,8 @@ public: User userInvolved; std::list tracksInvolved; }; + std::list requestQueue; + std::list lastInternalEvents; private: GroovePlayerMgr (std::string dbFile); ~GroovePlayerMgr(); @@ -68,9 +73,6 @@ private: Wt::Dbo::FixedSqlConnectionPool* connectionPool; bool continueEventLoop = true; - std::list requestQueue; - std::list lastInternalEvents; - std::thread* grooveEvents; void grooveEventLoop(); std::list getNextVoteBatch(Wt::Dbo::Session* session); -- GitLab