implemented race details

This commit is contained in:
Dorian Zedler 2020-10-03 11:10:15 +02:00
parent 3c626b82da
commit c9e1f4f8ec
Signed by: dorian
GPG key ID: D3B255CB8BC7CD37
6 changed files with 67 additions and 46 deletions

View file

@ -23,6 +23,7 @@
#include "scstwrace.h"
#include "scstwclient.h"
#include "scstwremotetimer.h"
#include "scstwsoundplayer.h"
class ScStwRemoteRace : public ScStwRace
{
@ -34,6 +35,7 @@ protected:
double currentStartTotalDelay;
double currentStartDelayStartedAt;
bool currentlyWaitingForClimbers;
bool isReadyForNextState;
private:
ScStwClient *scStwClient;
@ -47,11 +49,13 @@ public slots:
ScStw::StatusCode reset();
bool addTimer(ScStwTimer *timer);
QVariantList getCurrentStartDelay();
bool getIsReadyForNextState();
private slots:
void handleClientStateChanged();
void handleBaseStationSignal(ScStw::SignalKey key, QVariant data);
bool refreshRemoteTimers(QVariantList remoteTimers);
void refreshDetails(QVariantMap details);
};

View file

@ -26,6 +26,8 @@
#include "scstwtimer.h"
#include "scstwsoundplayer.h"
class ScStwRemoteRace;
/*!
* \brief The ScStwRace class can be used to measure timings of climbing races with multiple lanes at once.
*
@ -52,12 +54,14 @@ class ScStwRace : public QObject
Q_PROPERTY(RaceState state READ getState NOTIFY stateChanged)
Q_PROPERTY(QVariantList timers READ getTimerDetailList NOTIFY timersChanged)
Q_PROPERTY(QVariantList currentStartDelay READ getCurrentStartDelay NOTIFY currentStartDelayChanged)
Q_PROPERTY(bool isReadyForNextState READ isReadyForNextState NOTIFY isReadyForNextStateChanged)
Q_PROPERTY(bool isReadyForNextState READ getIsReadyForNextState NOTIFY isReadyForNextStateChanged)
Q_PROPERTY(QVariantMap details READ getDetails NOTIFY detailsChanged)
public:
explicit ScStwRace(QObject *parent = nullptr);
friend class ScStwRemoteRace;
enum RaceState { IDLE, PREPAIRING, WAITING, STARTING, RUNNING, STOPPED, INCIDENT };
Q_ENUM(RaceState)
@ -154,7 +158,7 @@ private slots:
void handleTimerStop();
bool isStarting();
bool isReadyForNextState();
virtual bool getIsReadyForNextState();
void handleTimerReadyStateChange(ScStwTimer::ReadyState readyState);
signals:
@ -164,11 +168,8 @@ signals:
void stateChanged(RaceState state);
void currentStartDelayChanged();
void timersChanged();
<<<<<<< HEAD
void isReadyForNextStateChanged();
=======
void detailsChanged();
>>>>>>> origin/master
};

View file

@ -110,7 +110,7 @@ public slots:
* \param volume the volume to play the false start sound at
* \return true if the playback was successfully stopped, false otherwise
*/
bool cancel(double volume = 0);
bool cancel();
private slots:

View file

@ -21,12 +21,11 @@
ScStwRemoteRace::ScStwRemoteRace(ScStwClient *monitorClient, QObject *parent) : ScStwRace(parent)
{
this->currentlyWaitingForClimbers = false;
this->isReadyForNextState = true;
this->scStwClient = monitorClient;
this->scStwClient->addSignalSubscription(ScStw::RaceStateChanged);
this->scStwClient->addSignalSubscription(ScStw::TimersChanged);
this->scStwClient->addSignalSubscription(ScStw::CurrentStartDelayChanged);
this->scStwClient->addSignalSubscription(ScStw::RaceDetailsChanged);
connect(this->scStwClient, &ScStwClient::stateChanged, this, &ScStwRemoteRace::handleClientStateChanged);
connect(this->scStwClient, &ScStwClient::gotSignal, this, &ScStwRemoteRace::handleBaseStationSignal);
@ -112,39 +111,48 @@ void ScStwRemoteRace::handleClientStateChanged() {
void ScStwRemoteRace::handleBaseStationSignal(ScStw::SignalKey key, QVariant data) {
//qDebug() << "got signal: " << data;
switch (key) {
case ScStw::RaceStateChanged:
case ScStw::RaceDetailsChanged:
{
// the remote race state has changed
this->setState( ScStwRace::RaceState( data.toInt() ) );
this->refreshDetails(data.toMap());
break;
}
case ScStw::TimersChanged:
{
// the remote timers have changed
this->refreshRemoteTimers(data.toList());
break;
}
case ScStw::CurrentStartDelayChanged:
{
// the next start action has changed
this->currentStartTotalDelay = data.toList()[ScStwRace::CurrentStartStateTotalDelay].toInt();
this->currentStartDelayStartedAt = QDateTime::currentMSecsSinceEpoch() - (this->currentStartTotalDelay * data.toList()[ScStwRace::CurrentStartStateDelayProgress].toDouble());
this->currentlyWaitingForClimbers = data.toList()[ScStwRace::CurrentStartStateDelayProgress].toDouble() == 0 && this->currentStartTotalDelay == -1;
emit this->currentStartDelayChanged();
qDebug() << "Current start delay changed: total:" << this->currentStartTotalDelay << " progress: " << data.toList()[ScStwRace::CurrentStartStateDelayProgress].toDouble();
break;
}
case ScStw::InvalidSignal:
return;
default:
return;
}
}
void ScStwRemoteRace::refreshDetails(QVariantMap details) {
// the details of the race have changed:
// state
this->setState(ScStwRace::RaceState(details["state"].toInt()));
// competition mode
this->competitionMode = details["competitionMode"].toBool();
// ready sound enabled
this->writeStartSoundSetting(ScStwSoundPlayer::Ready, details["readySoundEnabled"].toBool(), 0);
// current start delay
this->currentStartTotalDelay = details["currentStartDelay"].toList()[ScStwRace::CurrentStartStateTotalDelay].toInt();
this->currentStartDelayStartedAt = QDateTime::currentMSecsSinceEpoch() - (this->currentStartTotalDelay * details["currentStartDelay"].toList()[ScStwRace::CurrentStartStateDelayProgress].toDouble());
this->currentlyWaitingForClimbers = details["currentStartDelay"].toList()[ScStwRace::CurrentStartStateDelayProgress].toDouble() == 0 && this->currentStartTotalDelay == -1;
emit this->currentStartDelayChanged();
// timers
this->refreshRemoteTimers(details["timers"].toList());
// isReady
if(this->state == WAITING) {
this->isReadyForNextState = details["isReadyForNextState"].toBool();
emit this->isReadyForNextStateChanged();
}
emit this->detailsChanged();
}
bool ScStwRemoteRace::refreshRemoteTimers(QVariantList remoteTimers) {
if(remoteTimers.length() != this->timers.length()){
@ -218,3 +226,7 @@ QVariantList ScStwRemoteRace::getCurrentStartDelay() {
nextActionDelayProg
};
}
bool ScStwRemoteRace::getIsReadyForNextState() {
return this->isReadyForNextState;
}

View file

@ -34,6 +34,7 @@ ScStwRace::ScStwRace(QObject *parent) : QObject(parent)
connect(this, &ScStwRace::currentStartDelayChanged, this, &ScStwRace::detailsChanged);
connect(this, &ScStwRace::timersChanged, this, &ScStwRace::detailsChanged);
connect(this, &ScStwRace::stateChanged, this, &ScStwRace::detailsChanged);
// write default settings
this->startSoundSettings.insert(ScStwSoundPlayer::Start, {{"Enabled", true}, {"Delay", 1}});
@ -49,7 +50,7 @@ ScStwRace::ScStwRace(QObject *parent) : QObject(parent)
ScStw::StatusCode ScStwRace::start(bool asyncronous) {
if(this->state == WAITING) {
if(this->isReadyForNextState()) {
if(this->getIsReadyForNextState()) {
this->startWaitLoop->exit(LoopManualExit);
return ScStw::Success;
}
@ -61,7 +62,7 @@ ScStw::StatusCode ScStwRace::start(bool asyncronous) {
return ScStw::CurrentStateNotVaildForOperationError;
}
if(!this->isReadyForNextState())
if(!this->getIsReadyForNextState())
return ScStw::TimersNotReadyError;
this->setState(PREPAIRING);
@ -181,7 +182,7 @@ ScStw::StatusCode ScStwRace::cancel() {
this->setState(STOPPED);
this->startWaitLoop->exit(LoopCancelExit);
this->soundPlayer->cancel(this->soundVolume);
this->soundPlayer->cancel();
this->startDelayTimer->stop();
emit this->currentStartDelayChanged();
@ -246,7 +247,7 @@ bool ScStwRace::playSoundsAndStartTimers() {
bool timerTriggered = true;
do {
if(!this->isReadyForNextState()) {
if(!this->getIsReadyForNextState()) {
this->startDelayTimer->stop();
timerTriggered = false;
}
@ -276,7 +277,7 @@ bool ScStwRace::playSoundsAndStartTimers() {
//qDebug() << "At end of loop: remaining time: " << this->startDelayTimer->remainingTime() << " timer triggered: " << timerTriggered << " ready for next state: " << this->isReadyForNextState();
} while(this->startDelayTimer->remainingTime() > 0 || !timerTriggered || !this->isReadyForNextState());
} while(this->startDelayTimer->remainingTime() > 0 || !timerTriggered || !this->getIsReadyForNextState());
qDebug() << "[RACE][DEBUG] Wait finished, starting now!";
@ -296,7 +297,7 @@ bool ScStwRace::playSoundsAndStartTimers() {
if(loopExitCode == LoopCancelExit)
return false;
} while(loopExitCode != LoopManualExit || !this->isReadyForNextState());
} while(loopExitCode != LoopManualExit || !this->getIsReadyForNextState());
}
else {
qDebug() << "now playing ready sound";
@ -449,7 +450,7 @@ void ScStwRace::refreshTimerStates() {
// --- helper functions ---
// ------------------------
bool ScStwRace::isReadyForNextState() {
bool ScStwRace::getIsReadyForNextState() {
if(!this->competitionMode) {
return true;
}
@ -542,7 +543,7 @@ QVariantList ScStwRace::getCurrentStartDelay() {
int nextActionDelay = -1;
double nextActionDelayProg = -1;
if(this->state == WAITING && !this->isReadyForNextState()) {
if(this->state == WAITING && !this->getIsReadyForNextState()) {
// indicate that we are waiting for climbers and the progress shall be zero
nextActionDelayProg = 0;
}
@ -645,13 +646,14 @@ QVariantList ScStwRace::getTimerDetailList() {
QVariantMap ScStwRace::getDetails() {
QVariantMap tmpDetails;
tmpDetails.insert("timers", this->getTimerDetailList());
tmpDetails.insert("currentStartDelay", this->getCurrentStartDelay());
tmpDetails.insert("state", this->getState());
tmpDetails.insert("competitionMode", this->competitionMode);
tmpDetails.insert("readySoundEnabled", this->startSoundSettings[ScStwSoundPlayer::Ready]["Enabled"].toBool());
tmpDetails.insert("currentStartDelay", this->getCurrentStartDelay());
tmpDetails.insert("timers", this->getTimerDetailList());
if(this->state == WAITING)
tmpDetails.insert("isReady", this->isReadyForNextState());
tmpDetails.insert("isReadyForNextState", this->getIsReadyForNextState());
return tmpDetails;
}

View file

@ -79,13 +79,15 @@ bool ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound sound, double volume, d
return true;
}
bool ScStwSoundPlayer::cancel(double volume) {
bool ScStwSoundPlayer::cancel() {
if(!this->soundEffect->isPlaying() )
return false;
// stop playback
this->soundEffect->stop();
this->waitLoop->quit();
return true;
}
bool ScStwSoundPlayer::waitForSoundFinish(double *timeOfStop) {