- remote race now switches to a local race when the client is not connected automatically
- fixed some issues
This commit is contained in:
parent
da97e671a5
commit
8c74521477
5 changed files with 107 additions and 40 deletions
|
@ -29,33 +29,43 @@ class ScStwRemoteRace : public ScStwRace
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ScStwRemoteRace(ScStwClient *monitorClient, QObject *parent = nullptr);
|
ScStwRemoteRace(ScStwClient *scStwClient, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
enum RaceMode {
|
||||||
|
LOCAL,
|
||||||
|
REMOTE
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double currentStartTotalDelay;
|
double currentStartTotalDelay;
|
||||||
double currentStartDelayStartedAt;
|
double currentStartDelayStartedAt;
|
||||||
double latestStartDelayProgress;
|
double latestStartDelayProgress;
|
||||||
bool isReadyForNextState;
|
bool isReadyForNextState;
|
||||||
|
bool readySoundEnabled;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScStwClient *scStwClient;
|
ScStwClient *scStwClient;
|
||||||
QList<ScStwRemoteTimer*> remoteTimers;
|
QList<ScStwRemoteTimer*> remoteTimers;
|
||||||
|
QList<ScStwTimer*> localTimers;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ScStw::StatusCode start(bool);
|
ScStw::StatusCode start(bool asyncronous = true);
|
||||||
ScStw::StatusCode start();
|
|
||||||
ScStw::StatusCode cancel();
|
ScStw::StatusCode cancel();
|
||||||
ScStw::StatusCode stop();
|
ScStw::StatusCode stop();
|
||||||
ScStw::StatusCode reset();
|
ScStw::StatusCode reset();
|
||||||
bool addTimer(ScStwTimer *timer);
|
bool addTimer(ScStwTimer *timer);
|
||||||
QVariantMap getCurrentStartDelay();
|
QVariantMap getCurrentStartDelay();
|
||||||
bool getIsReadyForNextState();
|
bool getIsReadyForNextState();
|
||||||
|
bool getReadySoundEnabled();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleClientStateChanged();
|
|
||||||
void handleBaseStationSignal(ScStw::SignalKey key, QVariant data);
|
void handleBaseStationSignal(ScStw::SignalKey key, QVariant data);
|
||||||
bool refreshRemoteTimers(QVariantList remoteTimers);
|
bool refreshRemoteTimers(QVariantList remoteTimers);
|
||||||
|
void rebuildRemoteTimers(QVariantList remoteTimers);
|
||||||
void refreshDetails(QVariantMap details);
|
void refreshDetails(QVariantMap details);
|
||||||
|
void handleClientStateChange();
|
||||||
|
RaceMode getMode();
|
||||||
|
bool local();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,11 +43,10 @@ protected:
|
||||||
private:
|
private:
|
||||||
ScStwClient * scStwClient;
|
ScStwClient * scStwClient;
|
||||||
|
|
||||||
SettingsMode getMode();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleClientStateChange();
|
void handleClientStateChange();
|
||||||
void handleBaseStationSignal(ScStw::SignalKey key, QVariant data);
|
void handleBaseStationSignal(ScStw::SignalKey key, QVariant data);
|
||||||
|
SettingsMode getMode();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SCSTWREMOTESETTINGS_H
|
#endif // SCSTWREMOTESETTINGS_H
|
||||||
|
|
|
@ -137,7 +137,7 @@ public slots:
|
||||||
QVariantList getTimerDetailList();
|
QVariantList getTimerDetailList();
|
||||||
QVariantMap getDetails();
|
QVariantMap getDetails();
|
||||||
bool getCompetitionMode();
|
bool getCompetitionMode();
|
||||||
bool getReadySoundEnabled();
|
virtual bool getReadySoundEnabled();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,15 @@
|
||||||
|
|
||||||
#include "scstwremoterace.h"
|
#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->isReadyForNextState = true;
|
||||||
|
|
||||||
this->scStwClient = monitorClient;
|
this->scStwClient = scStwClient;
|
||||||
|
|
||||||
this->scStwClient->addSignalSubscription(ScStw::RaceDetailsChanged);
|
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);
|
connect(this->scStwClient, &ScStwClient::gotSignal, this, &ScStwRemoteRace::handleBaseStationSignal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +34,10 @@ ScStwRemoteRace::ScStwRemoteRace(ScStwClient *monitorClient, QObject *parent) :
|
||||||
// --- Main Functionality ---
|
// --- Main Functionality ---
|
||||||
// --------------------------
|
// --------------------------
|
||||||
|
|
||||||
ScStw::StatusCode ScStwRemoteRace::start(bool) {
|
ScStw::StatusCode ScStwRemoteRace::start(bool asyncronous) {
|
||||||
return this->start();
|
if(this->local())
|
||||||
}
|
return ScStwRace::start(asyncronous);
|
||||||
|
|
||||||
ScStw::StatusCode ScStwRemoteRace::start() {
|
|
||||||
if(this->getState() != ScStwRace::IDLE && this->getState() != ScStwRace::WAITING)
|
if(this->getState() != ScStwRace::IDLE && this->getState() != ScStwRace::WAITING)
|
||||||
return ScStw::CurrentStateNotVaildForOperationError;
|
return ScStw::CurrentStateNotVaildForOperationError;
|
||||||
|
|
||||||
|
@ -51,6 +49,9 @@ ScStw::StatusCode ScStwRemoteRace::start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScStw::StatusCode ScStwRemoteRace::cancel() {
|
ScStw::StatusCode ScStwRemoteRace::cancel() {
|
||||||
|
if(this->local())
|
||||||
|
return ScStwRace::cancel();
|
||||||
|
|
||||||
if(this->getState() != PREPAIRING && this->getState() != WAITING && this->getState() != STARTING && this->getState() != RUNNING)
|
if(this->getState() != PREPAIRING && this->getState() != WAITING && this->getState() != STARTING && this->getState() != RUNNING)
|
||||||
return ScStw::CurrentStateNotVaildForOperationError;
|
return ScStw::CurrentStateNotVaildForOperationError;
|
||||||
|
|
||||||
|
@ -62,6 +63,9 @@ ScStw::StatusCode ScStwRemoteRace::cancel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScStw::StatusCode ScStwRemoteRace::stop() {
|
ScStw::StatusCode ScStwRemoteRace::stop() {
|
||||||
|
if(this->local())
|
||||||
|
return ScStwRace::stop();
|
||||||
|
|
||||||
if(this->getState() != ScStwRace::RUNNING && this->getState() != ScStwRace::STARTING)
|
if(this->getState() != ScStwRace::RUNNING && this->getState() != ScStwRace::STARTING)
|
||||||
return ScStw::CurrentStateNotVaildForOperationError;
|
return ScStw::CurrentStateNotVaildForOperationError;
|
||||||
|
|
||||||
|
@ -73,6 +77,9 @@ ScStw::StatusCode ScStwRemoteRace::stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScStw::StatusCode ScStwRemoteRace::reset() {
|
ScStw::StatusCode ScStwRemoteRace::reset() {
|
||||||
|
if(this->local())
|
||||||
|
return ScStwRace::reset();
|
||||||
|
|
||||||
if(this->getState() != ScStwRace::STOPPED && this->getState() != ScStwRace::INCIDENT)
|
if(this->getState() != ScStwRace::STOPPED && this->getState() != ScStwRace::INCIDENT)
|
||||||
return ScStw::CurrentStateNotVaildForOperationError;
|
return ScStw::CurrentStateNotVaildForOperationError;
|
||||||
|
|
||||||
|
@ -88,18 +95,41 @@ ScStw::StatusCode ScStwRemoteRace::reset() {
|
||||||
// --- Base Station sync ---
|
// --- Base Station sync ---
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
void ScStwRemoteRace::handleClientStateChanged() {
|
void ScStwRemoteRace::handleClientStateChange() {
|
||||||
// TODO
|
|
||||||
switch (this->scStwClient->getState()) {
|
switch (this->scStwClient->getState()) {
|
||||||
case ScStwClient::CONNECTED:
|
case ScStwClient::CONNECTED:
|
||||||
break;
|
this->localTimers.clear();
|
||||||
default:
|
this->localTimers = this->timers;
|
||||||
this->timers.clear();
|
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);
|
this->setState(IDLE);
|
||||||
break;
|
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
|
* @brief ScStwAppBackend::handleBaseStationUpdate
|
||||||
*
|
*
|
||||||
|
@ -134,8 +164,8 @@ void ScStwRemoteRace::refreshDetails(QVariantMap details) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ready sound enabled
|
// ready sound enabled
|
||||||
if(this->getReadySoundEnabled() != details["readySoundEnabled"].toBool()) {
|
if(this->readySoundEnabled != details["readySoundEnabled"].toBool()) {
|
||||||
this->writeStartSoundSetting(ScStwSoundPlayer::Ready, details["readySoundEnabled"].toBool(), 0);
|
this->readySoundEnabled = details["readySoundEnabled"].toBool();
|
||||||
emit this->readySoundEnabledChanged();
|
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) {
|
bool ScStwRemoteRace::refreshRemoteTimers(QVariantList remoteTimers) {
|
||||||
|
|
||||||
if(remoteTimers.length() != this->timers.length()){
|
if(remoteTimers.length() != this->remoteTimers.length()){
|
||||||
// local timers are out of sync
|
// local timers are out of sync
|
||||||
|
this->rebuildRemoteTimers(remoteTimers);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(QVariant remoteTimer, remoteTimers){
|
foreach(QVariant remoteTimer, remoteTimers){
|
||||||
int currId = remoteTimer.toMap()["id"].toInt();
|
int currId = remoteTimer.toMap()["id"].toInt();
|
||||||
|
|
||||||
|
if(this->remoteTimers.length() <= currId)
|
||||||
|
this->rebuildRemoteTimers(remoteTimers);
|
||||||
|
|
||||||
ScStwTimer::TimerState newState = ScStwTimer::TimerState(remoteTimer.toMap()["state"].toInt());
|
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();
|
double currentMSecsSinceEpoch = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
|
||||||
|
@ -206,11 +243,15 @@ bool ScStwRemoteRace::refreshRemoteTimers(QVariantList remoteTimers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScStwRemoteRace::addTimer(ScStwTimer* timer) {
|
bool ScStwRemoteRace::addTimer(ScStwTimer* timer) {
|
||||||
Q_UNUSED(timer)
|
if(this->local())
|
||||||
|
return ScStwRace::addTimer(timer);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap ScStwRemoteRace::getCurrentStartDelay() {
|
QVariantMap ScStwRemoteRace::getCurrentStartDelay() {
|
||||||
|
if(this->local())
|
||||||
|
return ScStwRace::getCurrentStartDelay();
|
||||||
|
|
||||||
QVariantMap currentStartDelay = {
|
QVariantMap currentStartDelay = {
|
||||||
{"total", -1.0},
|
{"total", -1.0},
|
||||||
|
@ -234,5 +275,15 @@ QVariantMap ScStwRemoteRace::getCurrentStartDelay() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScStwRemoteRace::getIsReadyForNextState() {
|
bool ScStwRemoteRace::getIsReadyForNextState() {
|
||||||
|
if(this->local())
|
||||||
|
return ScStwRace::getIsReadyForNextState();
|
||||||
|
|
||||||
return this->isReadyForNextState;
|
return this->isReadyForNextState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScStwRemoteRace::getReadySoundEnabled() {
|
||||||
|
if(this->local())
|
||||||
|
return ScStwRace::getReadySoundEnabled();
|
||||||
|
|
||||||
|
return this->readySoundEnabled;
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ ScStwTimer::ScStwTimer(QObject *parent, QString letter) : QObject(parent)
|
||||||
else
|
else
|
||||||
this->letter = letter;
|
this->letter = letter;
|
||||||
|
|
||||||
|
qDebug() << "Timer created with letter: " << letter;
|
||||||
|
|
||||||
this->startTime = 0;
|
this->startTime = 0;
|
||||||
this->stopTime = 0;
|
this->stopTime = 0;
|
||||||
this->reactionTime = 0;
|
this->reactionTime = 0;
|
||||||
|
@ -86,6 +88,9 @@ bool ScStwTimer::cancel() {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
qDebug() << "[INFO][TIMER] Timer was cancelled";
|
qDebug() << "[INFO][TIMER] Timer was cancelled";
|
||||||
|
this->reactionTime = 0;
|
||||||
|
this->startTime = 0;
|
||||||
|
this->stopTime = 0;
|
||||||
|
|
||||||
this->setState(CANCELLED);
|
this->setState(CANCELLED);
|
||||||
return true;
|
return true;
|
||||||
|
@ -213,6 +218,8 @@ QString ScStwTimer::getLetter() {
|
||||||
|
|
||||||
QString ScStwTimer::getText() {
|
QString ScStwTimer::getText() {
|
||||||
|
|
||||||
|
qDebug() << "getting text: start time: " << this->startTime << " state: " << this->state;
|
||||||
|
|
||||||
QString newText = "";
|
QString newText = "";
|
||||||
int newTime = 0;
|
int newTime = 0;
|
||||||
switch (this->state) {
|
switch (this->state) {
|
||||||
|
|
Reference in a new issue