did some adjustments to allow waiting for climbers before start; renamed some stuff

This commit is contained in:
Dorian Zedler 2020-10-02 14:16:24 +02:00
parent 78b0b883d5
commit 41818ff308
Signed by: dorian
GPG key ID: D3B255CB8BC7CD37
5 changed files with 204 additions and 146 deletions

View file

@ -61,7 +61,7 @@ public:
RaceStateChanged = 9000, RaceStateChanged = 9000,
TimersChanged = 9001, TimersChanged = 9001,
ExtensionsChanged = 9002, ExtensionsChanged = 9002,
NextStartActionChanged = 9003, /*, ProfilesChanged*/ CurrentStartDelayChanged = 9003, /*, ProfilesChanged*/
SettingChanged = 9004 SettingChanged = 9004
}; };
Q_ENUM(SignalKey) Q_ENUM(SignalKey)
@ -84,7 +84,7 @@ public:
GetNextStartActionCommand = 2005, GetNextStartActionCommand = 2005,
GetExtensionsCommand = 2006, GetExtensionsCommand = 2006,
GetTimersCommand = 2007, GetTimersCommand = 2007,
GetNextStartActionDetailsCommand = 2009, GetCurrentStartDelayCommand = 2009,
WriteSettingCommand = 3000, WriteSettingCommand = 3000,
ReadSettingCommand = 3001, ReadSettingCommand = 3001,
@ -160,8 +160,8 @@ public:
*/ */
enum ExtensionBatteryState { enum ExtensionBatteryState {
BatteryUnknown = -1, BatteryUnknown = -1,
BatteryFine = 1, BatteryCritical = 0,
BatteryCritical = 0 BatteryFine = 1
}; };
Q_ENUM(ExtensionBatteryState); Q_ENUM(ExtensionBatteryState);

View file

@ -42,7 +42,7 @@ public slots:
int stop(); int stop();
int reset(); int reset();
bool addTimer(ScStwTimer *timer); bool addTimer(ScStwTimer *timer);
QVariantList getNextStartActionDetails(); QVariantList getCurrentStartDelay();
private slots: private slots:
void handleClientStateChanged(); void handleClientStateChanged();

View file

@ -51,7 +51,7 @@ class ScStwRace : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY(RaceState state READ getState NOTIFY stateChanged) Q_PROPERTY(RaceState state READ getState NOTIFY stateChanged)
Q_PROPERTY(QVariantList timers READ getTimerDetailList NOTIFY timersChanged) Q_PROPERTY(QVariantList timers READ getTimerDetailList NOTIFY timersChanged)
Q_PROPERTY(QVariantList nextStartActionDetails READ getNextStartActionDetails NOTIFY nextStartActionDetailsChanged) Q_PROPERTY(QVariantList currentStartDelay READ getCurrentStartDelay NOTIFY currentStartDelayChanged)
public: public:
explicit ScStwRace(QObject *parent = nullptr); explicit ScStwRace(QObject *parent = nullptr);
@ -59,42 +59,43 @@ public:
enum RaceState { IDLE, PREPAIRING, WAITING, STARTING, RUNNING, STOPPED, INCIDENT }; enum RaceState { IDLE, PREPAIRING, WAITING, STARTING, RUNNING, STOPPED, INCIDENT };
Q_ENUM(RaceState) Q_ENUM(RaceState)
enum StartAction { None = -1, AtYourMarks = 0, Ready = 1, Start = 2 }; enum CurrentStartDetailAttributes {
Q_ENUM(StartAction) CurrentStartStateTotalDelay = 0,
CurrentStartStateDelayProgress = 1
enum NextStartActionDetailAttributes {
NextStartAction = 0,
NextStartActionTotalDelay = 1,
NextStartActionDelayProgress = 2
}; };
Q_ENUM(NextStartActionDetailAttributes); Q_ENUM(CurrentStartDetailAttributes);
protected: protected:
StartAction nextStartAction;
QList<ScStwTimer *> timers; QList<ScStwTimer *> timers;
void setState(RaceState newState); void setState(RaceState newState);
private: private:
RaceState state; RaceState state;
QTimer *nextActionTimer; QTimer *startDelayTimer;
QEventLoop *nextActionLoop; QEventLoop *startWaitLoop;
QEventLoop *climberReadyWaitLoop;
// sounds // sounds
ScStwSoundPlayer * soundPlayer; ScStwSoundPlayer * soundPlayer;
// some settings // some settings
double soundVolume; double soundVolume;
bool allowAutomaticTimerDisable; bool competitionMode;
bool allowAutomaticTimerDisableChanged; bool competitionModeChanged;
/*! /*!
* \brief stores the start action settings * \brief stores the start action settings
* *
* \details Stores the settings for the action ScStwRace::AtYourMarks and ScStwRace::Ready. The settings keys are: "Enabled" and "Delay" * \details Stores the settings for the action ScStwRace::AtYourMarks and ScStwRace::Ready. The settings keys are: "Enabled" and "Delay"
*/ */
QMap<StartAction, QVariantMap> startActionSettings; QMap<ScStwSoundPlayer::StartSound, QVariantMap> startSoundSettings;
enum LoopExitTypes {
LoopAutomaticExit = 0,
LoopManualExit = 2,
LoopCancelExit = 3
};
public slots: public slots:
@ -122,15 +123,14 @@ public slots:
virtual int cancel(); virtual int cancel();
// setters // setters
bool writeStartActionSetting(StartAction action, bool enabled, int delay); bool writeStartSoundSetting(ScStwSoundPlayer::StartSound sound, bool enabled, int delay);
bool setSoundVolume(double volume); bool setSoundVolume(double volume);
virtual bool addTimer(ScStwTimer *timer); virtual bool addTimer(ScStwTimer *timer);
void setAllowAutomaticTimerDisable(bool allow); void setCompetitionMode(bool competitionMode);
// getters // getters
RaceState getState(); RaceState getState();
StartAction getNextStartAction(); virtual QVariantList getCurrentStartDelay();
virtual QVariantList getNextStartActionDetails();
QList<ScStwTimer*> getTimers(); QList<ScStwTimer*> getTimers();
QVariantList getTimerDetailList(); QVariantList getTimerDetailList();
@ -142,7 +142,7 @@ private slots:
void handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled); void handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled);
int handleFalseStart(); int handleFalseStart();
bool playSoundsAndStartTimers(); bool playSoundsAndStartTimers();
bool doDelayAndSoundOfStartAction(StartAction action, double *timeOfSoundPlaybackStart = nullptr); bool doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackStart = nullptr);
void enableAllTimers(); void enableAllTimers();
/** /**
@ -151,14 +151,14 @@ private slots:
void handleTimerStop(); void handleTimerStop();
bool isStarting(); bool isStarting();
bool isReadyForNextState();
signals: signals:
void startTimers(); void startTimers();
void stopTimers(int type); void stopTimers(int type);
void resetTimers(); void resetTimers();
void stateChanged(RaceState state); void stateChanged(RaceState state);
void nextStartActionChanged(); void currentStartDelayChanged();
void nextStartActionDetailsChanged();
void timersChanged(); void timersChanged();

View file

@ -41,6 +41,12 @@ public:
*/ */
explicit ScStwSoundPlayer(QObject *parent = nullptr); explicit ScStwSoundPlayer(QObject *parent = nullptr);
enum StartSound {
Start,
Ready,
AtYourMarks
};
private: private:
/*! /*!
* \brief A map containing all sound files * \brief A map containing all sound files

View file

@ -26,22 +26,18 @@ ScStwRace::ScStwRace(QObject *parent) : QObject(parent)
this->soundPlayer = new ScStwSoundPlayer(); this->soundPlayer = new ScStwSoundPlayer();
// configure timer that handles the delay between the start commands // configure timer that handles the delay between the start commands
this->nextActionTimer = new QTimer(this); this->startDelayTimer = new QTimer(this);
nextActionTimer->setSingleShot(true); startDelayTimer->setSingleShot(true);
this->nextActionLoop = new QEventLoop(this); this->startWaitLoop = new QEventLoop(this);
this->nextStartAction = None;
this->climberReadyWaitLoop = new QEventLoop(this);
connect(this->nextActionTimer, &QTimer::timeout, this->nextActionLoop, &QEventLoop::quit); connect(this->startDelayTimer, &QTimer::timeout, this->startWaitLoop, &QEventLoop::quit);
connect(this->nextActionTimer, &QTimer::timeout, this->climberReadyWaitLoop, &QEventLoop::quit);
connect(this, &ScStwRace::nextStartActionChanged, this, &ScStwRace::nextStartActionDetailsChanged);
// write default settings // write default settings
this->startActionSettings.insert(Start, {{"Enabled", true}, {"Delay", 1}}); this->startSoundSettings.insert(ScStwSoundPlayer::Start, {{"Enabled", true}, {"Delay", 1}});
this->writeStartActionSetting(AtYourMarks, false, 0); this->writeStartSoundSetting(ScStwSoundPlayer::AtYourMarks, false, 0);
this->writeStartActionSetting(Ready, false, 0); this->writeStartSoundSetting(ScStwSoundPlayer::Ready, false, 0);
this->setSoundVolume(1.0); this->setSoundVolume(1.0);
this->allowAutomaticTimerDisable = false; this->competitionMode = false;
} }
// -------------------------- // --------------------------
@ -49,40 +45,22 @@ ScStwRace::ScStwRace(QObject *parent) : QObject(parent)
// -------------------------- // --------------------------
int ScStwRace::start(bool asyncronous) { int ScStwRace::start(bool asyncronous) {
if(this->state != IDLE) { if(this->state == WAITING) {
if(this->isReadyForNextState()) {
this->startWaitLoop->exit(LoopManualExit);
return ScStw::Success;
}
else {
return ScStw::TimersNotReadyError;
}
}
else if(this->state != IDLE) {
return ScStw::CurrentStateNotVaildForOperationError; return ScStw::CurrentStateNotVaildForOperationError;
} }
qDebug() << "[INFO][RACE] checking timers"; qDebug() << "[INFO][RACE] checking timers";
foreach (ScStwTimer *timer, this->timers) { if(!this->isReadyForNextState())
if(timer->getState() == ScStwTimer::DISABLED)
continue;
if(timer->getReadyState() == ScStwTimer::ExtensionIsNotConnected || timer->getReadyState() == ScStwTimer::ExtensionBatteryNotFine) {
if(this->allowAutomaticTimerDisable) {
timer->setDisabled(true);
continue;
}
qDebug() << "Timer ready state is: " << timer->getReadyState();
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->setState(INCIDENT);
qDebug() << "[ERROR][RACE] Could not start due to not-ready timers";
return ScStw::TimersNotReadyError; return ScStw::TimersNotReadyError;
}
}
qDebug() << "[INFO][RACE] starting race"; qDebug() << "[INFO][RACE] starting race";
this->setState(PREPAIRING); this->setState(PREPAIRING);
@ -199,11 +177,9 @@ int ScStwRace::cancel() {
this->setState(STOPPED); this->setState(STOPPED);
this->startWaitLoop->exit(LoopCancelExit);
this->soundPlayer->cancel(this->soundVolume); this->soundPlayer->cancel(this->soundVolume);
this->nextActionTimer->stop(); this->startDelayTimer->stop();
this->nextActionLoop->quit();
this->climberReadyWaitLoop->quit();
this->nextStartAction = None;
return returnCode; return returnCode;
} }
@ -230,9 +206,8 @@ bool ScStwRace::playSoundsAndStartTimers() {
return true; return true;
// The check if all timers are ready has already happened at this point // The check if all timers are ready has already happened at this point
if(!this->doDelayAndSoundOfStartAction(AtYourMarks)) { if(!this->doDelayAndSoundOfCurrentStartState())
return false; return false;
}
// check if the start was cancelled // check if the start was cancelled
if(!this->isStarting()) if(!this->isStarting())
@ -241,65 +216,84 @@ bool ScStwRace::playSoundsAndStartTimers() {
this->setState(WAITING); this->setState(WAITING);
// do climber readiness tests // do climber readiness tests
this->nextStartAction = Ready;
emit this->nextStartActionChanged(); // wait until both climbers are ready
// if the automatic ready tone is enabled, wait for the climbers to become ready // if the automatic ready tone is enabled, wait for the climbers to become ready
if(this->startActionSettings.contains(Ready) && this->startActionSettings[Ready]["Enabled"].toBool()) { if(this->startSoundSettings.contains(ScStwSoundPlayer::Ready) && this->startSoundSettings[ScStwSoundPlayer::Ready]["Enabled"].toBool()) {
qDebug() << "[RACE][INFO] Now waiting for climbers"; qDebug() << "[RACE][INFO] Now waiting for climbers";
// get delay // get delay
int minimumReadyDelay = 1000; int minimumReadyDelay = 1000;
if(this->startActionSettings[Ready]["Delay"].toInt() > 1000 || !this->allowAutomaticTimerDisable) if(this->startSoundSettings[ScStwSoundPlayer::Ready]["Delay"].toInt() > 1000)
minimumReadyDelay = this->startActionSettings[Ready]["Delay"].toInt(); minimumReadyDelay = this->startSoundSettings[ScStwSoundPlayer::Ready]["Delay"].toInt();
this->startDelayTimer->setInterval(minimumReadyDelay);
// wait for climbers to become ready initially // wait for climbers to become ready initially
bool allClimbersReady = false; bool timerTriggered = true;
while (!allClimbersReady) { do {
allClimbersReady = true;
foreach (ScStwTimer *timer, this->timers) { if(!this->isReadyForNextState()) {
if(timer->getReadyState() != ScStwTimer::IsReady) this->startDelayTimer->stop();
allClimbersReady = false; timerTriggered = false;
}
else if(this->startDelayTimer->isActive()) {
timerTriggered = true;
}
else {
this->startDelayTimer->stop();
this->startDelayTimer->start();
} }
if(!allClimbersReady) emit this->currentStartDelayChanged();
this->climberReadyWaitLoop->exec();
// check if the start was cancelled int loopExitCode = this->startWaitLoop->exec();
if(!this->isStarting())
switch (loopExitCode) {
case LoopAutomaticExit:
break;
case LoopManualExit:
// prevent manual stop
timerTriggered = false;
break;
case LoopCancelExit:
return false; return false;
} }
} while(this->startDelayTimer->remainingTime() > 0 || !timerTriggered || !this->isReadyForNextState());
qDebug() << "[RACE][DEBUG] Initial wait finished"; qDebug() << "[RACE][DEBUG] Initial wait finished";
// wait for all climbers to be ready for the ReadyActionDelay, but at least one second continuosly // wait for all climbers to be ready for the ReadyActionDelay, but at least one second continuosly
// the climber ready wait loop will also quit, if the climber steps of the pad // the climber ready wait loop will also quit, if the climber steps of the pad
// -> wait for both climbers to stand on the pad for at least one second // -> wait for both climbers to stand on the pad for at least one second
do {
this->nextActionTimer->stop();
this->nextActionTimer->start(minimumReadyDelay);
this->climberReadyWaitLoop->exec();
// check if the start was cancelled
if(!this->isStarting())
return false;
} while(this->nextActionTimer->remainingTime() > 0);
qDebug() << "[RACE][DEBUG] Wait finished, starting now!"; qDebug() << "[RACE][DEBUG] Wait finished, starting now!";
// play ready tone // play ready tone
if(!this->soundPlayer->play(Ready, this->soundVolume)) if(!this->soundPlayer->play(ScStwSoundPlayer::Ready, this->soundVolume))
return false; return false;
} }
else {
// wait for climbers and manual start
int loopExitCode;
do {
loopExitCode = this->startWaitLoop->exec();
if(loopExitCode == LoopCancelExit)
return false;
} while(loopExitCode != LoopManualExit || !this->isReadyForNextState());
}
// enter starting state // enter starting state
this->setState(STARTING); this->setState(STARTING);
// play start tone // play start tone
double timeOfSoundPlaybackStart; double timeOfSoundPlaybackStart;
this->doDelayAndSoundOfStartAction(Start, &timeOfSoundPlaybackStart); this->doDelayAndSoundOfCurrentStartState(&timeOfSoundPlaybackStart);
// perform start // perform start
@ -324,9 +318,6 @@ bool ScStwRace::playSoundsAndStartTimers() {
if(!this->isStarting()) if(!this->isStarting())
return true; return true;
nextStartAction = None;
emit this->nextStartActionChanged();
this->setState(RUNNING); this->setState(RUNNING);
return true; return true;
@ -334,32 +325,48 @@ bool ScStwRace::playSoundsAndStartTimers() {
} }
bool ScStwRace::doDelayAndSoundOfStartAction(ScStwRace::StartAction action, double *timeOfSoundPlaybackStart) { bool ScStwRace::doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackStart) {
if(!this->isStarting()) ScStwSoundPlayer::StartSound sound;
switch (this->state) {
case PREPAIRING:
sound = ScStwSoundPlayer::AtYourMarks;
break;
case WAITING:
sound = ScStwSoundPlayer::Ready;
break;
case STARTING:
sound = ScStwSoundPlayer::Start;
break;
default:
return false; return false;
}
if(this->startActionSettings.contains(action) && this->startActionSettings[action]["Enabled"].toBool()) { if(this->startSoundSettings.contains(sound) && this->startSoundSettings[sound]["Enabled"].toBool()) {
this->nextStartAction = action;
emit this->nextStartActionChanged();
if(action != Start && this->startActionSettings[action]["Delay"].toInt() > 0) { if(sound != ScStwSoundPlayer::Start && this->startSoundSettings[sound]["Delay"].toInt() > 0) {
// perform the delay before the start // perform the delay before the start
// get delay // get delay
int thisActionDelay = this->startActionSettings[action]["Delay"].toInt(); int thisSoundDelay = this->startSoundSettings[sound]["Delay"].toInt();
// perform next action // perform next action
if(thisActionDelay > 0) { if(thisSoundDelay > 0) {
this->nextActionTimer->start(thisActionDelay); this->startDelayTimer->setInterval(thisSoundDelay);
this->nextActionLoop->exec(); this->startDelayTimer->start();
emit this->currentStartDelayChanged();
if(this->startWaitLoop->exec() == LoopCancelExit)
return false;
} }
} }
if(!this->isStarting()) if(!this->isStarting())
return false; return false;
if(!this->soundPlayer->play(action, this->soundVolume, timeOfSoundPlaybackStart)) if(!this->soundPlayer->play(sound, this->soundVolume, timeOfSoundPlaybackStart))
return false; return false;
} }
@ -374,12 +381,12 @@ void ScStwRace::setState(RaceState newState) {
if(this->state == IDLE) { if(this->state == IDLE) {
// if we changed to IDLE -> handle timer enable / disable // if we changed to IDLE -> handle timer enable / disable
if(this->allowAutomaticTimerDisableChanged && !this->allowAutomaticTimerDisable) { if(this->competitionModeChanged && this->competitionMode) {
this->enableAllTimers(); this->enableAllTimers();
this->allowAutomaticTimerDisableChanged = false; this->competitionModeChanged = false;
} }
if(this->allowAutomaticTimerDisable) { if(!this->competitionMode) {
foreach(ScStwTimer* timer, this->timers) { foreach(ScStwTimer* timer, this->timers) {
if(timer->getWantsToBeDisabled() && timer->getState() != ScStwTimer::DISABLED) if(timer->getWantsToBeDisabled() && timer->getState() != ScStwTimer::DISABLED)
this->handleTimerWantsToBeDisabledChange(timer, timer->getWantsToBeDisabled()); this->handleTimerWantsToBeDisabledChange(timer, timer->getWantsToBeDisabled());
@ -418,12 +425,64 @@ void ScStwRace::refreshTimerStates() {
// --- helper functions --- // --- helper functions ---
// ------------------------ // ------------------------
bool ScStwRace::isReadyForNextState() {
switch (this->state) {
case IDLE: {
foreach (ScStwTimer *timer, this->timers) {
if(timer->getState() == ScStwTimer::DISABLED)
continue;
if(timer->getReadyState() == ScStwTimer::ExtensionIsNotConnected || timer->getReadyState() == ScStwTimer::ExtensionBatteryNotFine) {
if(!this->competitionMode) {
timer->setDisabled(true);
continue;
}
qDebug() << "Timer ready state is: " << timer->getReadyState();
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->setState(INCIDENT);
qDebug() << "[ERROR][RACE] Could not start due to not-ready timers";
return false;
}
}
break;
case WAITING: {
foreach (ScStwTimer *timer, this->timers) {
if(timer->getReadyState() != ScStwTimer::IsReady)
return false;
}
break;
}
default:
break;;
}
}
return true;
}
/** /**
* @brief ScStwRace::handleTimerEnable function to enable timers at the right moment to prevent them from bricking the state machine * @brief ScStwRace::handleTimerEnable function to enable timers at the right moment to prevent them from bricking the state machine
* @param {ScStwExtensionControlledTimer*} timer timer to be enabled * @param {ScStwExtensionControlledTimer*} timer timer to be enabled
*/ */
void ScStwRace::handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled) { void ScStwRace::handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled) {
if(!this->allowAutomaticTimerDisable) if(this->competitionMode)
return; return;
if(this->state == IDLE) { if(this->state == IDLE) {
@ -431,18 +490,17 @@ void ScStwRace::handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wants
} }
} }
void ScStwRace::setCompetitionMode(bool competitionMode) {
void ScStwRace::setAllowAutomaticTimerDisable(bool allow) { if(this->competitionMode == competitionMode)
if(this->allowAutomaticTimerDisable == allow)
return; return;
qDebug() << "Setting allow automatic timer disable to " << allow; qDebug() << "Setting competition mode to " << competitionMode;
this->allowAutomaticTimerDisable = allow; this->competitionMode = competitionMode;
if(this->state != IDLE) if(this->state != IDLE)
this->allowAutomaticTimerDisableChanged = true; this->competitionModeChanged = true;
else if(!this->allowAutomaticTimerDisable) else if(this->competitionMode)
this->enableAllTimers(); this->enableAllTimers();
} }
@ -457,14 +515,14 @@ void ScStwRace::enableAllTimers() {
} }
} }
QVariantList ScStwRace::getNextStartActionDetails() { QVariantList ScStwRace::getCurrentStartDelay() {
int nextActionDelay = 0; int nextActionDelay = 0;
double nextActionDelayProg = -1; double nextActionDelayProg = -1;
if(this->nextStartAction == AtYourMarks || this->nextStartAction == Ready) { if(this->state == PREPAIRING || this->state == WAITING) {
// get the total delay and the delay progress of the next action timer // get the total delay and the delay progress of the next action timer
double remaining = this->nextActionTimer->remainingTime(); double remaining = this->startDelayTimer->remainingTime();
nextActionDelay = this->startActionSettings[this->nextStartAction]["Delay"].toInt(); nextActionDelay = this->startDelayTimer->interval();;
if(remaining < 0) { if(remaining < 0) {
remaining = nextActionDelay; remaining = nextActionDelay;
} }
@ -472,22 +530,21 @@ QVariantList ScStwRace::getNextStartActionDetails() {
} }
return { return {
this->nextStartAction,
nextActionDelay, nextActionDelay,
nextActionDelayProg nextActionDelayProg
}; };
} }
bool ScStwRace::writeStartActionSetting(StartAction action, bool enabled, int delay) { bool ScStwRace::writeStartSoundSetting(ScStwSoundPlayer::StartSound sound, bool enabled, int delay) {
if(action != AtYourMarks && action != Ready) if(sound != ScStwSoundPlayer::AtYourMarks && sound != ScStwSoundPlayer::Ready)
return false; return false;
QVariantMap setting = {{"Enabled", enabled}, {"Delay", delay}}; QVariantMap setting = {{"Enabled", enabled}, {"Delay", delay}};
if(!this->startActionSettings.contains(action)) if(!this->startSoundSettings.contains(sound))
this->startActionSettings.insert(action, setting); this->startSoundSettings.insert(sound, setting);
else else
this->startActionSettings[action] = setting; this->startSoundSettings[sound] = setting;
return true; return true;
} }
@ -517,9 +574,9 @@ bool ScStwRace::addTimer(ScStwTimer *timer) {
connect(timer, &ScStwTimer::wantsToBeDisabledChanged, this, &ScStwRace::handleTimerWantsToBeDisabledChange); connect(timer, &ScStwTimer::wantsToBeDisabledChanged, this, &ScStwRace::handleTimerWantsToBeDisabledChange);
connect(timer, &ScStwTimer::stateChanged, this, &ScStwRace::timersChanged); connect(timer, &ScStwTimer::stateChanged, this, &ScStwRace::timersChanged);
connect(timer, &ScStwTimer::reactionTimeChanged, this, &ScStwRace::timersChanged); connect(timer, &ScStwTimer::reactionTimeChanged, this, &ScStwRace::timersChanged);
connect(timer, &ScStwTimer::readyStateChanged, this->climberReadyWaitLoop, &QEventLoop::quit); connect(timer, &ScStwTimer::readyStateChanged, this->startWaitLoop, &QEventLoop::quit);
if(!this->allowAutomaticTimerDisable && timer->getState() == ScStwTimer::DISABLED) if(this->competitionMode && timer->getState() == ScStwTimer::DISABLED)
timer->setDisabled(false); timer->setDisabled(false);
return true; return true;
@ -530,11 +587,6 @@ ScStwRace::RaceState ScStwRace::getState() {
return this->state; return this->state;
} }
ScStwRace::StartAction ScStwRace::getNextStartAction()
{
return this->nextStartAction;
}
QList<ScStwTimer*> ScStwRace::getTimers() { QList<ScStwTimer*> ScStwRace::getTimers() {
return this->timers; return this->timers;
} }