Redo events so that the event can have needed info alongside it. Make sure when computer is picking tracks if no votes that it doesn't pick a song that just played if possible. Fix mislabeled method. Implement untest admin skip and vote code.

This commit is contained in:
Kevin Whitaker
2017-02-08 23:05:13 -05:00
parent 39a780cb95
commit 35279008ee
4 changed files with 76 additions and 32 deletions

View File

@@ -26,6 +26,7 @@
#include <locale> #include <locale>
#include <Wt/WLogger> #include <Wt/WLogger>
#include <Wt/Dbo/Transaction> #include <Wt/Dbo/Transaction>
#include <Wt/WDateTime>
#include <groovefingerprinter/fingerprinter.h> #include <groovefingerprinter/fingerprinter.h>
#include <grooveplayer/player.h> #include <grooveplayer/player.h>
#include <taglib/fileref.h> #include <taglib/fileref.h>
@@ -233,12 +234,12 @@ void GroovePlayerMgr::grooveEventLoop()
while(getInstance()->continueEventLoop) while(getInstance()->continueEventLoop)
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(200));
PlayerEvents event = getNextPlayerEvent(&sqlSession); PlayerEvent event = getNextPlayerEvent(&sqlSession);
if(event == NOTHING) if(event.eventType == NOTHING)
{ {
continue; continue;
} }
else if(event == GROOVE_NOWPLAYING) else if(event.eventType == GROOVE_NOWPLAYING)
{ {
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.
@@ -259,7 +260,7 @@ void GroovePlayerMgr::grooveEventLoop()
); );
Wt::log("info") << "Track playing changed to: " << currentTrack.trackName; Wt::log("info") << "Track playing changed to: " << currentTrack.trackName;
} }
else if(event == VOTING_ENDED) else if(event.eventType == VOTING_ENDED)
{ {
//Look at votes and add correct track to end of playlist. //Look at votes and add correct track to end of playlist.
//If more than one track has highest votes, pick random. TODO:maybe base off of other play data instead. //If more than one track has highest votes, pick random. TODO:maybe base off of other play data instead.
@@ -324,12 +325,12 @@ void GroovePlayerMgr::grooveEventLoop()
{ {
//Pick based on percentages. //Pick based on percentages.
int pick = rand() % 10 +1; int pick = rand() % 10 +1;
if(pick <= 5) if(pick <= 5 && currentVoteBatch.front().trackFingerprint != currentTrack.trackFingerprint)
{ {
//First track wins //First track wins
winner = currentVoteBatch.front(); winner = currentVoteBatch.front();
} }
else if(pick <= 8) else if(pick <= 8 && (*std::next(currentVoteBatch.begin(),1)).trackFingerprint != currentTrack.trackFingerprint)
{ {
//Second track wins. //Second track wins.
winner = (*std::next(currentVoteBatch.begin(),1)); winner = (*std::next(currentVoteBatch.begin(),1));
@@ -352,38 +353,76 @@ void GroovePlayerMgr::grooveEventLoop()
); );
Wt::log("info")<< "Voting has ended. Next track is: " << winner.trackName; Wt::log("info")<< "Voting has ended. Next track is: " << winner.trackName;
} }
else if(event == VOTE_CAST) else if(event.eventType == VOTE_CAST)
{ {
if(!voteEndedButNotNextTrackYet) if(!voteEndedButNotNextTrackYet)
{ {
// //Add vote to DB
Wt::Dbo::Transaction voteTransaction(sqlSession);
UserAction* action = new UserAction();
action->action = UserAction::UAction::VoteTrack;
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);
voteTransaction.commit();
//Add vote to vote status
for(std::pair<AudioTrack, int> voteItem: currentVoteStatus)
{
if(voteItem.first.trackFingerprint == event.tracksInvolved.front().trackFingerprint)
{
++(voteItem.second);
}
}
//Update vote display on all clients.
Wt::WServer::instance()->postAll([event]() {
Wt::WApplication* app = Wt::WApplication::instance();
if(app != nullptr)
{
static_cast<WebInterface*>(app)->voteNextSongFromServer(event.userInvolved, event.tracksInvolved.front());
}
}
);
} }
} }
else if(event == PLAYING_PAUSED) else if(event.eventType == PLAYING_PAUSED)
{ {
// //TODO
} }
else if(event == PLAYING_RESUMED) else if(event.eventType == PLAYING_RESUMED)
{ {
// //TODO
} }
else if(event == SKIP_REQUESTED) else if(event.eventType == SKIP_REQUESTED)
{ {
// //TODO
} }
else if(event == SKIP_VOTE_CAST) else if(event.eventType == SKIP_VOTE_CAST_AGAINST)
{ {
// //TODO
} }
else if(event == SKIP_VOTING_ENDED) else if(event.eventType == SKIP_VOTING_ENDED)
{ {
// //TODO
} }
else if(event == ADMIN_FORCE_SKIP) 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::VOTING_ENDED});
}
else
{
GroovePlaylistItem* item;
groove_player_position(currentPlayer,&item,nullptr);
groove_playlist_seek(currentPlaylist, item->next, 0.0);
}
} }
//TODO
} }
currentPlaylist = nullptr; currentPlaylist = nullptr;
@@ -398,14 +437,14 @@ void GroovePlayerMgr::shutdown()
continueEventLoop = false; continueEventLoop = false;
} }
GroovePlayerMgr::PlayerEvents GroovePlayerMgr::getNextPlayerEvent(Wt::Dbo::Session* session) GroovePlayerMgr::PlayerEvent GroovePlayerMgr::getNextPlayerEvent(Wt::Dbo::Session* session)
{ {
double timeIntoTrack; double timeIntoTrack;
groove_player_position(currentPlayer,nullptr,&timeIntoTrack); groove_player_position(currentPlayer,nullptr,&timeIntoTrack);
if(!voteEndedButNotNextTrackYet && currentTrack.trackName != std::string() && currentTrack.trackLengthSeconds-timeIntoTrack < 3) if(!voteEndedButNotNextTrackYet && currentTrack.trackName != std::string() && currentTrack.trackLengthSeconds-timeIntoTrack < 3)
{ {
voteEndedButNotNextTrackYet = true; voteEndedButNotNextTrackYet = true;
return VOTING_ENDED; return PlayerEvent() = {PlayerEventType::VOTING_ENDED};
} }
GroovePlayerEvent event; GroovePlayerEvent event;
if(groove_player_event_get(this->currentPlayer,&event, 0) > 0) if(groove_player_event_get(this->currentPlayer,&event, 0) > 0)
@@ -413,16 +452,16 @@ GroovePlayerMgr::PlayerEvents GroovePlayerMgr::getNextPlayerEvent(Wt::Dbo::Sessi
if(event.type == GROOVE_EVENT_NOWPLAYING) if(event.type == GROOVE_EVENT_NOWPLAYING)
{ {
voteEndedButNotNextTrackYet = false; voteEndedButNotNextTrackYet = false;
return GROOVE_NOWPLAYING; return PlayerEvent() = {PlayerEventType::GROOVE_NOWPLAYING};
} }
} }
if(lastInternalEvents.size() > 0) if(lastInternalEvents.size() > 0)
{ {
PlayerEvents event = lastInternalEvents.front(); PlayerEvent event = lastInternalEvents.front();
lastInternalEvents.pop_front(); lastInternalEvents.pop_front();
return event; return event;
} }
return NOTHING; return PlayerEvent() = {PlayerEventType::NOTHING};
} }
AudioTrack GroovePlayerMgr::getCurrentTrackDB(Wt::Dbo::Session* session) AudioTrack GroovePlayerMgr::getCurrentTrackDB(Wt::Dbo::Session* session)

View File

@@ -54,9 +54,14 @@ public:
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);
private:
enum PlayerEvents {NOTHING, GROOVE_NOWPLAYING, VOTING_ENDED, VOTE_CAST, PLAYING_PAUSED, PLAYING_RESUMED, SKIP_REQUESTED, SKIP_VOTE_CAST, SKIP_VOTING_ENDED, ADMIN_FORCE_SKIP};
enum PlayerEventType {NOTHING, GROOVE_NOWPLAYING, VOTING_ENDED, VOTE_CAST, PLAYING_PAUSED, PLAYING_RESUMED, SKIP_REQUESTED, SKIP_VOTE_CAST_AGAINST, SKIP_VOTING_ENDED, ADMIN_FORCE_SKIP};
struct PlayerEvent {
PlayerEventType eventType;
User userInvolved;
std::list<AudioTrack> tracksInvolved;
};
private:
GroovePlayerMgr (std::string dbFile); GroovePlayerMgr (std::string dbFile);
~GroovePlayerMgr(); ~GroovePlayerMgr();
Wt::Dbo::backend::Sqlite3* sqliteConnection; Wt::Dbo::backend::Sqlite3* sqliteConnection;
@@ -64,14 +69,14 @@ private:
bool continueEventLoop = true; bool continueEventLoop = true;
std::list<AudioTrack> requestQueue; std::list<AudioTrack> requestQueue;
std::list<PlayerEvents> lastInternalEvents; 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);
std::thread* grooveAudioScanner; std::thread* grooveAudioScanner;
void grooveAudioScannerLoop(); void grooveAudioScannerLoop();
PlayerEvents getNextPlayerEvent(Wt::Dbo::Session* session); PlayerEvent getNextPlayerEvent(Wt::Dbo::Session* session);
void removeOrphanedTracks(Wt::Dbo::Session* session); void removeOrphanedTracks(Wt::Dbo::Session* session);
AudioTrack getCurrentTrackDB(Wt::Dbo::Session* session); AudioTrack getCurrentTrackDB(Wt::Dbo::Session* session);

View File

@@ -75,7 +75,7 @@ void WebInterface::skipVotedFromServer(User userRequestingToSkipCurrentTrack)
triggerUpdate(); triggerUpdate();
} }
void WebInterface::voteUpdateFromServer(User userVoting, bool forSkip) void WebInterface::skipVoteUpdateFromServer(User userVoting, bool forSkip)
{ {
priv_int->playerUI->tempText->setText(priv_int->playerUI->tempText->text()+"vote"); priv_int->playerUI->tempText->setText(priv_int->playerUI->tempText->text()+"vote");
triggerUpdate(); triggerUpdate();

View File

@@ -35,7 +35,7 @@ public:
void songChangedFromServer(AudioTrack nextTrack); void songChangedFromServer(AudioTrack nextTrack);
void voteTracksUpdatedFromServer(std::list<AudioTrack> voteableTracks); void voteTracksUpdatedFromServer(std::list<AudioTrack> voteableTracks);
void skipVotedFromServer(User userRequestingToSkipCurrentTrack); void skipVotedFromServer(User userRequestingToSkipCurrentTrack);
void voteUpdateFromServer(User userVoting, bool forSkip); void skipVoteUpdateFromServer(User userVoting, bool forSkip);
void voteNextSongFromServer(User userVoting, AudioTrack trackVoted); void voteNextSongFromServer(User userVoting, AudioTrack trackVoted);
void voteNextPollClosedFromServer(); void voteNextPollClosedFromServer();
private: private: