diff --git a/ScStwLibraries/headers/scstwrace.h b/ScStwLibraries/headers/scstwrace.h index c745038..87599d0 100644 --- a/ScStwLibraries/headers/scstwrace.h +++ b/ScStwLibraries/headers/scstwrace.h @@ -87,6 +87,7 @@ private: enum LoopExitTypes { LoopAutomaticExit = 0, + LoopReadyStateChangeExit = 1, LoopManualExit = 2, LoopCancelExit = 3 }; diff --git a/ScStwLibraries/sources/scstwrace.cpp b/ScStwLibraries/sources/scstwrace.cpp index f00fa40..e51e29f 100644 --- a/ScStwLibraries/sources/scstwrace.cpp +++ b/ScStwLibraries/sources/scstwrace.cpp @@ -194,12 +194,43 @@ ScStw::StatusCode ScStwRace::cancel() { } void ScStwRace::technicalIncident() { + + bool raceIsRunning = this->state == RUNNING; + + qDebug() << "[ERROR][RACE] Got a technical incident"; + foreach(ScStwTimer *timer, this->timers){ - timer->cancel(); + if(raceIsRunning && timer->getReadyState() == ScStwTimer::ExtensionBatteryNotFine) + continue; + else if(timer->getReadyState() == ScStwTimer::ExtensionIsNotConnected || timer->getReadyState() == ScStwTimer::ExtensionBatteryNotFine) + timer->technicalIncident(); + else if(!raceIsRunning) + timer->setState(ScStwTimer::CANCELLED); } - this->soundPlayer->cancel(); - this->setState(INCIDENT); + if(!raceIsRunning) { + this->startWaitLoop->exit(LoopCancelExit); + this->soundPlayer->cancel(); + this->setState(INCIDENT); + } +} + +void ScStwRace::handleTimerReadyStateChange(ScStwTimer::ReadyState readyState) { + + if(!this->competitionMode || this->state == IDLE || this->state == STOPPED || this->state == INCIDENT ) + return; + + // cancel as a technical incident if extensions are disconnected or run low on battery + if(readyState == ScStwTimer::ExtensionBatteryNotFine || readyState == ScStwTimer::ExtensionBatteryNotFine) { + this->technicalIncident(); + return; + } + + // only continue if the current state is waiting + if(this->state == WAITING) { + this->startWaitLoop->exit(ScStwRace::LoopReadyStateChangeExit); + emit this->timersChanged(); + } } int ScStwRace::handleFalseStart() { @@ -466,15 +497,6 @@ bool ScStwRace::getIsReadyForNextState() { if(timer->getReadyState() == ScStwTimer::ExtensionIsNotConnected || timer->getReadyState() == ScStwTimer::ExtensionBatteryNotFine) { - timer->technicalIncident(); - - foreach (ScStwTimer *subTimer, this->timers) { - if(timer != subTimer && (timer->getReadyState() == ScStwTimer::ExtensionIsNotConnected || timer->getReadyState() == ScStwTimer::ExtensionBatteryNotFine)) - subTimer->technicalIncident(); - else if(timer != subTimer) - subTimer->setState(ScStwTimer::CANCELLED); - } - this->technicalIncident(); qDebug() << "[ERROR][RACE] Could not start due to not-ready timers"; @@ -603,7 +625,6 @@ bool ScStwRace::addTimer(ScStwTimer *timer) { connect(timer, &ScStwTimer::stateChanged, this, &ScStwRace::timersChanged); connect(timer, &ScStwTimer::wantsToBeDisabledChanged, this, &ScStwRace::handleTimerWantsToBeDisabledChange); connect(timer, &ScStwTimer::reactionTimeChanged, this, &ScStwRace::timersChanged); - connect(timer, &ScStwTimer::readyStateChanged, this->startWaitLoop, &QEventLoop::quit); connect(timer, &ScStwTimer::readyStateChanged, this, &ScStwRace::handleTimerReadyStateChange); connect(timer, &ScStwTimer::readyStateChanged, this, &ScStwRace::isReadyForNextStateChanged); @@ -719,15 +740,6 @@ QVariantMap ScStwRace::getDetails() { bool ScStwRace::isStarting() { return this->state == PREPAIRING || this->state == WAITING || this->state == STARTING; } - -void ScStwRace::handleTimerReadyStateChange(ScStwTimer::ReadyState readyState) { - Q_UNUSED(readyState) - - // only continue if the current state is waiting - if(this->state == WAITING) - emit this->timersChanged(); -} - bool ScStwRace::getCompetitionMode() { return this->competitionMode; }