From 34f9d0f08e5a181b43e0e06957a531fa273dac79 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Sun, 14 Oct 2018 18:39:39 +0200 Subject: [PATCH] continued to implement the base station connection --- headers/baseconn.h | 41 ++++++- headers/buzzerconn.h | 1 + headers/speedtimer.h | 9 +- headers/speedtimerqmladapter.h | 52 +++++++++ qml/ProfilesDialog.qml | 1 + qml/SettingsDialog.qml | 2 +- qml/SpeedTimer.qml | 122 ++++---------------- qml/main.qml | 74 +++++++----- sources/baseconn.cpp | 188 ++++++++++++++++++++++++------- sources/main.cpp | 2 + sources/speedtimer.cpp | 49 ++++++-- sources/speedtimerqmladapter.cpp | 96 ++++++++++++++++ speedclimbing_stopwatch.pro | 6 +- 13 files changed, 460 insertions(+), 183 deletions(-) create mode 100644 headers/speedtimerqmladapter.h create mode 100644 sources/speedtimerqmladapter.cpp diff --git a/headers/baseconn.h b/headers/baseconn.h index 086cde9..e3fed20 100644 --- a/headers/baseconn.h +++ b/headers/baseconn.h @@ -8,6 +8,10 @@ #include #include #include +#include +#include +#include +#include #include "headers/appsettings.h" #include "headers/speedtimer.h" @@ -20,6 +24,8 @@ class BaseConn : public QObject Q_PROPERTY(QString state READ getState NOTIFY stateChanged) Q_PROPERTY(int progress READ getProgress NOTIFY progressChanged) Q_PROPERTY(QStringList connections READ getConnections NOTIFY connectionsChanged) + Q_PROPERTY(QString nextRemoteAction READ getNextRemoteAction NOTIFY nextRemoteActionChanged) + Q_PROPERTY(float nextRemoteActionDelayProg READ getNextRemoteActionDelayProg NOTIFY nextRemoteActionDelayProgChanged) public: explicit BaseConn(QObject *parent = nullptr); @@ -53,6 +59,23 @@ private: QList speedTimers; + QTimer *refreshTimer; + QSemaphore remoteSessions; + + int nextConnectionId; + + struct waitingRequest { + int id; + QEventLoop * loop; + QString reply; + }; + + QList waitingRequests; + + QString nextRemoteAction; + + float nextRemoteActionDelayProg; + signals: void stateChanged(); //is emitted, when the connection state changes @@ -60,10 +83,16 @@ signals: void progressChanged(); //is emmited during the connection process when the progress changes - void gotReply(); + void gotUnexpectedReply(QString reply); void connectionsChanged(); + void connectionSlotReleased(); + + void nextRemoteActionChanged(); + + void nextRemoteActionDelayProgChanged(); + public slots: Q_INVOKABLE bool connectToHost(); @@ -77,7 +106,7 @@ public slots: bool startTimers(); - bool stopTimers(); + bool stopTimers(QString type); bool resetTimers(); @@ -92,12 +121,12 @@ public slots: QStringList getConnections(); + QString getNextRemoteAction(); + + float getNextRemoteActionDelayProg(); + private slots: void readyRead(); - -private: - QTimer *refreshTimer; - QSemaphore remoteSessions; }; #endif // BASECONN_H diff --git a/headers/buzzerconn.h b/headers/buzzerconn.h index da68784..13eeece 100644 --- a/headers/buzzerconn.h +++ b/headers/buzzerconn.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "appsettings.h" diff --git a/headers/speedtimer.h b/headers/speedtimer.h index c0cad99..8e2e339 100644 --- a/headers/speedtimer.h +++ b/headers/speedtimer.h @@ -22,6 +22,8 @@ public: double stoppedTime; double reactionTime; + bool remoteControlled; + signals: void stateChanged(timerState newState); void startCanceled(bool falseStart); @@ -35,11 +37,14 @@ public slots: QString getState(); double getCurrTime(); - void handleStartpadTrigger(); - void handleToppadTrigger(); + //void handleStartpadTrigger(); + //void handleToppadTrigger(); + + //helper functions void delay(int mSecs); + timerState stateFromString(QString state); private: QDateTime *date; }; diff --git a/headers/speedtimerqmladapter.h b/headers/speedtimerqmladapter.h new file mode 100644 index 0000000..c216fb7 --- /dev/null +++ b/headers/speedtimerqmladapter.h @@ -0,0 +1,52 @@ +#ifndef SPEEDTIMERQMLADAPTER_H +#define SPEEDTIMERQMLADAPTER_H + +#include +#include +#include "speedtimer.h" + +class SpeedTimerQmlAdapter : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString state READ getState NOTIFY stateChanged) + //Q_PROPERTY(int currtime READ getCurrTime) + Q_PROPERTY(QString text READ getText NOTIFY textChanged) + +public: + explicit SpeedTimerQmlAdapter(QObject *parent = nullptr); + + SpeedTimer::timerState state; + + // variables for capturing the time + double startTime; + double stopTime; + double stoppedTime; + double reactionTime; + + QString text; + +signals: + void stateChanged(SpeedTimer::timerState newState); + Q_SIGNAL void startCanceled(bool falseStart); + void textChanged(); + +public slots: + Q_INVOKABLE bool setStarting(); + Q_INVOKABLE bool start(); + Q_INVOKABLE bool stop(QString type); + Q_INVOKABLE bool reset(); + + void setState(SpeedTimer::timerState newState); + Q_INVOKABLE QString getState(); + Q_INVOKABLE QString getText(); + +// double getCurrTime(); + +private: + QTimer * refreshTimer; + +private slots: + void refreshValues(); +}; + +#endif // SPEEDTIMERQMLADAPTER_H diff --git a/qml/ProfilesDialog.qml b/qml/ProfilesDialog.qml index e0321a2..203675a 100644 --- a/qml/ProfilesDialog.qml +++ b/qml/ProfilesDialog.qml @@ -21,6 +21,7 @@ import QtQuick.Window 2.2 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import com.itsblue.speedclimbingstopwatch 1.0 +import "./components/ProgressCircle.qml" Popup { diff --git a/qml/SettingsDialog.qml b/qml/SettingsDialog.qml index 1f4b77b..a7168db 100644 --- a/qml/SettingsDialog.qml +++ b/qml/SettingsDialog.qml @@ -72,7 +72,7 @@ Popup { Label { id: head_text text: options_stack.currentItem.title - font.pixelSize: headlineUnderline.width * 0.1 + font.pixelSize: headlineUnderline.width * 0.05 color: enabled ? StyleSettings.textColor:StyleSettings.disabledTextColor anchors { horizontalCenter: parent.horizontalCenter diff --git a/qml/SpeedTimer.qml b/qml/SpeedTimer.qml index 1027cc4..84c1ba9 100644 --- a/qml/SpeedTimer.qml +++ b/qml/SpeedTimer.qml @@ -5,6 +5,7 @@ import QtQuick.Controls 2.2 import "." import "./components" import "./styles" +import com.itsblue.speedclimbingstopwatch 1.0 Item { id: control @@ -27,19 +28,20 @@ Item { signal stopped() signal startCanceled(bool falseStart) + signal stateChanged(var newState) anchors.fill: parent state: "IDLE" Label { id: time - text: parent.text + text: timerBackend.state === "STARTING" ? control.text:timerBackend.text scale: parent.scale anchors.centerIn: parent font.pixelSize: parent.pixelSize elide: parent.elide color: StyleSettings.textColor Behavior on text { - enabled: control.state !== "RUNNING" + enabled: timerBackend.state !== "RUNNING" FadeAnimation { target: time } @@ -47,74 +49,38 @@ Item { } + SpeedTimerBackend { + id: timerBackend + + onStateChanged: { + control.stateChanged(newState) + } + + onStartCanceled: { + console.log("start cnaceled") + control.startCanceled(falseStart) + } + } + + function getState(){ + return(timerBackend.getState()) + } + function setStarting(){ - control.state = "STARTING" + timerBackend.setStarting() } function start(inMilliSeconds){ - - control.state = "STARTING" - control.startTime = new Date().getTime() + inMilliSeconds //set the startime to be 0 after the starttone - startTimer.interval = inMilliSeconds startTimer.start() } function stop(type){ - //_cppStartpadConn.appendCommand("SET_LED_STARTING"); - switch(type){ - case "toppad": - //the buzzer was pushed - control.stopTime = control.toppadConn.lastTriggered + control.toppadConn.offset - control.stoppedTime = control.stopTime - control.startTime - control.stopped() - //time.text = ( root.stoppedTime / 1000 ).toFixed(3) + " sec" - //console.log("STOPPED: "+control.stoppedTime + " started at: " + control.startTime + " offset: "+ control.buzzer_offset + "lastpressed: " + control.last_button_pressed) - break - case "manual": - //the stop button was pressed - if(baseConn.state === "connected"){ - control.stoppedTime = baseConn.getTime("raw") - time.text = (control.stoppedTime / 1000).toFixed(3) + " sec" - return - } - control.stopTime = new Date().getTime() - control.stoppedTime = control.stopTime - control.startTime - control.stopped() - break - case "false": - //there was a false start - control.stoppedTime = -1 - startTimer.stop() - control.state = "STOPPED" - control.startCanceled(true) - break - case "cancel": - //the cancel button was pressed - control.stoppedTime = 0 - startTimer.stop() - control.state = "STOPPED" - control.startCanceled(false) - break - } - control.state = "STOPPED" + timerBackend.stop(type) } function reset(){ - - control.startTime = 0 - control.stopTime = 0 - control.stoppedTime = 0 - - if(baseConn.state === "connected"){ - var ret = baseConn.sendCommand("CMD_RESET_TIMER") - if(ret !== "OK"){ - control.state = "IDLE" - return - } - } - - control.state = "IDLE" + timerBackend.reset() } function handleStartpad(){ @@ -138,46 +104,8 @@ Item { running: false repeat: false onTriggered: { + timerBackend.start() console.log("started") - control.state = "RUNNING" } } - - Timer { - //timer that updates the currTime variable - running: true - repeat: true - interval: 1 - onTriggered: { - control.currTime = new Date().getTime() - } - } - - - states: [ - State { - name: "IDLE" - //state for the start page - PropertyChanges { target: time; text: qsTr("Click start to start");} - }, - State { - name: "STARTING" - //state for the start sequence - PropertyChanges { target: time; text: control.text;} - }, - State { - name: "RUNNING" - //state when the timer is running - PropertyChanges { target: time; text: Math.abs( ( ( control.currTime - control.startTime ) / 1000 ) ).toFixed(3) + " sec";} - }, - - State { - name: "STOPPED" - //state when the meassuring is over - PropertyChanges { - target: time; - text: control.stoppedTime >= 0 ? ( control.stoppedTime / 1000 ).toFixed(3) + " sec":qsTr("false start"); - } - } - ] } diff --git a/qml/main.qml b/qml/main.qml index cbf274a..604bb75 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -119,25 +119,34 @@ Window { BaseStationConn { id: baseConn - ipAdress: "localhost"//"raspberrypi.local" + ipAdress: "raspberrypi.local" property var status: {'status': baseConn.state, 'progress': baseConn.progress, 'connections': baseConn.connections} + onNextRemoteActionChanged: { + switch(nextRemoteAction){ + case "at_marks": + timer_1.text = "at your\nmarks" + break + case "ready": + timer_1.text = "ready" + break + case "start": + timer_1.text = "0.000 sec" + break + } + } - function getTime(type){ - var time = parseInt(sendCommand("GET_CURRTIME")) - if(type === "readable"){ - return(time / 1000).toFixed(3) - } - else if(type === "raw"){ - return(time) - } + onNextRemoteActionDelayProgChanged: { + console.log(nextRemoteActionDelayProg) + prog.progress = baseConn.nextRemoteActionDelayProg * 100 + console.log(prog.progress) } } Timer { id: baseRefreshTimer - running: baseConn.state === "connected" + running: false repeat: false interval: 1 @@ -328,6 +337,11 @@ Window { text: "0.000 sec" + onStateChanged: { + console.log(newState) + root.state = timer_1.getState() + } + onStopped: { root.state = "STOPPED" } @@ -473,6 +487,9 @@ Window { arcEnd: baseConn.state !== "connected" ? 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval) :(360/100) * progress colorCircle: "grey" + onProgressChanged: { + console.log(progress) + } animationDuration: baseConn.state === "connected" ? 150:0 @@ -482,6 +499,7 @@ Window { interval: 1 repeat: true onTriggered: { + console.log("prog refresh timer") prog.arcEnd = 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval) } } @@ -776,16 +794,10 @@ Window { /*----Functions to control the stopwatch----*/ function start(){ if(baseConn.state === "connected"){ - var ret = baseConn.sendCommand("CMD_START_TIMER") - if(ret === "OK"){ - root.state = "STARTING" - timer_1.setStarting() - return - } + baseConn.startTimers() + return; } - - root.state = "STARTING" timer_1.setStarting() if(_cppAppSettings.loadSetting("at_marks_en") === "true"){ next_actionTimer.action = "at_marks" @@ -804,22 +816,30 @@ Window { } function stop(type){ - if(type === "manual" || type === "cancel"){ - if(baseConn.state === "connected"){ - baseConn.sendCommand("CMD_STOP_TIMER") - } + if(baseConn.state === "connected"){ + baseConn.stopTimers(type) } - root.state = "STOPPED" - timer_1.stop(type) + else { + timer_1.stop(type) + } + + if(type === "manual" || type === "cancel"){ + + } + //root.state = "STOPPED" + //timer_1.stop(type) } function reset(){ if(baseConn.state === "connected"){ - baseConn.sendCommand("CMD_RESET_TIMER") + baseConn.resetTimers() + } + else { + timer_1.reset() } - timer_1.reset() - root.state = "IDLE" + // + //root.state = "IDLE" } } } diff --git a/sources/baseconn.cpp b/sources/baseconn.cpp index 30e5bc8..c7f2822 100644 --- a/sources/baseconn.cpp +++ b/sources/baseconn.cpp @@ -4,7 +4,9 @@ BaseConn::BaseConn(QObject *parent) : QObject(parent) { socket = new QTcpSocket(); this->setState("disconnected"); - remoteSessions.release(2); + remoteSessions.release(1); + + this->nextConnectionId = 1; this->speedTimers.append(pGlobalSpeedTimer); @@ -12,6 +14,7 @@ BaseConn::BaseConn(QObject *parent) : QObject(parent) refreshTimer->setInterval(1); refreshTimer->setSingleShot(true); refreshTimer->connect(this->refreshTimer, &QTimer::timeout, this, &BaseConn::refreshTimers); + refreshTimer->start(); } bool BaseConn::connectToHost() { @@ -48,6 +51,7 @@ bool BaseConn::connectToHost() { connect(this->socket, &QTcpSocket::readyRead, this, &BaseConn::readyRead); this->connection_progress = 100; setState("connected"); + this->speedTimers[0]->remoteControlled = true; return(true); } @@ -55,44 +59,62 @@ QString BaseConn::sendCommand(QString command){ if(this->state != "connected"){ return "ERR_NOT_CONNECTED"; } - remoteSessions.acquire(1); - QByteArray arrBlock; - QDataStream out(&arrBlock, QIODevice::WriteOnly); - //out.setVersion(QDataStream::Qt_5_10); - out << quint16(0) << command; - out.device()->seek(0); - out << quint16(arrBlock.size() - sizeof(quint16)); + // generate id and witing requests entry + int thisId = nextConnectionId; + nextConnectionId ++; + QEventLoop loop; + this->waitingRequests.append({thisId, &loop, ""}); - QEventLoop loop; - QTimer timer; + command = "ID:" + QString::number(thisId) + "_"+command; - timer.setSingleShot(true); - // quit the loop when the timer times out - loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - //quit the loop when the connection was established - loop.connect(this, &BaseConn::gotReply, &loop, &QEventLoop::quit); - // start the timer before starting to connect - timer.start(3000); + QByteArray arrBlock; + QDataStream out(&arrBlock, QIODevice::WriteOnly); + //out.setVersion(QDataStream::Qt_5_10); + out << quint16(0) << command; - //write data + out.device()->seek(0); + out << quint16(arrBlock.size() - sizeof(quint16)); - socket->write(arrBlock); + QTimer timer; - //wait for an answer to finish (programm gets stuck in here) - loop.exec(); + timer.setSingleShot(true); + // quit the loop when the timer times out + loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + //quit the loop when the connection was established + // loop.connect(this, &BaseConn::gotReply, &loop, &QEventLoop::quit); + // start the timer before starting to connect + timer.start(3000); - //loop finished - if(timer.remainingTime() == -1){ - //the time has been triggered -> timeout - return("timeout"); + //write data + + socket->write(arrBlock); + + //wait for an answer to finish (programm gets stuck in here) + loop.exec(); + + //loop finished + if(timer.remainingTime() == -1){ + //the time has been triggered -> timeout + + return("ERR_TIMEOUT"); + } + + QString reply; + + for(int i = 0; iwaitingRequests.length(); i++){ + if(this->waitingRequests[i].id == thisId){ + reply = this->waitingRequests[i].reply; } + } - // stop the timer as the connection has been established - timer.stop(); + // stop the timer as the connection has been established + timer.stop(); - remoteSessions.release(1); - return(this->latestReadReply); + timer.deleteLater(); + + //remoteSessions.release(1); + return(reply); } void BaseConn::readyRead() { @@ -111,14 +133,32 @@ void BaseConn::readyRead() { QString str; in >> str; -// if (str == "0") -// { -// str = "Connection closed"; -// closeConnection(); -// } + // if (str == "0") + // { + // str = "Connection closed"; + // closeConnection(); + // } + nextBlockSize = 0; + QString reply = str; + int id = 0; + if(reply.startsWith("ID:")){ + reply.replace("ID:", ""); + QStringList temp = reply.split("_"); + reply.replace(temp[0]+"_", ""); + id = temp[0].toInt(); + + for(int i = 0; iwaitingRequests.length(); i++){ + if(this->waitingRequests[i].id == id){ + this->waitingRequests[i].reply = reply; + this->waitingRequests[i].loop->quit(); + return; + } + } + } + latestReadReply = str; - emit gotReply(); + emit gotUnexpectedReply(str); } } @@ -127,33 +167,81 @@ void BaseConn::readyRead() { void BaseConn::refreshTimers(){ if(this->state != "connected"){ + this->refreshTimer->start(); return; } QString remoteState; + QString remoteTime; + QString tmpNextRemoteAction; + QString tmpNextRemoteActionDelayProg; + + remoteState = sendCommand("GET_TIMER_STATE"); switch (speedTimers[0]->state) { case SpeedTimer::IDLE: break; case SpeedTimer::STARTING: - remoteState = sendCommand("GET_TIMER_STATE"); if(remoteState == "RUNNING"){ speedTimers[0]->start(); } else if (remoteState == "STOPPED") { speedTimers[0]->stop("manual"); } + + tmpNextRemoteAction = sendCommand("GET_NEXT_ACTION"); + if(tmpNextRemoteAction.startsWith("ERR")){ + //handle Error!! + } + else { + if(this->nextRemoteAction != tmpNextRemoteAction){ + this->nextRemoteAction = tmpNextRemoteAction; + this->nextRemoteActionChanged(); + } + } + + tmpNextRemoteActionDelayProg = sendCommand("GET_NEXT_ACTION_DELAY_PROG"); + if(tmpNextRemoteActionDelayProg.startsWith("ERR")){ + //handle error!! + } + else { + if(this->nextRemoteActionDelayProg != tmpNextRemoteActionDelayProg.toFloat()){ + this->nextRemoteActionDelayProg = tmpNextRemoteActionDelayProg.toFloat(); + this->nextRemoteActionDelayProgChanged(); + } + } + break; case SpeedTimer::RUNNING: - remoteState = sendCommand("GET_TIMER_STATE"); + if(remoteState == "STOPPED"){ speedTimers[0]->stop("manual"); } + remoteTime = sendCommand("GET_CURRTIME"); + if(remoteTime.startsWith("ERR")){ + //handle error!! + } + else { + speedTimers[0]->stoppedTime = remoteTime.toInt(); + } break; case SpeedTimer::STOPPED: + remoteTime = sendCommand("GET_STOPPED_TIME"); + if(remoteTime.startsWith("ERR")){ + //handle error!! + + } + else { + speedTimers[0]->stoppedTime = remoteTime.toInt(); + } break; } + if(speedTimers[0]->state != speedTimers[0]->stateFromString(remoteState)){ + // speedTimers[0]->setState(speedTimers[0]->stateFromString(remoteState)); + qWarning() << "WARNING: Remote State not matching!!" << " remote state: " << remoteState << " local state: " << this->speedTimers[0]->getState(); + } + this->refreshTimer->start(); } @@ -171,7 +259,7 @@ bool BaseConn::startTimers(){ return true; } -bool BaseConn::stopTimers(){ +bool BaseConn::stopTimers(QString type){ qDebug() << "stopping timers"; QString ret = this->sendCommand("CMD_STOP_TIMER"); @@ -181,10 +269,24 @@ bool BaseConn::stopTimers(){ return false; } - this->speedTimers[0]->stop("manual"); + this->speedTimers[0]->stop(type); + qDebug() << "stopped timers"; return true; } +bool BaseConn::resetTimers(){ + qDebug() << "resetting timers"; + + QString ret = this->sendCommand("CMD_RESET_TIMER"); + + if(ret.startsWith("ERR")){ + //handle Error! + return false; + } + + this->speedTimers[0]->reset(); + return true; +} void BaseConn::setIP(const QString &ipAdress){ this->ip = ipAdress; @@ -224,3 +326,11 @@ QStringList BaseConn::getConnections() { return(connections); } +QString BaseConn::getNextRemoteAction() { + return this->nextRemoteAction; +} + +float BaseConn::getNextRemoteActionDelayProg(){ + return this->nextRemoteActionDelayProg; +} + diff --git a/sources/main.cpp b/sources/main.cpp index 4c19591..5849289 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -54,6 +54,7 @@ #include "headers/appsettings.h" #include "headers/baseconn.h" #include "headers/speedtimer.h" +#include "headers/speedtimerqmladapter.h" #include static void connectToDatabase() @@ -123,6 +124,7 @@ int main(int argc, char *argv[]) qmlRegisterType("com.itsblue.speedclimbingstopwatch", 1, 0, "BuzzerConn"); qmlRegisterType("com.itsblue.speedclimbingstopwatch", 1, 0, "StartpadConn"); qmlRegisterType("com.itsblue.speedclimbingstopwatch", 1, 0, "BaseStationConn"); + qmlRegisterType("com.itsblue.speedclimbingstopwatch", 1, 0, "SpeedTimerBackend"); //setup translation engine //to the language of the system diff --git a/sources/speedtimer.cpp b/sources/speedtimer.cpp index b73b978..c345315 100644 --- a/sources/speedtimer.cpp +++ b/sources/speedtimer.cpp @@ -4,6 +4,7 @@ SpeedTimer * pGlobalSpeedTimer = nullptr; SpeedTimer::SpeedTimer(QObject *parent) : QObject(parent) { + this->date = new QDateTime; this->startTime = 0; @@ -11,16 +12,21 @@ SpeedTimer::SpeedTimer(QObject *parent) : QObject(parent) this->stoppedTime = 0; this->reactionTime = 0; this->state = IDLE; + this->remoteControlled = false; } void SpeedTimer::start() { if(this->state != STARTING){ return; } - this->stopTime = 0; - this->stoppedTime = 0; - this->reactionTime = 0; - this->startTime = this->date->currentMSecsSinceEpoch(); + qDebug() << "starting timer"; + if(!this->remoteControlled){ + this->stopTime = 0; + this->stoppedTime = 0; + this->reactionTime = 0; + this->startTime = this->date->currentMSecsSinceEpoch(); + } + this->setState(RUNNING); //this->startPad->appendCommand("SET_LED_RUNNING"); } @@ -30,9 +36,18 @@ void SpeedTimer::stop(QString type) { return; } - qDebug() << "Stopping: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << stoppedTime << " reactionTime: " << reactionTime; + //qDebug() << "Stopping: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << stoppedTime << " reactionTime: " << reactionTime; - if(type == "manual"){ + if(this->remoteControlled){ + if(type == "cancel"){ + emit startCanceled(false); + } + } + else if(type == "cancel"){ + emit startCanceled(false); + this->stoppedTime = 0; + } + else if(type == "manual"){ if(this->state == STARTING){ emit startCanceled(false); } @@ -57,6 +72,7 @@ void SpeedTimer::reset(){ if(this->state != STOPPED){ return; } + this->startTime = 0; this->stopTime = 0; this->stoppedTime = 0; @@ -66,9 +82,8 @@ void SpeedTimer::reset(){ } void SpeedTimer::setState(timerState newState){ - this->state = newState; - qDebug() << "tmer state changed: " << newState; + qDebug() << "timer state changed: " << newState; emit this->stateChanged(newState); } @@ -87,7 +102,7 @@ QString SpeedTimer::getState(){ double SpeedTimer::getCurrTime() { double currTime; - if(this->state == RUNNING){ + if(this->state == RUNNING && !this->remoteControlled){ currTime = this->date->currentMSecsSinceEpoch() - this->startTime; } else { @@ -113,3 +128,19 @@ void SpeedTimer::delay(int mSecs){ loop.exec(); } +SpeedTimer::timerState SpeedTimer::stateFromString(QString state){ + + if(state == "IDLE"){ + return IDLE; + } + else if (state == "STARTING") { + return STARTING; + } + else if (state == "RUNNING") { + return RUNNING; + } + else if (state == "STOPPED") { + return STOPPED; + } +} + diff --git a/sources/speedtimerqmladapter.cpp b/sources/speedtimerqmladapter.cpp new file mode 100644 index 0000000..7ab15e2 --- /dev/null +++ b/sources/speedtimerqmladapter.cpp @@ -0,0 +1,96 @@ +#include "headers/speedtimerqmladapter.h" + +SpeedTimerQmlAdapter::SpeedTimerQmlAdapter(QObject *parent) : QObject(parent) +{ + this->state = SpeedTimer::IDLE; + connect(pGlobalSpeedTimer, &SpeedTimer::stateChanged, this, &SpeedTimerQmlAdapter::setState); + connect(pGlobalSpeedTimer, &SpeedTimer::startCanceled, this, &SpeedTimerQmlAdapter::startCanceled); + + this->refreshTimer = new QTimer(); + refreshTimer->setInterval(1); + refreshTimer->setSingleShot(true); + refreshTimer->connect(refreshTimer, &QTimer::timeout, this, &SpeedTimerQmlAdapter::refreshValues); + refreshTimer->start(); + +} + +QString SpeedTimerQmlAdapter::getState(){ + switch(state){ + case SpeedTimer::IDLE: + return("IDLE"); + case SpeedTimer::STARTING: + return("STARTING"); + case SpeedTimer::RUNNING: + return("RUNNING"); + case SpeedTimer::STOPPED: + return("STOPPED"); + } +} + +void SpeedTimerQmlAdapter::setState(SpeedTimer::timerState newState){ + + this->state = newState; + qDebug() << "tmer state changed: " << newState; + emit this->stateChanged(newState); +} + +QString SpeedTimerQmlAdapter::getText(){ + return(this->text); +} + +void SpeedTimerQmlAdapter::refreshValues(){ + //qDebug() << this->getState(); + QString newText; + switch (this->state) { + case SpeedTimer::IDLE: + newText = "Click Start to start"; + break; + case SpeedTimer::STARTING: + newText = "0.000 sec"; + break; + case SpeedTimer::RUNNING: + newText = QString::number( pGlobalSpeedTimer->getCurrTime() / 1000.0, 'f', 3 ) + " sec"; + break; + case SpeedTimer::STOPPED: + newText = QString::number( pGlobalSpeedTimer->stoppedTime / 1000.0, 'f', 3 ) + " sec"; + } + + if(this->text != newText){ + this->text = newText; + emit textChanged(); + } + //qDebug() << this->text; + refreshTimer->start(); +} + +bool SpeedTimerQmlAdapter::setStarting(){ + if(pGlobalSpeedTimer->remoteControlled){ + return false; + } + pGlobalSpeedTimer->setState(SpeedTimer::STARTING); + return true; +} + +bool SpeedTimerQmlAdapter::start(){ + if(pGlobalSpeedTimer->remoteControlled){ + return false; + } + pGlobalSpeedTimer->start(); + return true; +} + +bool SpeedTimerQmlAdapter::stop(QString type){ + if(pGlobalSpeedTimer->remoteControlled){ + return false; + } + pGlobalSpeedTimer->stop(type); + return true; +} + +bool SpeedTimerQmlAdapter::reset(){ + if(pGlobalSpeedTimer->remoteControlled){ + return false; + } + pGlobalSpeedTimer->reset(); + return true; +} diff --git a/speedclimbing_stopwatch.pro b/speedclimbing_stopwatch.pro index 6226223..ab9240a 100644 --- a/speedclimbing_stopwatch.pro +++ b/speedclimbing_stopwatch.pro @@ -26,7 +26,8 @@ SOURCES += \ sources/buzzerconn.cpp \ sources/appsettings.cpp \ sources/baseconn.cpp \ - sources/speedtimer.cpp + sources/speedtimer.cpp \ + sources/speedtimerqmladapter.cpp HEADERS += \ headers/sqlstoragemodel.h \ @@ -34,7 +35,8 @@ HEADERS += \ headers/buzzerconn.h \ headers/appsettings.h \ headers/baseconn.h \ - headers/speedtimer.h + headers/speedtimer.h \ + headers/speedtimerqmladapter.h RESOURCES += \ shared.qrc \