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:
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user