diff --git a/ScStwLibraries/headers/client/scstwremoterace.h b/ScStwLibraries/headers/client/scstwremoterace.h index 9c89e56..2b22cf5 100644 --- a/ScStwLibraries/headers/client/scstwremoterace.h +++ b/ScStwLibraries/headers/client/scstwremoterace.h @@ -34,7 +34,7 @@ public: protected: double currentStartTotalDelay; double currentStartDelayStartedAt; - bool currentlyWaitingForClimbers; + double latestStartDelayProgress; bool isReadyForNextState; private: @@ -48,7 +48,7 @@ public slots: ScStw::StatusCode stop(); ScStw::StatusCode reset(); bool addTimer(ScStwTimer *timer); - QVariantList getCurrentStartDelay(); + QVariantMap getCurrentStartDelay(); bool getIsReadyForNextState(); private slots: diff --git a/ScStwLibraries/headers/scstwrace.h b/ScStwLibraries/headers/scstwrace.h index 6d9b682..4409c9a 100644 --- a/ScStwLibraries/headers/scstwrace.h +++ b/ScStwLibraries/headers/scstwrace.h @@ -53,8 +53,10 @@ class ScStwRace : public QObject Q_OBJECT 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(QVariantMap currentStartDelay READ getCurrentStartDelay NOTIFY currentStartDelayChanged) Q_PROPERTY(bool isReadyForNextState READ getIsReadyForNextState NOTIFY isReadyForNextStateChanged) + Q_PROPERTY(bool competitionMode READ getCompetitionMode NOTIFY competitionModeChanged) + Q_PROPERTY(bool readySoundEnabled READ getReadySoundEnabled NOTIFY readySoundEnabledChanged) Q_PROPERTY(QVariantMap details READ getDetails NOTIFY detailsChanged) public: @@ -65,12 +67,6 @@ public: enum RaceState { IDLE, PREPAIRING, WAITING, STARTING, RUNNING, STOPPED, INCIDENT }; Q_ENUM(RaceState) - enum CurrentStartDetailAttributes { - CurrentStartStateTotalDelay = 0, - CurrentStartStateDelayProgress = 1 - }; - Q_ENUM(CurrentStartDetailAttributes); - protected: QList timers; void setState(RaceState newState); @@ -87,7 +83,7 @@ private: // some settings double soundVolume; bool competitionMode; - bool competitionModeChanged; + bool competitionModeChangedRecently; /*! * \brief stores the start action settings @@ -136,14 +132,15 @@ public slots: // getters RaceState getState(); - virtual QVariantList getCurrentStartDelay(); + virtual QVariantMap getCurrentStartDelay(); QList getTimers(); QVariantList getTimerDetailList(); QVariantMap getDetails(); + bool getCompetitionMode(); + bool getReadySoundEnabled(); protected slots: - private slots: void refreshTimerStates(); void handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled); @@ -170,7 +167,8 @@ signals: void timersChanged(); void isReadyForNextStateChanged(); void detailsChanged(); - + void competitionModeChanged(); + void readySoundEnabledChanged(); }; diff --git a/ScStwLibraries/sources/client/scstwremoterace.cpp b/ScStwLibraries/sources/client/scstwremoterace.cpp index a8f53e2..a7a5e8f 100644 --- a/ScStwLibraries/sources/client/scstwremoterace.cpp +++ b/ScStwLibraries/sources/client/scstwremoterace.cpp @@ -128,15 +128,21 @@ void ScStwRemoteRace::refreshDetails(QVariantMap details) { this->setState(ScStwRace::RaceState(details["state"].toInt())); // competition mode - this->competitionMode = details["competitionMode"].toBool(); + if(this->competitionMode != details["competitionMode"].toBool()) { + this->competitionMode = details["competitionMode"].toBool(); + emit this->competitionModeChanged(); + } // ready sound enabled - this->writeStartSoundSetting(ScStwSoundPlayer::Ready, details["readySoundEnabled"].toBool(), 0); + if(this->getReadySoundEnabled() != details["readySoundEnabled"].toBool()) { + this->writeStartSoundSetting(ScStwSoundPlayer::Ready, details["readySoundEnabled"].toBool(), 0); + emit this->readySoundEnabledChanged(); + } // 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; + this->currentStartTotalDelay = details["currentStartDelay"].toMap()["total"].toInt(); + this->latestStartDelayProgress = details["currentStartDelay"].toMap()["progress"].toDouble(); + this->currentStartDelayStartedAt = QDateTime::currentMSecsSinceEpoch() - (this->currentStartTotalDelay * this->latestStartDelayProgress); emit this->currentStartDelayChanged(); @@ -204,27 +210,27 @@ bool ScStwRemoteRace::addTimer(ScStwTimer* timer) { return false; } -QVariantList ScStwRemoteRace::getCurrentStartDelay() { - int nextActionDelay = -1; - double nextActionDelayProg = -1; +QVariantMap ScStwRemoteRace::getCurrentStartDelay() { - if(this->getState() == WAITING && this->currentlyWaitingForClimbers) { - nextActionDelayProg = 0; + QVariantMap currentStartDelay = { + {"total", -1.0}, + {"progress", -1.0} + }; + + if(this->currentStartTotalDelay == -1) { + currentStartDelay["progress"] = this->latestStartDelayProgress; } else if(this->getState() == PREPAIRING || this->getState() == WAITING) { // get the total delay and the delay progress of the next action timer double elapsed = QDateTime::currentMSecsSinceEpoch() - this->currentStartDelayStartedAt; - nextActionDelay = this->currentStartTotalDelay; - if(elapsed < 0 || elapsed > nextActionDelay) { - elapsed = nextActionDelay; + currentStartDelay["total"] = this->currentStartTotalDelay; + if(elapsed < 0 || elapsed > currentStartDelay["total"].toDouble()) { + elapsed = currentStartDelay["total"].toDouble(); } - nextActionDelayProg = elapsed / nextActionDelay; + currentStartDelay["progress"] = elapsed / currentStartDelay["total"].toDouble(); } - return { - nextActionDelay, - nextActionDelayProg - }; + return currentStartDelay; } bool ScStwRemoteRace::getIsReadyForNextState() { diff --git a/ScStwLibraries/sources/scstwrace.cpp b/ScStwLibraries/sources/scstwrace.cpp index 6f6ae98..58cbe94 100644 --- a/ScStwLibraries/sources/scstwrace.cpp +++ b/ScStwLibraries/sources/scstwrace.cpp @@ -406,9 +406,9 @@ void ScStwRace::setState(RaceState newState) { if(this->state == IDLE) { // if we changed to IDLE -> handle timer enable / disable - if(this->competitionModeChanged && this->competitionMode) { + if(this->competitionModeChangedRecently && this->competitionMode) { this->enableAllTimers(); - this->competitionModeChanged = false; + this->competitionModeChangedRecently = false; } if(!this->competitionMode) { @@ -523,7 +523,7 @@ void ScStwRace::setCompetitionMode(bool competitionMode) { this->competitionMode = competitionMode; if(this->state != IDLE) - this->competitionModeChanged = true; + this->competitionModeChangedRecently = true; else if(this->competitionMode) this->enableAllTimers(); } @@ -539,31 +539,48 @@ void ScStwRace::enableAllTimers() { } } -QVariantList ScStwRace::getCurrentStartDelay() { - int nextActionDelay = -1; - double nextActionDelayProg = -1; +QVariantMap ScStwRace::getCurrentStartDelay() { - if(this->state == WAITING && !this->getIsReadyForNextState()) { - // indicate that we are waiting for climbers and the progress shall be zero - nextActionDelayProg = 0; - } - else if(this->state == PREPAIRING || this->state == WAITING) { - // get the total delay and the delay progress of the next action timer - double remaining = this->startDelayTimer->remainingTime(); - nextActionDelay = this->startDelayTimer->interval(); - if(remaining < 0) { - remaining = nextActionDelay; - } - nextActionDelayProg = 1 - (remaining / nextActionDelay); - - if(nextActionDelayProg < 0) - nextActionDelayProg = 0; - } - - return { - nextActionDelay, - nextActionDelayProg + QVariantMap currentStartDelay = { + {"total", -1.0}, + {"progress", -1.0} }; + + switch (this->state) { + + case WAITING: + if(!this->startSoundSettings[ScStwSoundPlayer::Ready]["Enabled"].toBool()) + return currentStartDelay; + if(!this->getIsReadyForNextState()) + // indicate that we are waiting for climbers and the progress shall be zero + currentStartDelay["progress"] = -1; + return currentStartDelay; + case PREPAIRING: { + if(!this->startSoundSettings[ScStwSoundPlayer::AtYourMarks]["Enabled"].toBool()) + return currentStartDelay; + + break; + } + + default: + return currentStartDelay; + break; + + } + + // get the total delay and the delay progress of the next action timer + double remaining = this->startDelayTimer->remainingTime(); + currentStartDelay["total"] = this->startDelayTimer->interval(); + if(remaining < 0) { + remaining = currentStartDelay["total"].toDouble(); + } + currentStartDelay["progress"] = 1 - (remaining / currentStartDelay["total"].toDouble()); + + if(currentStartDelay["progress"].toDouble() < 0) + currentStartDelay["progress"] = 0; + + + return currentStartDelay; } bool ScStwRace::writeStartSoundSetting(ScStwSoundPlayer::StartSound sound, bool enabled, int delay) { @@ -669,3 +686,11 @@ void ScStwRace::handleTimerReadyStateChange(ScStwTimer::ReadyState readyState) { if(this->state == WAITING) emit this->timersChanged(); } + +bool ScStwRace::getCompetitionMode() { + return this->competitionMode; +} + +bool ScStwRace::getReadySoundEnabled() { + return this->startSoundSettings[ScStwSoundPlayer::Ready]["Enabled"].toBool(); +}