From 685d1828add27b971aeaf5758ac92d6bdf24f279 Mon Sep 17 00:00:00 2001 From: Kevin Whitaker Date: Wed, 1 Feb 2017 22:13:40 -0500 Subject: [PATCH] add limits to places where offsets to avoid some syntax problems. Rename grooveplayer class to avoid conflict with official libgroove class. Add admin event. Write start of event loop that picks initial song. --- src/GroovePlayer.cpp | 57 ++++++++++++++++++++++++++++++++------------ src/GroovePlayer.h | 14 +++++------ src/main.cpp | 2 +- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/GroovePlayer.cpp b/src/GroovePlayer.cpp index 7fcba4c..a53c4f5 100644 --- a/src/GroovePlayer.cpp +++ b/src/GroovePlayer.cpp @@ -27,10 +27,11 @@ #include #include #include +#include -std::filesystem::path GroovePlayer::musicScanDir = ""; +std::filesystem::path GroovePlayerMgr::musicScanDir = ""; -GroovePlayer::GroovePlayer(std::string dbFile) : sqliteConnection(dbFile) +GroovePlayerMgr::GroovePlayerMgr (std::string dbFile) : sqliteConnection(dbFile) { sqlSession.setConnection(this->sqliteConnection); sqlSession.mapClass("user"); @@ -50,7 +51,7 @@ GroovePlayer::GroovePlayer(std::string dbFile) : sqliteConnection(dbFile) grooveEvents = new std::thread(grooveEventLoop); } -std::list GroovePlayer::getNextVoteBatch() +std::list GroovePlayerMgr::getNextVoteBatch() { /** * This method will attempt to pick 3 tracks that will be up for selection next. @@ -82,13 +83,13 @@ std::list GroovePlayer::getNextVoteBatch() if(trackAlbumCount > 0 && computerSlightOfHand > 3) { //Pick item from album - Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().where("album = ?").offset(rand() % trackAlbumCount).bind(getCurrentTrack()->trackAlbumName); + Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().where("album = ?").limit(1).offset(rand() % trackAlbumCount).bind(getCurrentTrack()->trackAlbumName); selectedTracks.push_back(eligibleTrack.get()); } else if(trackArtistCount > 0) { //Pick item from artist - Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().where("artist = ?").offset(rand() % trackArtistCount).bind(getCurrentTrack()->trackArtistName); + Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().where("artist = ?").limit(1).offset(rand() % trackArtistCount).bind(getCurrentTrack()->trackArtistName); selectedTracks.push_back(eligibleTrack.get()); } @@ -97,7 +98,7 @@ std::list GroovePlayer::getNextVoteBatch() if(trackGenreCount > 0) { //Pick item from genre - Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().where("genre = ?").offset(rand() % trackGenreCount).bind(getCurrentTrack()->trackGenre); + Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(getCurrentTrack()->trackGenre); selectedTracks.push_back(eligibleTrack.get()); } @@ -111,35 +112,61 @@ std::list GroovePlayer::getNextVoteBatch() else if(trackNotGenreCount > 0) { //Pick from other genre - Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().where("genre != ?").offset(rand() % trackNotGenreCount).bind(getCurrentTrack()->trackGenre); + Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().where("genre != ?").limit(1).offset(rand() % trackNotGenreCount).bind(getCurrentTrack()->trackGenre); selectedTracks.push_back(eligibleTrack.get()); } else { //Pick randomly - Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().offset(rand() % trackCount); + Wt::Dbo::ptr eligibleTrack = getInstance()->sqlSession.find().limit(1).offset(rand() % trackCount); selectedTracks.push_back(eligibleTrack.get()); } return selectedTracks; } -void GroovePlayer::grooveEventLoop() +void GroovePlayerMgr::grooveEventLoop() { /** - * On first boot, random track that has been played before will start(or random if no track has been played before). + * On first boot, random track that has been voted before will start(or random if no track has been played before). * When voting ends, if no vote was cast, the first will be picked 60% of the time with second being 30% of the time and third being picked 10% of the time. * Exception is if third track is a request, then it is picked. If another song is voted over this, it will be put in back of request queue. */ + + Wt::Dbo::Transaction transaction(getInstance()->sqlSession); + + //Wait until at least one track is in DB. + if(getInstance()->sqlSession.query("select count(fingerprint) from tracks") < 1) + { + while(getInstance()->sqlSession.query("select count(fingerprint) from tracks") < 1){} + } + + //Pick initial track and boostrap player. + int tracksPlayedBefore = getInstance()->sqlSession.query("select count(fingerprint) from tracks as t join actions on (actions.action = 3 or actions.action = 2) and actions.track_id = t.id"); + const AudioTrack* selectedTrack; + if (tracksPlayedBefore > 0) + { + selectedTrack = getInstance()->sqlSession.query>("select t from tracks as t join actions on (actions.action = 3 or actions.action = 2) and actions.track_id = t.id").limit(1).offset(rand() % tracksPlayedBefore).resultValue().get(); + } + else + { + int trackCount = getInstance()->sqlSession.query("select count(fingerprint) from tracks"); + selectedTrack = getInstance()->sqlSession.find().limit(1).offset(rand() % trackCount).resultValue().get(); + } + struct GroovePlaylist* playlist = groove_playlist_create(); + struct GroovePlayer* player = groove_player_create(); + if(!player) {return;} + + //TODO } -GroovePlayer::PlayerEvents GroovePlayer::getNextPlayerEvent() +GroovePlayerMgr::PlayerEvents GroovePlayerMgr::getNextPlayerEvent() { //TODO } -Wt::Dbo::ptr GroovePlayer::getCurrentTrack() +Wt::Dbo::ptr GroovePlayerMgr::getCurrentTrack() { Wt::Dbo::Transaction transaction(getInstance()->sqlSession); Wt::Dbo::ptr track = getInstance()->sqlSession.find().where("path = ?").bind(currentItem->file->filename); @@ -147,7 +174,7 @@ Wt::Dbo::ptr GroovePlayer::getCurrentTrack() } -bool GroovePlayer::addFileToTrackDBIfTagged(std::filesystem::path file) +bool GroovePlayerMgr::addFileToTrackDBIfTagged(std::filesystem::path file) { //Now check if tags exist and put into DB. struct GrooveFile* gfile = groove_file_open(file.c_str()); @@ -202,7 +229,7 @@ bool GroovePlayer::addFileToTrackDBIfTagged(std::filesystem::path file) return true; } -void GroovePlayer::removeOrphanedTracks() +void GroovePlayerMgr::removeOrphanedTracks() { Wt::Dbo::Transaction transaction(getInstance()->sqlSession); Wt::Dbo::collection> tracks = getInstance()->sqlSession.find(); @@ -219,7 +246,7 @@ void GroovePlayer::removeOrphanedTracks() -void GroovePlayer::grooveAudioScannerLoop() +void GroovePlayerMgr::grooveAudioScannerLoop() { if(!std::filesystem::exists(musicScanDir)) { diff --git a/src/GroovePlayer.h b/src/GroovePlayer.h index 71939d3..57845e5 100644 --- a/src/GroovePlayer.h +++ b/src/GroovePlayer.h @@ -32,21 +32,21 @@ namespace std { namespace filesystem = experimental::filesystem; } -class GroovePlayer +class GroovePlayerMgr { public: static std::filesystem::path musicScanDir; - static GroovePlayer* getInstance() { - static GroovePlayer instance("music.db"); + static GroovePlayerMgr* getInstance() { + static GroovePlayerMgr instance("music.db"); musicScanDir = std::filesystem::path("music"); return &instance; }; - GroovePlayer(GroovePlayer const&) = delete; - void operator=(GroovePlayer const&) = delete; + GroovePlayerMgr ( GroovePlayerMgr const&) = delete; + void operator=( GroovePlayerMgr const&) = delete; private: - enum PlayerEvents {NOTHING, GROOVE_NOWPLAYING, VOTING_ENDED, VOTE_CAST, PLAYING_PAUSED, PLAYING_RESUMED, SKIP_REQUESTED, SKIP_VOTE_CAST, SKIP_VOTING_ENDED}; + enum PlayerEvents {NOTHING, GROOVE_NOWPLAYING, VOTING_ENDED, VOTE_CAST, PLAYING_PAUSED, PLAYING_RESUMED, SKIP_REQUESTED, SKIP_VOTE_CAST, SKIP_VOTING_ENDED, ADMIN_FORCE_SKIP}; - GroovePlayer(std::string dbFile); + GroovePlayerMgr (std::string dbFile); Wt::Dbo::backend::Sqlite3 sqliteConnection; Wt::Dbo::Session sqlSession; diff --git a/src/main.cpp b/src/main.cpp index 62d3171..6ddfe8c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,7 +17,7 @@ int main ( int argc, char** argv ) server.addEntryPoint(Wt::Application, createApplication); if(server.start()) { - GroovePlayer::getInstance(); + GroovePlayerMgr::getInstance(); int sig = Wt::WServer::waitForShutdown(argv[0]); server.stop(); }