Merge remote-tracking branch 'origin/master'
# Conflicts: # ScStwLibraries/headers/scstwrace.h
This commit is contained in:
commit
3c626b82da
5 changed files with 78 additions and 45 deletions
|
@ -62,7 +62,8 @@ public:
|
|||
TimersChanged = 9001,
|
||||
ExtensionsChanged = 9002,
|
||||
CurrentStartDelayChanged = 9003, /*, ProfilesChanged*/
|
||||
SettingChanged = 9004
|
||||
SettingChanged = 9004,
|
||||
RaceDetailsChanged = 9005
|
||||
};
|
||||
Q_ENUM(SignalKey)
|
||||
|
||||
|
@ -82,7 +83,7 @@ public:
|
|||
CancelRaceCommand = 1003,
|
||||
|
||||
GetRaceStateCommand = 2000,
|
||||
GetNextStartActionCommand = 2005,
|
||||
GetRaceDetailsCommand = 2001,
|
||||
GetExtensionsCommand = 2006,
|
||||
GetTimersCommand = 2007,
|
||||
GetCurrentStartDelayCommand = 2009,
|
||||
|
|
|
@ -53,6 +53,7 @@ class ScStwRace : public QObject
|
|||
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(QVariantMap details READ getDetails NOTIFY detailsChanged)
|
||||
|
||||
public:
|
||||
explicit ScStwRace(QObject *parent = nullptr);
|
||||
|
@ -134,6 +135,7 @@ public slots:
|
|||
virtual QVariantList getCurrentStartDelay();
|
||||
QList<ScStwTimer*> getTimers();
|
||||
QVariantList getTimerDetailList();
|
||||
QVariantMap getDetails();
|
||||
|
||||
protected slots:
|
||||
|
||||
|
@ -153,6 +155,7 @@ private slots:
|
|||
|
||||
bool isStarting();
|
||||
bool isReadyForNextState();
|
||||
void handleTimerReadyStateChange(ScStwTimer::ReadyState readyState);
|
||||
|
||||
signals:
|
||||
void startTimers();
|
||||
|
@ -161,7 +164,11 @@ signals:
|
|||
void stateChanged(RaceState state);
|
||||
void currentStartDelayChanged();
|
||||
void timersChanged();
|
||||
<<<<<<< HEAD
|
||||
void isReadyForNextStateChanged();
|
||||
=======
|
||||
void detailsChanged();
|
||||
>>>>>>> origin/master
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -42,10 +42,11 @@ public:
|
|||
explicit ScStwSoundPlayer(QObject *parent = nullptr);
|
||||
|
||||
enum StartSound {
|
||||
AtYourMarks,
|
||||
Ready,
|
||||
Start,
|
||||
FalseStart
|
||||
None = -1,
|
||||
AtYourMarks = 0,
|
||||
Ready = 1,
|
||||
Start = 2,
|
||||
FalseStart = 3
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -32,6 +32,9 @@ ScStwRace::ScStwRace(QObject *parent) : QObject(parent)
|
|||
|
||||
connect(this->startDelayTimer, &QTimer::timeout, this->startWaitLoop, &QEventLoop::quit);
|
||||
|
||||
connect(this, &ScStwRace::currentStartDelayChanged, this, &ScStwRace::detailsChanged);
|
||||
connect(this, &ScStwRace::timersChanged, this, &ScStwRace::detailsChanged);
|
||||
|
||||
// write default settings
|
||||
this->startSoundSettings.insert(ScStwSoundPlayer::Start, {{"Enabled", true}, {"Delay", 1}});
|
||||
this->writeStartSoundSetting(ScStwSoundPlayer::AtYourMarks, false, 0);
|
||||
|
@ -58,11 +61,9 @@ ScStw::StatusCode ScStwRace::start(bool asyncronous) {
|
|||
return ScStw::CurrentStateNotVaildForOperationError;
|
||||
}
|
||||
|
||||
qDebug() << "[INFO][RACE] checking timers";
|
||||
if(!this->isReadyForNextState())
|
||||
return ScStw::TimersNotReadyError;
|
||||
|
||||
qDebug() << "[INFO][RACE] starting race";
|
||||
this->setState(PREPAIRING);
|
||||
|
||||
if(asyncronous) {
|
||||
|
@ -156,6 +157,8 @@ ScStw::StatusCode ScStwRace::reset() {
|
|||
if(returnCode == ScStw::Success)
|
||||
this->setState(IDLE);
|
||||
|
||||
this->soundPlayer->cancel();
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
|
@ -181,6 +184,8 @@ ScStw::StatusCode ScStwRace::cancel() {
|
|||
this->soundPlayer->cancel(this->soundVolume);
|
||||
this->startDelayTimer->stop();
|
||||
|
||||
emit this->currentStartDelayChanged();
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
|
@ -196,7 +201,8 @@ int ScStwRace::handleFalseStart() {
|
|||
}
|
||||
|
||||
this->setState(STOPPED);
|
||||
this->soundPlayer->cancel(this->soundVolume);
|
||||
this->soundPlayer->cancel();
|
||||
this->soundPlayer->play(ScStwSoundPlayer::FalseStart, this->soundVolume);
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
@ -233,7 +239,10 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
|||
|
||||
this->startDelayTimer->setInterval(minimumReadyDelay);
|
||||
|
||||
// wait for climbers to become ready initially
|
||||
// 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
|
||||
// -> wait for both climbers to stand on the pad for at least one second
|
||||
|
||||
bool timerTriggered = true;
|
||||
do {
|
||||
|
||||
|
@ -252,10 +261,7 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
|||
|
||||
emit this->currentStartDelayChanged();
|
||||
|
||||
|
||||
qDebug() << "entering wait loop...";
|
||||
int loopExitCode = this->startWaitLoop->exec();
|
||||
qDebug() << "wait loop exited with code " << loopExitCode;
|
||||
|
||||
switch (loopExitCode) {
|
||||
case LoopAutomaticExit:
|
||||
|
@ -268,22 +274,19 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
|||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "At end of loop: remaining time: " << this->startDelayTimer->remainingTime() << " timer triggered: " << timerTriggered << " ready for next state: " << this->isReadyForNextState();
|
||||
//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());
|
||||
|
||||
qDebug() << "[RACE][DEBUG] Initial wait finished";
|
||||
|
||||
// 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
|
||||
// -> wait for both climbers to stand on the pad for at least one second
|
||||
|
||||
qDebug() << "[RACE][DEBUG] Wait finished, starting now!";
|
||||
|
||||
// play ready tone
|
||||
if(!this->soundPlayer->play(ScStwSoundPlayer::Ready, this->soundVolume))
|
||||
if(!this->soundPlayer->play(ScStwSoundPlayer::Ready, this->soundVolume)) {
|
||||
qDebug() << "Ready sound redturned false!";
|
||||
this->setState(INCIDENT);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(this->competitionMode) {
|
||||
// wait for climbers and manual start
|
||||
int loopExitCode;
|
||||
|
@ -297,9 +300,11 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
|||
}
|
||||
else {
|
||||
qDebug() << "now playing ready sound";
|
||||
if(!this->doDelayAndSoundOfCurrentStartState())
|
||||
if(!this->doDelayAndSoundOfCurrentStartState()) {
|
||||
this->cancel();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "now in starting state";
|
||||
|
||||
|
@ -309,7 +314,10 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
|||
// play start tone
|
||||
qDebug() << "now playing start sound";
|
||||
double timeOfSoundPlaybackStart;
|
||||
this->doDelayAndSoundOfCurrentStartState(&timeOfSoundPlaybackStart);
|
||||
if(!this->doDelayAndSoundOfCurrentStartState(&timeOfSoundPlaybackStart)) {
|
||||
this->setState(INCIDENT);
|
||||
return false;
|
||||
}
|
||||
|
||||
// perform start
|
||||
|
||||
|
@ -322,11 +330,13 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
|||
}
|
||||
if(!startOk) {
|
||||
qDebug() << "[ERROR][START] error staring all timers";
|
||||
this->setState(INCIDENT);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!this->soundPlayer->waitForSoundFinish()) {
|
||||
qDebug() << "[ERROR][START] start sound wait error";
|
||||
this->setState(INCIDENT);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -529,17 +539,24 @@ void ScStwRace::enableAllTimers() {
|
|||
}
|
||||
|
||||
QVariantList ScStwRace::getCurrentStartDelay() {
|
||||
int nextActionDelay = 0;
|
||||
int nextActionDelay = -1;
|
||||
double nextActionDelayProg = -1;
|
||||
|
||||
if(this->state == PREPAIRING || this->state == WAITING) {
|
||||
if(this->state == WAITING && !this->isReadyForNextState()) {
|
||||
// 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();;
|
||||
nextActionDelay = this->startDelayTimer->interval();
|
||||
if(remaining < 0) {
|
||||
remaining = nextActionDelay;
|
||||
}
|
||||
nextActionDelayProg = 1 - (remaining / nextActionDelay);
|
||||
|
||||
if(nextActionDelayProg < 0)
|
||||
nextActionDelayProg = 0;
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -584,10 +601,11 @@ bool ScStwRace::addTimer(ScStwTimer *timer) {
|
|||
this->timers.append(timer);
|
||||
|
||||
connect(timer, &ScStwTimer::stateChanged, this, &ScStwRace::refreshTimerStates);
|
||||
connect(timer, &ScStwTimer::wantsToBeDisabledChanged, this, &ScStwRace::handleTimerWantsToBeDisabledChange);
|
||||
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);
|
||||
|
||||
|
@ -617,12 +635,35 @@ QVariantList ScStwRace::getTimerDetailList() {
|
|||
tmpTimer.insert("reactionTime", timer->getReactionTime());
|
||||
tmpTimer.insert("text", timer->getText());
|
||||
tmpTimer.insert("letter", timer->getLetter());
|
||||
tmpTimer.insert("readyState", timer->getReadyState());
|
||||
tmpTimers.append(tmpTimer);
|
||||
}
|
||||
|
||||
return tmpTimers;
|
||||
}
|
||||
|
||||
QVariantMap ScStwRace::getDetails() {
|
||||
QVariantMap tmpDetails;
|
||||
|
||||
tmpDetails.insert("timers", this->getTimerDetailList());
|
||||
tmpDetails.insert("currentStartDelay", this->getCurrentStartDelay());
|
||||
tmpDetails.insert("competitionMode", this->competitionMode);
|
||||
tmpDetails.insert("readySoundEnabled", this->startSoundSettings[ScStwSoundPlayer::Ready]["Enabled"].toBool());
|
||||
|
||||
if(this->state == WAITING)
|
||||
tmpDetails.insert("isReady", this->isReadyForNextState());
|
||||
|
||||
return tmpDetails;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -39,9 +39,6 @@ bool ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound sound, double volume, d
|
|||
if(!this->soundFiles.contains(sound))
|
||||
return false;
|
||||
|
||||
if(sound > Start || sound < AtYourMarks)
|
||||
return false;
|
||||
|
||||
// stop playback
|
||||
if(this->soundEffect->isPlaying())
|
||||
this->soundEffect->stop();
|
||||
|
@ -76,7 +73,7 @@ bool ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound sound, double volume, d
|
|||
*timeOfStart = this->playingStartedAt;
|
||||
}
|
||||
|
||||
if(sound < 2)
|
||||
if(sound < Start)
|
||||
return this->waitForSoundFinish();
|
||||
|
||||
return true;
|
||||
|
@ -89,20 +86,6 @@ bool ScStwSoundPlayer::cancel(double volume) {
|
|||
// stop playback
|
||||
this->soundEffect->stop();
|
||||
this->waitLoop->quit();
|
||||
|
||||
if(this->currentlyPlayingSound != 2)
|
||||
return true;
|
||||
|
||||
// update volume
|
||||
this->soundEffect->setVolume(volume);
|
||||
|
||||
// load
|
||||
this->soundEffect->setSource(this->soundFiles[FalseStart]["path"].toString());
|
||||
|
||||
// play
|
||||
this->soundEffect->play();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScStwSoundPlayer::waitForSoundFinish(double *timeOfStop) {
|
||||
|
|
Reference in a new issue