diff --git a/ScStwLibraries/headers/client/scstwremoterace.h b/ScStwLibraries/headers/client/scstwremoterace.h index 75488c7..7a3ba79 100644 --- a/ScStwLibraries/headers/client/scstwremoterace.h +++ b/ScStwLibraries/headers/client/scstwremoterace.h @@ -28,7 +28,10 @@ class ScStwRemoteRace : public ScStwRace { Q_OBJECT + Q_PROPERTY(ScStwClient* scStwClient READ getScStwClient WRITE setScStwClient NOTIFY scStwClientChanged) + public: + ScStwRemoteRace(QObject *parent = nullptr); ScStwRemoteRace(ScStwClient *scStwClient, ScStwSettings *settings = nullptr, QObject *parent = nullptr); enum RaceMode { @@ -59,6 +62,9 @@ public slots: bool getIsReadyForNextState(); bool getReadySoundEnabled(); + ScStwClient *getScStwClient(); + void setScStwClient(ScStwClient *client); + private slots: void handleBaseStationSignal(ScStw::SignalKey key, QVariant data); @@ -70,6 +76,9 @@ private slots: void refreshCompetitionMode(); RaceMode getMode(); bool local(); + +signals: + void scStwClientChanged(); }; #endif // SCSTWREMOTEMONITORRACE_H diff --git a/ScStwLibraries/headers/client/scstwremotesettings.h b/ScStwLibraries/headers/client/scstwremotesettings.h index 2b6a9f3..e1515b5 100644 --- a/ScStwLibraries/headers/client/scstwremotesettings.h +++ b/ScStwLibraries/headers/client/scstwremotesettings.h @@ -27,7 +27,10 @@ class ScStwRemoteSettings : public ScStwSettings { Q_OBJECT + Q_PROPERTY(ScStwClient* scStwClient READ getScStwClient WRITE setScStwClient NOTIFY scStwClientChanged) + public: + ScStwRemoteSettings(QObject * parent = nullptr); ScStwRemoteSettings(ScStwClient * scStwClient, QObject * parent = nullptr); enum SettingsMode { @@ -43,10 +46,17 @@ protected: private: ScStwClient * scStwClient; +public slots: + ScStwClient *getScStwClient(); + void setScStwClient(ScStwClient *client); + private slots: void handleClientStateChange(); void handleBaseStationSignal(ScStw::SignalKey key, QVariant data); SettingsMode getMode(); + +signals: + void scStwClientChanged(); }; #endif // SCSTWREMOTESETTINGS_H diff --git a/ScStwLibraries/headers/client/scstwremotetimer.h b/ScStwLibraries/headers/client/scstwremotetimer.h index 71d5992..518140b 100644 --- a/ScStwLibraries/headers/client/scstwremotetimer.h +++ b/ScStwLibraries/headers/client/scstwremotetimer.h @@ -74,7 +74,6 @@ protected slots: */ void setState(TimerState newState); - }; #endif // SCSTWREMOTETIMER_H diff --git a/ScStwLibraries/headers/scstwlibraries.h b/ScStwLibraries/headers/scstwlibraries.h index 1965a70..5435edf 100644 --- a/ScStwLibraries/headers/scstwlibraries.h +++ b/ScStwLibraries/headers/scstwlibraries.h @@ -36,6 +36,7 @@ #include "scstwsetting.h" #include "scstwremoterace.h" #include "scstwclient.h" +#include "scstwremotesettings.h" #endif class ScStwLibraries : public QObject diff --git a/ScStwLibraries/headers/scstwrace.h b/ScStwLibraries/headers/scstwrace.h index 7fc59c9..70cc2b6 100644 --- a/ScStwLibraries/headers/scstwrace.h +++ b/ScStwLibraries/headers/scstwrace.h @@ -59,8 +59,11 @@ class ScStwRace : public QObject Q_PROPERTY(bool competitionMode READ getCompetitionMode NOTIFY competitionModeChanged) Q_PROPERTY(bool readySoundEnabled READ getReadySoundEnabled NOTIFY readySoundEnabledChanged) Q_PROPERTY(QVariantMap details READ getDetails NOTIFY detailsChanged) + Q_PROPERTY(ScStwSettings* settings READ getSettings WRITE setSettings NOTIFY settingsChanged) + Q_PROPERTY(bool autoRefreshTimerText READ getAutoRefreshTimerText WRITE setAutoRefreshTimerText NOTIFY autoRefreshTimerTextChanged) public: + explicit ScStwRace(QObject *parent = nullptr); explicit ScStwRace(ScStwSettings *settings, QObject *parent = nullptr); friend class ScStwRemoteRace; @@ -76,6 +79,7 @@ private: RaceState state; QTimer *startDelayTimer; + QTimer *timerTextRefreshTimer; QEventLoop *startWaitLoop; // sounds @@ -84,6 +88,7 @@ private: // settings ScStwSettings *settings; bool competitionMode; + bool autoRefreshTimerText; enum LoopExitTypes { LoopAutomaticExit = 0, @@ -119,7 +124,7 @@ public slots: virtual ScStw::StatusCode setTimerDisabled(int id, bool disabled); - virtual bool addTimer(ScStwTimer *timer); + Q_INVOKABLE virtual bool addTimer(ScStwTimer *timer); // getters RaceState getState(); @@ -130,6 +135,12 @@ public slots: bool getCompetitionMode(); virtual bool getReadySoundEnabled(); + ScStwSettings* getSettings(); + void setSettings(ScStwSettings* settings); + + bool getAutoRefreshTimerText(); + void setAutoRefreshTimerText(bool autoRefresh); + protected slots: private slots: @@ -171,6 +182,8 @@ signals: void detailsChanged(); void competitionModeChanged(); void readySoundEnabledChanged(); + void settingsChanged(); + void autoRefreshTimerTextChanged(); }; diff --git a/ScStwLibraries/headers/scstwtimer.h b/ScStwLibraries/headers/scstwtimer.h index 9ded219..ccd67b4 100644 --- a/ScStwLibraries/headers/scstwtimer.h +++ b/ScStwLibraries/headers/scstwtimer.h @@ -65,13 +65,16 @@ class ScStwTimer : public QObject { Q_OBJECT public: + + explicit ScStwTimer(QObject *parent = nullptr); + /*! * \brief ScStwTimer constructor * \param parent the parent object * \param directControlEnabled Defines if protected properties (startTimer, stopTime, reactionTime and state) can be directly set from outside. * \param letter the letter of the timer (only first char will be used!) */ - explicit ScStwTimer(QObject *parent = nullptr, QString letter = "" ); + explicit ScStwTimer(QString letter, QObject *parent = nullptr); friend class ScStwRace; diff --git a/ScStwLibraries/sources/client/scstwremoterace.cpp b/ScStwLibraries/sources/client/scstwremoterace.cpp index 6b9140f..9d3912c 100644 --- a/ScStwLibraries/sources/client/scstwremoterace.cpp +++ b/ScStwLibraries/sources/client/scstwremoterace.cpp @@ -18,6 +18,10 @@ #include "scstwremoterace.h" +ScStwRemoteRace::ScStwRemoteRace(QObject* parent) : ScStwRemoteRace(nullptr, nullptr, parent) +{ +} + ScStwRemoteRace::ScStwRemoteRace(ScStwClient *scStwClient, ScStwSettings *settings, QObject *parent) : ScStwRace(settings, parent) { this->isReadyForNextState = true; @@ -25,12 +29,7 @@ ScStwRemoteRace::ScStwRemoteRace(ScStwClient *scStwClient, ScStwSettings *settin this->remoteTimers = {}; this->localTimers = {}; - this->scStwClient = scStwClient; - - this->scStwClient->addSignalSubscription(ScStw::RaceDetailsChanged); - - connect(this->scStwClient, &ScStwClient::stateChanged, this, &ScStwRemoteRace::handleClientStateChange); - connect(this->scStwClient, &ScStwClient::gotSignal, this, &ScStwRemoteRace::handleBaseStationSignal); + this->setScStwClient(scStwClient); } // -------------------------- @@ -146,10 +145,10 @@ void ScStwRemoteRace::handleClientStateChange() { } ScStwRemoteRace::RaceMode ScStwRemoteRace::getMode() { - if(this->scStwClient->getState() == ScStwClient::CONNECTED) - return ScStwRemoteRace::REMOTE; + if(this->scStwClient == nullptr || this->scStwClient->getState() != ScStwClient::CONNECTED) + return LOCAL; else - return ScStwRemoteRace::LOCAL; + return REMOTE; } bool ScStwRemoteRace::local() { @@ -328,3 +327,22 @@ void ScStwRemoteRace::refreshCompetitionMode() { if(this->local()) return ScStwRace::refreshCompetitionMode(); } + +ScStwClient* ScStwRemoteRace::getScStwClient() { + return this->scStwClient; +} + +void ScStwRemoteRace::setScStwClient(ScStwClient* client) { + if(client == this->scStwClient) + return; + + this->scStwClient = client; + + if(this->scStwClient != nullptr) { + this->scStwClient->addSignalSubscription(ScStw::RaceDetailsChanged); + + connect(this->scStwClient, &ScStwClient::stateChanged, this, &ScStwRemoteRace::handleClientStateChange); + connect(this->scStwClient, &ScStwClient::gotSignal, this, &ScStwRemoteRace::handleBaseStationSignal); + + } +} diff --git a/ScStwLibraries/sources/client/scstwremotesettings.cpp b/ScStwLibraries/sources/client/scstwremotesettings.cpp index aaecf45..4a63c5d 100644 --- a/ScStwLibraries/sources/client/scstwremotesettings.cpp +++ b/ScStwLibraries/sources/client/scstwremotesettings.cpp @@ -18,19 +18,21 @@ #include "../../headers/client/scstwremotesettings.h" +ScStwRemoteSettings::ScStwRemoteSettings(QObject* parent) : ScStwSettings(parent) +{ + this->scStwClient = nullptr; +} + ScStwRemoteSettings::ScStwRemoteSettings(ScStwClient * scStwClient, QObject * parent) : ScStwSettings(parent) { - this->scStwClient = scStwClient; - this->scStwClient->addSignalSubscription(ScStw::SettingChanged); - - connect(this->scStwClient, &ScStwClient::gotSignal, this, &ScStwRemoteSettings::handleBaseStationSignal); + this->setScStwClient(scStwClient); } ScStwRemoteSettings::SettingsMode ScStwRemoteSettings::getMode() { - if(this->scStwClient->getState() == ScStwClient::CONNECTED) - return ScStwRemoteSettings::REMOTE; + if(this->scStwClient == nullptr || this->scStwClient->getState() != ScStwClient::CONNECTED) + return LOCAL; else - return ScStwRemoteSettings::LOCAL; + return REMOTE; } QVariant ScStwRemoteSettings::readSetting(QString key, int keyInt, int keyLevel) { @@ -76,3 +78,20 @@ void ScStwRemoteSettings::handleBaseStationSignal(ScStw::SignalKey key, QVariant break; } } + +ScStwClient* ScStwRemoteSettings::getScStwClient() { + return this->scStwClient; +} + +void ScStwRemoteSettings::setScStwClient(ScStwClient* client) { + if(client == this->scStwClient) + return; + + this->scStwClient = client; + + if(this->scStwClient != nullptr) { + this->scStwClient->addSignalSubscription(ScStw::SettingChanged); + + connect(this->scStwClient, &ScStwClient::gotSignal, this, &ScStwRemoteSettings::handleBaseStationSignal); + } +} diff --git a/ScStwLibraries/sources/scstwlibraries.cpp b/ScStwLibraries/sources/scstwlibraries.cpp index 08ba19d..64696c8 100644 --- a/ScStwLibraries/sources/scstwlibraries.cpp +++ b/ScStwLibraries/sources/scstwlibraries.cpp @@ -30,13 +30,15 @@ void ScStwLibraries::init() { qRegisterMetaType("ScStw::SocketCommand"); qRegisterMetaType("ScStw::StatusCode"); - qmlRegisterUncreatableType("de.itsblue.ScStw", 2, 0, "ScStwRace", "ScStwRace is not creatable"); + qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwRace"); qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwTimer"); #ifdef ScStwLibraries_ClientLibs qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwClient"); qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwSettings"); qmlRegisterUncreatableType("de.itsblue.ScStw", 2, 0, "ScStwSetting", "The ScStwSetting is manage by a ScStwSettings instance and therefore not creatable"); + qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwRemoteRace"); + qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwRemoteSettings"); #endif #endif diff --git a/ScStwLibraries/sources/scstwrace.cpp b/ScStwLibraries/sources/scstwrace.cpp index 0880a2c..2d91318 100644 --- a/ScStwLibraries/sources/scstwrace.cpp +++ b/ScStwLibraries/sources/scstwrace.cpp @@ -18,10 +18,15 @@ #include "../headers/scstwrace.h" +ScStwRace::ScStwRace(QObject* parent) : ScStwRace(nullptr, parent) +{ +} + ScStwRace::ScStwRace(ScStwSettings *settings, QObject *parent) : QObject(parent) { this->state = IDLE; this->competitionMode = false; + this->autoRefreshTimerText = false; // configure the loop that waits for the sound effect to finish this->soundPlayer = new ScStwSoundPlayer(); @@ -38,8 +43,7 @@ ScStwRace::ScStwRace(ScStwSettings *settings, QObject *parent) : QObject(parent) connect(this, &ScStwRace::stateChanged, this, &ScStwRace::detailsChanged); // init settings - this->settings = settings; - this->refreshCompetitionMode(); + this->setSettings(settings); } // -------------------------- @@ -624,7 +628,10 @@ void ScStwRace::refreshCompetitionMode() { if(this->state != IDLE) return; - bool currentCompetitionMode = this->settings->readSetting(ScStwSettings::CompetitionModeSetting).toBool(); + bool currentCompetitionMode = false; + + if(this->settings != nullptr) + currentCompetitionMode = this->settings->readSetting(ScStwSettings::CompetitionModeSetting).toBool(); if(this->competitionMode != currentCompetitionMode) { @@ -734,6 +741,9 @@ QList ScStwRace::getTimers() { } double ScStwRace::getSoundVolume() { + if(this->settings == nullptr) + return 1; + return this->settings->readSetting(ScStwSettings::SoundVolumeSetting).toDouble(); } @@ -769,6 +779,9 @@ bool ScStwRace::getSoundEnabledSetting(ScStwSoundPlayer::StartSound sound) { return false; } + if(this->settings == nullptr) + return false; + return this->settings->readSetting(soundEnabledSetting).toBool(); } @@ -788,6 +801,9 @@ int ScStwRace::getSoundDelaySetting(ScStwSoundPlayer::StartSound sound) { return -1; } + if(this->settings == nullptr) + return -1; + return this->settings->readSetting(soundDelaySetting).toInt(); } @@ -836,3 +852,53 @@ bool ScStwRace::getCompetitionMode() { bool ScStwRace::getReadySoundEnabled() { return this->getSoundEnabledSetting(ScStwSoundPlayer::Ready); } + +ScStwSettings* ScStwRace::getSettings() { + return this->settings; +} + +void ScStwRace::setSettings(ScStwSettings* settings) { + if(settings == this->settings) + return; + + this->settings = settings; + this->refreshCompetitionMode(); + emit this->settingsChanged(); +} + +bool ScStwRace::getAutoRefreshTimerText() { + return this->autoRefreshTimerText; +} + +void ScStwRace::setAutoRefreshTimerText(bool autoRefresh) { + if(autoRefresh == this->autoRefreshTimerText) + return; + + this->autoRefreshTimerText = autoRefresh; + + if(this->autoRefreshTimerText) { + this->timerTextRefreshTimer = new QTimer(this); + this->timerTextRefreshTimer->setInterval(1); + this->timerTextRefreshTimer->connect( + this->timerTextRefreshTimer, + &QTimer::timeout, + [=]{ + // refresh timer text + if(this->getState() == ScStwRace::RUNNING) { + emit this->timersChanged(); + } + + // refresh next start action delay progress + if(this->getState() == ScStwRace::WAITING || this->getState() == ScStwRace::PREPAIRING) { + emit this->currentStartDelayChanged(); + } + } + ); + this->timerTextRefreshTimer->start(); + } + else if(this->timerTextRefreshTimer != nullptr) { + this->timerTextRefreshTimer->deleteLater(); + } + + emit this->autoRefreshTimerTextChanged(); +} diff --git a/ScStwLibraries/sources/scstwtimer.cpp b/ScStwLibraries/sources/scstwtimer.cpp index 01c0b02..0744a66 100644 --- a/ScStwLibraries/sources/scstwtimer.cpp +++ b/ScStwLibraries/sources/scstwtimer.cpp @@ -18,7 +18,11 @@ #include "../headers/scstwtimer.h" -ScStwTimer::ScStwTimer(QObject *parent, QString letter) : QObject(parent) +ScStwTimer::ScStwTimer(QObject* parent) : ScStwTimer("", parent) +{ +} + +ScStwTimer::ScStwTimer(QString letter, QObject *parent) : QObject(parent) { if(letter.length() > 1) this->letter = letter[0];