Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
43d9f80f60
8 changed files with 130 additions and 102 deletions
|
@ -101,15 +101,14 @@ private:
|
|||
|
||||
QString readBuffer;
|
||||
|
||||
int nextConnectionId;
|
||||
unsigned int currentRequestId;
|
||||
|
||||
struct waitingRequest {
|
||||
int id;
|
||||
struct WaitingRequest {
|
||||
QEventLoop * loop;
|
||||
QJsonObject reply;
|
||||
};
|
||||
|
||||
QList<waitingRequest> waitingRequests;
|
||||
QMap<int, WaitingRequest> waitingRequests;
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -152,7 +151,7 @@ public slots:
|
|||
* \param key the key to read from
|
||||
* \return the value of the key or "false" if the key is not found or an error occured
|
||||
*/
|
||||
QVariant readRemoteSetting(ScStwSettings::BaseStationSetting key);
|
||||
QVariant readRemoteSetting(ScStwSettings::BaseStationSetting key, ScStw::StatusCode* status = nullptr);
|
||||
|
||||
/*! Getter fuctions */
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ class ScStwSetting : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QVariant value READ getValue WRITE setValue NOTIFY valueChanged)
|
||||
Q_PROPERTY(QVariant readonlyValue READ getValue NOTIFY valueChanged)
|
||||
|
||||
protected:
|
||||
explicit ScStwSetting(int key, int keyLevel, ScStwSettings*scStwSettings, QObject *parent);
|
||||
|
|
|
@ -23,7 +23,7 @@ ScStwClient * pGlobalScStwClient = nullptr;
|
|||
ScStwClient::ScStwClient(QObject * parent, QList<ScStw::SignalKey> signalSubscriptions) : QObject(parent)
|
||||
{
|
||||
this->state = DISCONNECTED;
|
||||
this->nextConnectionId = 1;
|
||||
this->currentRequestId = 1;
|
||||
this->extensions = QVariantMap({});
|
||||
this->signalSubscriptions = signalSubscriptions;
|
||||
|
||||
|
@ -50,6 +50,9 @@ ScStwClient::ScStwClient(QObject * parent, QList<ScStw::SignalKey> signalSubscri
|
|||
|
||||
void ScStwClient::connectToHost() {
|
||||
|
||||
if(this->state != DISCONNECTED)
|
||||
return;
|
||||
|
||||
setState(CONNECTING);
|
||||
|
||||
//connect
|
||||
|
@ -84,7 +87,6 @@ bool ScStwClient::init() {
|
|||
QVariantMap initResponse = this->sendCommand(1, sessionParams, 3000, false);
|
||||
|
||||
if(initResponse["status"] != 200) {
|
||||
this->closeConnection();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -121,7 +123,17 @@ void ScStwClient::deInit() {
|
|||
if(this->state == DISCONNECTED)
|
||||
return;
|
||||
|
||||
this->currentRequestId = 1;
|
||||
this->firmwareVersion = "";
|
||||
this->apiVersion = "";
|
||||
this->setExtensions(QVariantMap({}));
|
||||
|
||||
for(WaitingRequest waitingRequest : this->waitingRequests.values())
|
||||
if(waitingRequest.loop != nullptr)
|
||||
waitingRequest.loop->exit(ScStw::NotConnectedError);
|
||||
|
||||
this->waitingRequests.clear();
|
||||
|
||||
this->setState(DISCONNECTED);
|
||||
}
|
||||
|
||||
|
@ -160,16 +172,22 @@ QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, int timeout, b
|
|||
return {{"status", ScStw::NotConnectedError}, {"data", "not connected"}};
|
||||
}
|
||||
|
||||
// generate id and witing requests entry
|
||||
int thisId = nextConnectionId;
|
||||
// pick a new request id that is not already active
|
||||
do {
|
||||
if(this->currentRequestId >= 99)
|
||||
this->currentRequestId = 0;
|
||||
else
|
||||
this->currentRequestId ++;
|
||||
} while(this->waitingRequests.contains(this->currentRequestId));
|
||||
|
||||
int thisId = currentRequestId;
|
||||
//qDebug() << "sending command: " << header << " with data: " << data << " and id: " << thisId;
|
||||
nextConnectionId ++;
|
||||
|
||||
QEventLoop *loop = new QEventLoop(this);
|
||||
QTimer *timer = new QTimer(this);
|
||||
QJsonObject reply;
|
||||
|
||||
this->waitingRequests.append({thisId, loop, reply});
|
||||
this->waitingRequests.insert(thisId, {loop, reply});
|
||||
|
||||
QJsonObject requestObj;
|
||||
requestObj.insert("id", thisId);
|
||||
|
@ -180,7 +198,7 @@ QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, int timeout, b
|
|||
|
||||
timer->setSingleShot(true);
|
||||
// quit the loop when the timer times out
|
||||
loop->connect(timer, SIGNAL(timeout()), loop, SLOT(quit()));
|
||||
connect(timer, &QTimer::timeout, [=]{loop->exit(ScStw::TimeoutError);});
|
||||
// start the timer before starting to connect
|
||||
timer->start(timeout);
|
||||
|
||||
|
@ -191,37 +209,38 @@ QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, int timeout, b
|
|||
socket->write(jsonRequest.toUtf8());
|
||||
|
||||
//wait for an answer to finish (programm gets stuck in here)
|
||||
loop->exec();
|
||||
ScStw::StatusCode statusCode = ScStw::StatusCode(loop->exec());
|
||||
|
||||
|
||||
|
||||
bool replyFound = false;
|
||||
// delete the timer
|
||||
timer->deleteLater();
|
||||
|
||||
// find reply and delete the request from waiting list
|
||||
for(int i = 0; i<this->waitingRequests.length(); i++){
|
||||
if(this->waitingRequests[i].id == thisId){
|
||||
// request was found
|
||||
replyFound = true;
|
||||
// delete event loop
|
||||
if(this->waitingRequests[i].loop != nullptr) {
|
||||
delete this->waitingRequests[i].loop;
|
||||
}
|
||||
// store reply
|
||||
reply = this->waitingRequests[i].reply;
|
||||
// remove reply from waiting list
|
||||
this->waitingRequests.removeAt(i);
|
||||
if(this->waitingRequests.contains(thisId)) {
|
||||
// request was found
|
||||
// delete event loop
|
||||
if(this->waitingRequests[thisId].loop != nullptr) {
|
||||
this->waitingRequests[thisId].loop->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
if(!replyFound) {
|
||||
// store reply
|
||||
reply = this->waitingRequests[thisId].reply;
|
||||
|
||||
// remove reply from waiting list
|
||||
this->waitingRequests.remove(thisId);
|
||||
}
|
||||
else {
|
||||
// some internal error occured
|
||||
return {{"status", ScStw::Error}, {"data", ""}};
|
||||
return {{"status", ScStw::InternalError}, {"data", ""}};
|
||||
}
|
||||
|
||||
if(timer->remainingTime() == -1){
|
||||
if(statusCode == ScStw::TimeoutError){
|
||||
//the time has been triggered -> timeout
|
||||
return {{"status", ScStw::TimeoutError}, {"data", ""}};
|
||||
}
|
||||
else if(statusCode == ScStw::NotConnectedError) {
|
||||
// connection was closed during request
|
||||
return {{"status", ScStw::NotConnectedError}, {"data", ""}};
|
||||
}
|
||||
|
||||
delete timer;
|
||||
return {{"status", reply.value("header").toInt()}, {"data", reply.value("data").toVariant()}};
|
||||
|
@ -273,7 +292,6 @@ void ScStwClient::handleReadyRead() {
|
|||
|
||||
//qDebug() << "ready to ready " << socket->bytesAvailable() << " bytes" ;
|
||||
QString reply = socket->readAll();
|
||||
|
||||
//qWarning() << "socket read: " << reply;
|
||||
|
||||
processSocketMessage(reply);
|
||||
|
@ -335,7 +353,7 @@ void ScStwClient::handleSocketMessage(QString reply) {
|
|||
reply.replace(ScStw::SOCKET_MESSAGE_START_KEY, "");
|
||||
reply.replace(ScStw::SOCKET_MESSAGE_END_KEY, "");
|
||||
|
||||
//qDebug() << "got message: " << reply;
|
||||
qDebug() << "got message: " << qPrintable(reply);
|
||||
|
||||
int id = 0;
|
||||
|
||||
|
@ -352,14 +370,12 @@ void ScStwClient::handleSocketMessage(QString reply) {
|
|||
}
|
||||
|
||||
// this message is the reply to a command!
|
||||
for(int i = 0; i < this->waitingRequests.length(); i++){
|
||||
if(this->waitingRequests[i].id == id){
|
||||
this->waitingRequests[i].reply = replyObj;
|
||||
if(this->waitingRequests[i].loop != nullptr){
|
||||
this->waitingRequests[i].loop->quit();
|
||||
}
|
||||
return;
|
||||
if(this->waitingRequests.contains(id)){
|
||||
this->waitingRequests[id].reply = replyObj;
|
||||
if(this->waitingRequests[id].loop != nullptr){
|
||||
this->waitingRequests[id].loop->exit(ScStw::Success);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,8 +420,13 @@ ScStw::StatusCode ScStwClient::writeRemoteSetting(ScStwSettings::BaseStationSett
|
|||
return ScStw::StatusCode(this->sendCommand(3000, requestData)["status"].toInt());
|
||||
}
|
||||
|
||||
QVariant ScStwClient::readRemoteSetting(ScStwSettings::BaseStationSetting key) {
|
||||
QVariantMap reply = this->sendCommand(3001, int(key));
|
||||
QVariant ScStwClient::readRemoteSetting(ScStwSettings::BaseStationSetting key, ScStw::StatusCode* status) {
|
||||
QVariantMap reply = this->sendCommand(3001, int(key), 10000);
|
||||
qDebug() << "Setting read status is: " << reply["status"];
|
||||
|
||||
if(status != nullptr)
|
||||
*status = ScStw::StatusCode(reply["status"].toInt());
|
||||
|
||||
if(reply["status"] != 200){
|
||||
return "false";
|
||||
}
|
||||
|
|
|
@ -102,8 +102,8 @@ ScStw::StatusCode ScStwRemoteRace::setTimerDisabled(int timerId, bool disabled)
|
|||
qDebug() << "+ --- setting timer " << timerId << " to disabled: " << disabled;
|
||||
|
||||
QVariantMap requestData = {
|
||||
{"timerId", timerId},
|
||||
{"disabled", disabled}
|
||||
{"timerId", timerId},
|
||||
{"disabled", disabled}
|
||||
};
|
||||
|
||||
QVariantMap reply = this->scStwClient->sendCommand(ScStw::SetTimerDisabledCommand, QJsonValue::fromVariant(requestData));
|
||||
|
@ -125,11 +125,12 @@ void ScStwRemoteRace::handleClientStateChange() {
|
|||
// delete all obsolete remote timers
|
||||
for(ScStwRemoteTimer* oldRemoteTimer : this->remoteTimers)
|
||||
oldRemoteTimer->deleteLater();
|
||||
|
||||
this->remoteTimers.clear();
|
||||
break;
|
||||
case ScStwClient::DISCONNECTED:
|
||||
this->remoteTimers.clear();
|
||||
this->setTimers(this->localTimers, true);
|
||||
this->setTimers(this->localTimers, false);
|
||||
emit this->timersChanged();
|
||||
emit this->detailsChanged();
|
||||
emit this->currentStartDelayChanged();
|
||||
|
@ -141,6 +142,30 @@ void ScStwRemoteRace::handleClientStateChange() {
|
|||
}
|
||||
}
|
||||
|
||||
void ScStwRemoteRace::setTimers(QList<ScStwTimer*> timers, bool deleteOldTimers) {
|
||||
|
||||
// disconnect all signals of all current timers
|
||||
//qDebug() << "SETTING TIMERS";
|
||||
|
||||
foreach(ScStwTimer *existingTimer, this->timers) {
|
||||
disconnect(existingTimer, &ScStwTimer::stateChanged, this, &ScStwRace::handleTimerStateChange);
|
||||
disconnect(existingTimer, &ScStwTimer::stateChanged, this, &ScStwRace::timersChanged);
|
||||
disconnect(existingTimer, &ScStwTimer::wantsToBeDisabledChanged, this, &ScStwRace::handleTimerWantsToBeDisabledChange);
|
||||
disconnect(existingTimer, &ScStwTimer::reactionTimeChanged, this, &ScStwRace::timersChanged);
|
||||
disconnect(existingTimer, &ScStwTimer::readyStateChanged, this, &ScStwRace::handleTimerReadyStateChange);
|
||||
disconnect(existingTimer, &ScStwTimer::readyStateChanged, this, &ScStwRace::isReadyForNextStateChanged);
|
||||
|
||||
if(deleteOldTimers)
|
||||
existingTimer->deleteLater();
|
||||
}
|
||||
|
||||
this->timers.clear();
|
||||
|
||||
for(ScStwTimer* timer : timers) {
|
||||
this->addTimer(timer);
|
||||
}
|
||||
}
|
||||
|
||||
ScStwRemoteRace::RaceMode ScStwRemoteRace::getMode() {
|
||||
if(this->scStwClient == nullptr || this->scStwClient->getState() != ScStwClient::CONNECTED)
|
||||
return LOCAL;
|
||||
|
@ -233,43 +258,43 @@ void ScStwRemoteRace::rebuildRemoteTimers(QVariantList remoteTimers) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ScStwRemoteRace::refreshRemoteTimers(QVariantList remoteTimers) {
|
||||
bool ScStwRemoteRace::refreshRemoteTimers(QVariantList newRemoteTimers) {
|
||||
|
||||
qDebug() << "REFRESHING TIMERS";
|
||||
|
||||
if(remoteTimers.length() != this->remoteTimers.length()){
|
||||
// local timers are out of sync
|
||||
this->rebuildRemoteTimers(remoteTimers);
|
||||
qDebug() << "rebuilding remote timers";
|
||||
}
|
||||
if(newRemoteTimers.length() != this->remoteTimers.length()){
|
||||
// local timers are out of sync
|
||||
this->rebuildRemoteTimers(newRemoteTimers);
|
||||
qDebug() << "rebuilding remote timers";
|
||||
}
|
||||
|
||||
foreach(QVariant remoteTimer, remoteTimers){
|
||||
int currId = remoteTimer.toMap()["id"].toInt();
|
||||
for(QVariant remoteTimer : newRemoteTimers){
|
||||
int currId = remoteTimer.toMap()["id"].toInt();
|
||||
|
||||
if(this->remoteTimers.length() <= currId)
|
||||
this->rebuildRemoteTimers(remoteTimers);
|
||||
if(this->remoteTimers.length() <= currId)
|
||||
this->rebuildRemoteTimers(newRemoteTimers);
|
||||
|
||||
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() << " currentTime: " << remoteTimer.toMap()["currentTime"].toDouble();
|
||||
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();
|
||||
|
||||
this->remoteTimers[currId]->setStartTime(currentMSecsSinceEpoch - remoteTimer.toMap()["currentTime"].toDouble());
|
||||
this->remoteTimers[currId]->setStartTime(currentMSecsSinceEpoch - remoteTimer.toMap()["currentTime"].toDouble());
|
||||
|
||||
if(newState >= ScStwTimer::WAITING)
|
||||
this->remoteTimers[currId]->setStopTime(currentMSecsSinceEpoch);
|
||||
if(newState >= ScStwTimer::WAITING)
|
||||
this->remoteTimers[currId]->setStopTime(currentMSecsSinceEpoch);
|
||||
|
||||
this->remoteTimers[currId]->setReactionTime(remoteTimer.toMap()["reactionTime"].toDouble());
|
||||
this->remoteTimers[currId]->setLetter(remoteTimer.toMap()["letter"].toString());
|
||||
this->remoteTimers[currId]->setReadyState(ScStwTimer::ReadyState(remoteTimer.toMap()["readyState"].toInt()));
|
||||
this->remoteTimers[currId]->setReactionTime(remoteTimer.toMap()["reactionTime"].toDouble());
|
||||
this->remoteTimers[currId]->setLetter(remoteTimer.toMap()["letter"].toString());
|
||||
this->remoteTimers[currId]->setReadyState(ScStwTimer::ReadyState(remoteTimer.toMap()["readyState"].toInt()));
|
||||
|
||||
this->remoteTimers[currId]->setState(newState);
|
||||
}
|
||||
this->remoteTimers[currId]->setState(newState);
|
||||
}
|
||||
|
||||
emit this->timersChanged();
|
||||
emit this->timersChanged();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScStwRemoteRace::addTimer(ScStwTimer* timer) {
|
||||
|
@ -281,30 +306,6 @@ bool ScStwRemoteRace::addTimer(ScStwTimer* timer) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void ScStwRemoteRace::setTimers(QList<ScStwTimer*> timers, bool deleteOldTimers) {
|
||||
|
||||
// disconnect all signals of all current timers
|
||||
qDebug() << "SETTING TIMERS";
|
||||
|
||||
foreach(ScStwTimer *existingTimer, this->timers) {
|
||||
disconnect(existingTimer, &ScStwTimer::stateChanged, this, &ScStwRace::handleTimerStateChange);
|
||||
disconnect(existingTimer, &ScStwTimer::stateChanged, this, &ScStwRace::timersChanged);
|
||||
disconnect(existingTimer, &ScStwTimer::wantsToBeDisabledChanged, this, &ScStwRace::handleTimerWantsToBeDisabledChange);
|
||||
disconnect(existingTimer, &ScStwTimer::reactionTimeChanged, this, &ScStwRace::timersChanged);
|
||||
disconnect(existingTimer, &ScStwTimer::readyStateChanged, this, &ScStwRace::handleTimerReadyStateChange);
|
||||
disconnect(existingTimer, &ScStwTimer::readyStateChanged, this, &ScStwRace::isReadyForNextStateChanged);
|
||||
|
||||
if(deleteOldTimers)
|
||||
existingTimer->deleteLater();
|
||||
}
|
||||
|
||||
this->timers.clear();
|
||||
|
||||
for(ScStwTimer* timer : timers) {
|
||||
this->addTimer(timer);
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap ScStwRemoteRace::getCurrentStartDelay() {
|
||||
if(this->local())
|
||||
return ScStwRace::getCurrentStartDelay();
|
||||
|
|
|
@ -41,7 +41,13 @@ QVariant ScStwRemoteSettings::readSetting(QString key, int keyInt, int keyLevel)
|
|||
|
||||
qDebug() << "Setting read: keyLevel: " << keyLevel << " key: " << key;
|
||||
|
||||
return this->scStwClient->readRemoteSetting(ScStwSettings::BaseStationSetting(keyInt));
|
||||
ScStw::StatusCode status;
|
||||
QVariant value = this->scStwClient->readRemoteSetting(ScStwSettings::BaseStationSetting(keyInt), &status);
|
||||
|
||||
if(status == ScStw::Success)
|
||||
return value;
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool ScStwRemoteSettings::writeSetting(QString key, QVariant value, int keyInt, int keyLevel) {
|
||||
|
@ -66,8 +72,8 @@ bool ScStwRemoteSettings::setDefaultSetting(QString key, QVariant defaultVariant
|
|||
void ScStwRemoteSettings::handleClientStateChange() {
|
||||
if(this->scStwClient->getState() == ScStwClient::DISCONNECTED)
|
||||
emit this->settingChanged(-1, ScStwSettings::KeyLevel, QVariant());
|
||||
else if(this->scStwClient->getState() == ScStwClient::CONNECTED)
|
||||
emit this->settingChanged(-1, ScStwSettings::KeyLevel, QVariant());
|
||||
// Dont't need to do that when changing to connected,
|
||||
// as the basestation emits a wildcrd setting changed on connect anyway
|
||||
}
|
||||
|
||||
void ScStwRemoteSettings::handleBaseStationSignal(ScStw::SignalKey key, QVariant data) {
|
||||
|
|
|
@ -172,7 +172,7 @@ ScStw::StatusCode ScStwRace::setTimerDisabled(int timerId, bool disabled) {
|
|||
}
|
||||
|
||||
ScStw::StatusCode ScStwRace::setTimerDisabled(ScStwTimer* timer, bool disabled) {
|
||||
qDebug() << "[INFO][RACE] Setting timer "<< timer->getLetter() << " to disabled: " << disabled << " this state: " << this->state;
|
||||
//qDebug() << "[INFO][RACE] Setting timer "<< timer->getLetter() << " to disabled: " << disabled << " this state: " << this->state;
|
||||
if(this->state != IDLE && this->state != WAITING)
|
||||
return ScStw::CurrentStateNotVaildForOperationError;
|
||||
|
||||
|
@ -189,7 +189,7 @@ ScStw::StatusCode ScStwRace::setTimerDisabled(ScStwTimer* timer, bool disabled)
|
|||
if(disabled && enabledTimerCount <= 1)
|
||||
return ScStw::LastTimerCannotBeDisabledError;
|
||||
|
||||
qDebug() << "[INFO][RACE] Setting timer "<< timer->getLetter() << " to disabled: " << disabled;
|
||||
//qDebug() << "[INFO][RACE] Setting timer "<< timer->getLetter() << " to disabled: " << disabled;
|
||||
|
||||
timer->setDisabled(disabled);
|
||||
|
||||
|
@ -623,13 +623,12 @@ bool ScStwRace::getIsReadyForNextState() {
|
|||
* @param {ScStwExtensionControlledTimer*} timer timer to be enabled
|
||||
*/
|
||||
void ScStwRace::handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled) {
|
||||
qDebug() << "Handling timer wants to be disabled";
|
||||
//qDebug() << "Handling timer wants to be disabled";
|
||||
if(this->competitionMode)
|
||||
return;
|
||||
|
||||
if(this->state == IDLE) {
|
||||
|
||||
qDebug() << "Handling timer wants to be disabled: " << wantsToBeDisabled;
|
||||
//qDebug() << "Handling timer wants to be disabled: " << wantsToBeDisabled;
|
||||
this->setTimerDisabled(timer, wantsToBeDisabled);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ ScStwSetting::ScStwSetting(int key, int keyLevel, ScStwSettings*scStwSettings, Q
|
|||
}
|
||||
|
||||
QVariant ScStwSetting::getValue() {
|
||||
qDebug() << "Getting setting: " << this->key << " has to reload: " << this->hasToReload;
|
||||
if(this->hasToReload) {
|
||||
this->valueCache = this->scStwSettings->readSetting(this->key, this->keyLevel);
|
||||
this->hasToReload = false;
|
||||
|
|
|
@ -29,7 +29,7 @@ ScStwTimer::ScStwTimer(QString letter, QObject *parent) : QObject(parent)
|
|||
else
|
||||
this->letter = letter;
|
||||
|
||||
qDebug() << "Timer created with letter: " << letter;
|
||||
//qDebug() << "Timer created with letter: " << letter;
|
||||
|
||||
this->startTime = 0;
|
||||
this->stopTime = 0;
|
||||
|
|
Reference in a new issue