diff --git a/ScStwLibraries/headers/client/scstwremoterace.h b/ScStwLibraries/headers/client/scstwremoterace.h index 2b22cf5..505cb4e 100644 --- a/ScStwLibraries/headers/client/scstwremoterace.h +++ b/ScStwLibraries/headers/client/scstwremoterace.h @@ -29,33 +29,43 @@ class ScStwRemoteRace : public ScStwRace { Q_OBJECT public: - ScStwRemoteRace(ScStwClient *monitorClient, QObject *parent = nullptr); + ScStwRemoteRace(ScStwClient *scStwClient, QObject *parent = nullptr); + + enum RaceMode { + LOCAL, + REMOTE + }; protected: double currentStartTotalDelay; double currentStartDelayStartedAt; double latestStartDelayProgress; bool isReadyForNextState; + bool readySoundEnabled; private: ScStwClient *scStwClient; QList remoteTimers; + QList localTimers; public slots: - ScStw::StatusCode start(bool); - ScStw::StatusCode start(); + ScStw::StatusCode start(bool asyncronous = true); ScStw::StatusCode cancel(); ScStw::StatusCode stop(); ScStw::StatusCode reset(); bool addTimer(ScStwTimer *timer); QVariantMap getCurrentStartDelay(); bool getIsReadyForNextState(); + bool getReadySoundEnabled(); private slots: - void handleClientStateChanged(); void handleBaseStationSignal(ScStw::SignalKey key, QVariant data); bool refreshRemoteTimers(QVariantList remoteTimers); + void rebuildRemoteTimers(QVariantList remoteTimers); void refreshDetails(QVariantMap details); + void handleClientStateChange(); + RaceMode getMode(); + bool local(); }; diff --git a/ScStwLibraries/headers/client/scstwremotesettings.h b/ScStwLibraries/headers/client/scstwremotesettings.h index af3beb9..2b6a9f3 100644 --- a/ScStwLibraries/headers/client/scstwremotesettings.h +++ b/ScStwLibraries/headers/client/scstwremotesettings.h @@ -43,11 +43,10 @@ protected: private: ScStwClient * scStwClient; - SettingsMode getMode(); - private slots: void handleClientStateChange(); void handleBaseStationSignal(ScStw::SignalKey key, QVariant data); + SettingsMode getMode(); }; #endif // SCSTWREMOTESETTINGS_H diff --git a/ScStwLibraries/headers/scstwrace.h b/ScStwLibraries/headers/scstwrace.h index 4409c9a..7d6ac3c 100644 --- a/ScStwLibraries/headers/scstwrace.h +++ b/ScStwLibraries/headers/scstwrace.h @@ -137,7 +137,7 @@ public slots: QVariantList getTimerDetailList(); QVariantMap getDetails(); bool getCompetitionMode(); - bool getReadySoundEnabled(); + virtual bool getReadySoundEnabled(); protected slots: diff --git a/ScStwLibraries/sources/client/scstwremoterace.cpp b/ScStwLibraries/sources/client/scstwremoterace.cpp index a7a5e8f..aca8b6e 100644 --- a/ScStwLibraries/sources/client/scstwremoterace.cpp +++ b/ScStwLibraries/sources/client/scstwremoterace.cpp @@ -18,16 +18,15 @@ #include "scstwremoterace.h" -ScStwRemoteRace::ScStwRemoteRace(ScStwClient *monitorClient, QObject *parent) : ScStwRace(parent) +ScStwRemoteRace::ScStwRemoteRace(ScStwClient *scStwClient, QObject *parent) : ScStwRace(parent) { - this->currentlyWaitingForClimbers = false; this->isReadyForNextState = true; - this->scStwClient = monitorClient; + this->scStwClient = scStwClient; this->scStwClient->addSignalSubscription(ScStw::RaceDetailsChanged); - connect(this->scStwClient, &ScStwClient::stateChanged, this, &ScStwRemoteRace::handleClientStateChanged); + connect(this->scStwClient, &ScStwClient::stateChanged, this, &ScStwRemoteRace::handleClientStateChange); connect(this->scStwClient, &ScStwClient::gotSignal, this, &ScStwRemoteRace::handleBaseStationSignal); } @@ -35,11 +34,10 @@ ScStwRemoteRace::ScStwRemoteRace(ScStwClient *monitorClient, QObject *parent) : // --- Main Functionality --- // -------------------------- -ScStw::StatusCode ScStwRemoteRace::start(bool) { - return this->start(); -} +ScStw::StatusCode ScStwRemoteRace::start(bool asyncronous) { + if(this->local()) + return ScStwRace::start(asyncronous); -ScStw::StatusCode ScStwRemoteRace::start() { if(this->getState() != ScStwRace::IDLE && this->getState() != ScStwRace::WAITING) return ScStw::CurrentStateNotVaildForOperationError; @@ -51,6 +49,9 @@ ScStw::StatusCode ScStwRemoteRace::start() { } ScStw::StatusCode ScStwRemoteRace::cancel() { + if(this->local()) + return ScStwRace::cancel(); + if(this->getState() != PREPAIRING && this->getState() != WAITING && this->getState() != STARTING && this->getState() != RUNNING) return ScStw::CurrentStateNotVaildForOperationError; @@ -62,6 +63,9 @@ ScStw::StatusCode ScStwRemoteRace::cancel() { } ScStw::StatusCode ScStwRemoteRace::stop() { + if(this->local()) + return ScStwRace::stop(); + if(this->getState() != ScStwRace::RUNNING && this->getState() != ScStwRace::STARTING) return ScStw::CurrentStateNotVaildForOperationError; @@ -73,6 +77,9 @@ ScStw::StatusCode ScStwRemoteRace::stop() { } ScStw::StatusCode ScStwRemoteRace::reset() { + if(this->local()) + return ScStwRace::reset(); + if(this->getState() != ScStwRace::STOPPED && this->getState() != ScStwRace::INCIDENT) return ScStw::CurrentStateNotVaildForOperationError; @@ -88,18 +95,41 @@ ScStw::StatusCode ScStwRemoteRace::reset() { // --- Base Station sync --- // ------------------------- -void ScStwRemoteRace::handleClientStateChanged() { - // TODO +void ScStwRemoteRace::handleClientStateChange() { switch (this->scStwClient->getState()) { case ScStwClient::CONNECTED: - break; - default: + this->localTimers.clear(); + this->localTimers = this->timers; this->timers.clear(); + break; + case ScStwClient::DISCONNECTED: + foreach(ScStwRemoteTimer *remoteTimer, this->remoteTimers) + remoteTimer->deleteLater(); + this->remoteTimers.clear(); + + this->timers.clear(); + this->timers = this->localTimers; + this->localTimers.clear(); + emit this->timersChanged(); + this->competitionMode = false; this->setState(IDLE); break; + default: + break; } } +ScStwRemoteRace::RaceMode ScStwRemoteRace::getMode() { + if(this->scStwClient->getState() == ScStwClient::CONNECTED) + return ScStwRemoteRace::REMOTE; + else + return ScStwRemoteRace::LOCAL; +} + +bool ScStwRemoteRace::local() { + return this->getMode() == LOCAL; +} + /** * @brief ScStwAppBackend::handleBaseStationUpdate * @@ -134,8 +164,8 @@ void ScStwRemoteRace::refreshDetails(QVariantMap details) { } // ready sound enabled - if(this->getReadySoundEnabled() != details["readySoundEnabled"].toBool()) { - this->writeStartSoundSetting(ScStwSoundPlayer::Ready, details["readySoundEnabled"].toBool(), 0); + if(this->readySoundEnabled != details["readySoundEnabled"].toBool()) { + this->readySoundEnabled = details["readySoundEnabled"].toBool(); emit this->readySoundEnabledChanged(); } @@ -159,34 +189,41 @@ void ScStwRemoteRace::refreshDetails(QVariantMap details) { } +void ScStwRemoteRace::rebuildRemoteTimers(QVariantList remoteTimers) { + // delete all current timers + foreach(ScStwTimer * oldTimer, this->timers){ + oldTimer->deleteLater(); + } + + this->remoteTimers.clear(); + this->timers.clear(); + + foreach(QVariant remoteTimer, remoteTimers){ + // create a local timer for each remote timer + ScStwRemoteTimer * timer = new ScStwRemoteTimer(this); + this->timers.append(timer); + this->remoteTimers.append(timer); + connect(timer, &ScStwTimer::stateChanged, this, &ScStwRace::timersChanged); + connect(timer, &ScStwTimer::reactionTimeChanged, this, &ScStwRace::timersChanged); + } +} + bool ScStwRemoteRace::refreshRemoteTimers(QVariantList remoteTimers) { - if(remoteTimers.length() != this->timers.length()){ + if(remoteTimers.length() != this->remoteTimers.length()){ // local timers are out of sync - - // delete all current timers - foreach(ScStwTimer * locTimer, this->timers){ - delete locTimer; - } - - this->timers.clear(); - - foreach(QVariant remoteTimer, remoteTimers){ - // create a local timer for each remote timer - ScStwRemoteTimer * timer = new ScStwRemoteTimer(this); - this->timers.append(timer); - this->remoteTimers.append(timer); - connect(timer, &ScStwTimer::stateChanged, this, &ScStwRace::timersChanged); - connect(timer, &ScStwTimer::reactionTimeChanged, this, &ScStwRace::timersChanged); - } + this->rebuildRemoteTimers(remoteTimers); } foreach(QVariant remoteTimer, remoteTimers){ int currId = remoteTimer.toMap()["id"].toInt(); + if(this->remoteTimers.length() <= currId) + this->rebuildRemoteTimers(remoteTimers); + ScStwTimer::TimerState newState = ScStwTimer::TimerState(remoteTimer.toMap()["state"].toInt()); - qDebug() << "refreshing timers: id: " << currId << " state: " << newState << " readyState: " << remoteTimer.toMap()["readyState"].toInt(); + qDebug() << "refreshing timers: id: " << currId << " state: " << newState << " readyState: " << remoteTimer.toMap()["readyState"].toInt() << " currentTime: " << remoteTimer.toMap()["currentTime"].toDouble(); double currentMSecsSinceEpoch = QDateTime::currentMSecsSinceEpoch(); @@ -206,11 +243,15 @@ bool ScStwRemoteRace::refreshRemoteTimers(QVariantList remoteTimers) { } bool ScStwRemoteRace::addTimer(ScStwTimer* timer) { - Q_UNUSED(timer) + if(this->local()) + return ScStwRace::addTimer(timer); + return false; } QVariantMap ScStwRemoteRace::getCurrentStartDelay() { + if(this->local()) + return ScStwRace::getCurrentStartDelay(); QVariantMap currentStartDelay = { {"total", -1.0}, @@ -234,5 +275,15 @@ QVariantMap ScStwRemoteRace::getCurrentStartDelay() { } bool ScStwRemoteRace::getIsReadyForNextState() { + if(this->local()) + return ScStwRace::getIsReadyForNextState(); + return this->isReadyForNextState; } + +bool ScStwRemoteRace::getReadySoundEnabled() { + if(this->local()) + return ScStwRace::getReadySoundEnabled(); + + return this->readySoundEnabled; +} diff --git a/ScStwLibraries/sources/scstwtimer.cpp b/ScStwLibraries/sources/scstwtimer.cpp index 249bfa8..f7f77ba 100644 --- a/ScStwLibraries/sources/scstwtimer.cpp +++ b/ScStwLibraries/sources/scstwtimer.cpp @@ -25,6 +25,8 @@ ScStwTimer::ScStwTimer(QObject *parent, QString letter) : QObject(parent) else this->letter = letter; + qDebug() << "Timer created with letter: " << letter; + this->startTime = 0; this->stopTime = 0; this->reactionTime = 0; @@ -86,6 +88,9 @@ bool ScStwTimer::cancel() { return false; qDebug() << "[INFO][TIMER] Timer was cancelled"; + this->reactionTime = 0; + this->startTime = 0; + this->stopTime = 0; this->setState(CANCELLED); return true; @@ -213,6 +218,8 @@ QString ScStwTimer::getLetter() { QString ScStwTimer::getText() { + qDebug() << "getting text: start time: " << this->startTime << " state: " << this->state; + QString newText = ""; int newTime = 0; switch (this->state) {