implemented race details
This commit is contained in:
parent
3c626b82da
commit
c9e1f4f8ec
6 changed files with 67 additions and 46 deletions
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Reference in a new issue