2020-04-11 23:41:34 +02:00
|
|
|
#include "../headers/scstwtimer.h"
|
|
|
|
|
2020-04-18 14:25:48 +02:00
|
|
|
ScStwTimer::ScStwTimer(QObject *parent, bool directControlEnabled) : QObject(parent)
|
2020-04-11 23:41:34 +02:00
|
|
|
{
|
2020-04-18 14:25:48 +02:00
|
|
|
this->directControlEnabled = directControlEnabled;
|
2020-04-11 23:41:34 +02:00
|
|
|
this->startTime = 0;
|
|
|
|
this->stopTime = 0;
|
|
|
|
this->reactionTime = 0;
|
2020-04-14 00:08:58 +02:00
|
|
|
|
|
|
|
this->state = IDLE;
|
2020-04-11 23:41:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ScStwTimer::start() {
|
2020-04-14 00:08:58 +02:00
|
|
|
return this->start(QDateTime::currentMSecsSinceEpoch());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScStwTimer::start(double timeOfStart) {
|
2020-04-11 23:41:34 +02:00
|
|
|
switch (this->state) {
|
2020-04-14 00:08:58 +02:00
|
|
|
case IDLE: {
|
|
|
|
// in case of IDLE, start the race!
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-04-14 00:08:58 +02:00
|
|
|
this->startTime = timeOfStart;
|
2020-04-11 23:41:34 +02:00
|
|
|
this->stopTime = 0;
|
|
|
|
|
2020-04-14 00:08:58 +02:00
|
|
|
if(timeOfStart - QDateTime::currentMSecsSinceEpoch() > 0) {
|
|
|
|
this->setState(STARTING);
|
|
|
|
QTimer::singleShot(timeOfStart - QDateTime::currentMSecsSinceEpoch(), [=](){
|
|
|
|
if(this->state == STARTING)
|
|
|
|
this->setState(RUNNING);
|
|
|
|
});
|
|
|
|
QTimer::singleShot(timeOfStart - QDateTime::currentMSecsSinceEpoch() - 1000, [=](){
|
|
|
|
//this->handleClimberStart(QDateTime::currentMSecsSinceEpoch());
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
this->setState(RUNNING);
|
2020-04-11 23:41:34 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
// otherwise the timer is not supposed to be started!
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-14 00:08:58 +02:00
|
|
|
void ScStwTimer::handleClimberStart(double timeOfStart) {
|
|
|
|
this->reactionTime = timeOfStart - this->startTime;
|
|
|
|
qDebug() << "+ [INFO][TIMER] reaction time: " << this->reactionTime;
|
|
|
|
|
|
|
|
if(this->reactionTime <= 0){
|
|
|
|
this->stop(FailStop);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: check if necessary: emit this->reactionTimeChanged();
|
|
|
|
}
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
bool ScStwTimer::cancel() {
|
2020-04-14 00:08:58 +02:00
|
|
|
if(!(this->state == IDLE || this->state == STARTING || this->state == RUNNING))
|
2020-04-11 23:41:34 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
this->setState(CANCELLED);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScStwTimer::stop() {
|
2020-04-15 19:21:32 +02:00
|
|
|
return this->stop(QDateTime::currentMSecsSinceEpoch());
|
2020-04-11 23:41:34 +02:00
|
|
|
}
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
bool ScStwTimer::stop(double timeOfStop) {
|
|
|
|
return this->stop(ManualStop, timeOfStop);
|
2020-04-11 23:41:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ScStwTimer::stop(StopReason reason) {
|
2020-04-15 19:21:32 +02:00
|
|
|
return this->stop(reason, QDateTime::currentMSecsSinceEpoch());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScStwTimer::stop(StopReason reason, double timeOfStop) {
|
2020-04-11 23:41:34 +02:00
|
|
|
if(this->state != STARTING && this->state != RUNNING && this->state != WAITING){
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (reason) {
|
|
|
|
case ManualStop: {
|
|
|
|
if(this->state == STARTING){
|
|
|
|
emit startCanceled(false);
|
|
|
|
this->setState(CANCELLED);
|
|
|
|
}
|
|
|
|
else {
|
2020-04-15 19:21:32 +02:00
|
|
|
this->stopTime = timeOfStop;
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
// trigger an external state refresh to set the state to either WON or LOST depending on the other timers values (see ScStwRace::refreshTimerStates())
|
|
|
|
this->setState(WAITING);
|
2020-04-11 23:41:34 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case FailStop: {
|
2020-04-14 00:08:58 +02:00
|
|
|
qDebug() << "+ [INFO][TIMER] False Start detected: " << "start Time: " << startTime << " reactionTime: " << reactionTime;
|
|
|
|
this->setState(FAILED);
|
2020-04-11 23:41:34 +02:00
|
|
|
|
|
|
|
emit startCanceled(true);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
qDebug() << "+ [INFO][TIMER] Stopped: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << this->getCurrentTime() << " reactionTime: " << reactionTime;
|
2020-04-11 23:41:34 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
bool ScStwTimer::setResult(TimerState result) {
|
|
|
|
if(this->state != WAITING)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case WON:
|
|
|
|
this->setState(WON);
|
|
|
|
return true;
|
|
|
|
case LOST:
|
|
|
|
this->setState(LOST);
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
bool ScStwTimer::reset(){
|
|
|
|
if( this->state < WON || this->state == DISABLED ){
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->startTime = 0;
|
|
|
|
this->stopTime = 0;
|
|
|
|
this->reactionTime = 0;
|
|
|
|
|
|
|
|
this->setState(IDLE);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------
|
|
|
|
// --- helper functions ---
|
|
|
|
// ------------------------
|
|
|
|
|
2020-04-18 14:25:48 +02:00
|
|
|
bool ScStwTimer::setStartTime(double startTime) {
|
|
|
|
if(!this->directControlEnabled)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
this->startTime = startTime;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScStwTimer::setStopTime(double stopTime) {
|
|
|
|
if(!this->directControlEnabled)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
this->stopTime = stopTime;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScStwTimer::setReactionTime(double reactionTime) {
|
|
|
|
if(!this->directControlEnabled)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
this->reactionTime = reactionTime;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScStwTimer::setState(TimerState newState, bool force) {
|
|
|
|
if(!this->directControlEnabled || !force)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
this->setState(newState);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
void ScStwTimer::setState(TimerState newState){
|
|
|
|
if(this->state == DISABLED && newState != IDLE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(this->state != newState) {
|
|
|
|
this->state = newState;
|
|
|
|
qDebug() << "+ [INFO][TIMER] timer state changed: " << newState;
|
|
|
|
emit this->stateChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ScStwTimer::TimerState ScStwTimer::getState() {
|
|
|
|
return this->state;
|
|
|
|
}
|
|
|
|
|
|
|
|
double ScStwTimer::getCurrentTime() {
|
2020-04-15 19:21:32 +02:00
|
|
|
switch (this->state) {
|
|
|
|
case RUNNING:
|
|
|
|
return QDateTime::currentMSecsSinceEpoch() - this->startTime;
|
|
|
|
default: {
|
|
|
|
if(this->state == WAITING || this->state == WON || this->state == LOST)
|
|
|
|
return this->stopTime - this->startTime;
|
|
|
|
else
|
|
|
|
return -1;
|
2020-04-11 23:41:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
double ScStwTimer::getReactionTime() {
|
|
|
|
return this->reactionTime;
|
|
|
|
}
|
|
|
|
|
2020-04-17 19:57:00 +02:00
|
|
|
QString ScStwTimer::getText() {
|
|
|
|
//qDebug() << this->getState();
|
|
|
|
QString newText;
|
|
|
|
switch (this->state) {
|
|
|
|
case ScStwTimer::IDLE:
|
|
|
|
newText = "0.000 sec";
|
|
|
|
break;
|
|
|
|
case ScStwTimer::STARTING:
|
|
|
|
newText = "0.000 sec";
|
|
|
|
break;
|
|
|
|
case ScStwTimer::WAITING:
|
|
|
|
newText = "please wait...";
|
|
|
|
break;
|
|
|
|
case ScStwTimer::RUNNING:
|
|
|
|
newText = QString::number( this->getCurrentTime() / 1000.0, 'f', 3 ) + " sec";
|
|
|
|
break;
|
|
|
|
case ScStwTimer::WON:
|
|
|
|
newText = QString::number( this->getCurrentTime() / 1000.0, 'f', 3 ) + " sec";
|
|
|
|
break;
|
|
|
|
case ScStwTimer::LOST:
|
|
|
|
newText = QString::number( this->getCurrentTime() / 1000.0, 'f', 3 ) + " sec";
|
|
|
|
break;
|
|
|
|
case ScStwTimer::FAILED:
|
|
|
|
newText = "false start";
|
|
|
|
break;
|
|
|
|
case ScStwTimer::CANCELLED:
|
|
|
|
newText = "cancelled";
|
|
|
|
break;
|
|
|
|
case ScStwTimer::DISABLED:
|
|
|
|
newText = "---";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return newText;
|
|
|
|
}
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
void ScStwTimer::setDisabled(bool disabled) {
|
|
|
|
if(disabled)
|
|
|
|
this->setState(DISABLED);
|
|
|
|
else
|
|
|
|
this->setState(IDLE);
|
|
|
|
}
|