Fix: race problems when reading and writing data
This commit is contained in:
parent
ae659ac875
commit
bd9bfe858e
6 changed files with 71 additions and 53 deletions
|
@ -110,6 +110,8 @@ void LedDisplayBackend::handleFoundNewDevice(QBluetoothLeUartDevice* device) {
|
||||||
|
|
||||||
void LedDisplayBackend::handleDisplayTextModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) {
|
void LedDisplayBackend::handleDisplayTextModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) {
|
||||||
|
|
||||||
|
if(this->state == Initing) return;
|
||||||
|
|
||||||
qDebug() << "Data changed: topLeft: " << topLeft << " bottomRight: " << bottomRight << " roles: " << roles;
|
qDebug() << "Data changed: topLeft: " << topLeft << " bottomRight: " << bottomRight << " roles: " << roles;
|
||||||
|
|
||||||
for(int role : roles)
|
for(int role : roles)
|
||||||
|
@ -140,6 +142,13 @@ void LedDisplayBackend::sendBluetoothCommand(OmobiDisplayCommand command, QVaria
|
||||||
|
|
||||||
qDebug() << "Sending command: \n" << qPrintable(doc.toJson(QJsonDocument::Compact));
|
qDebug() << "Sending command: \n" << qPrintable(doc.toJson(QJsonDocument::Compact));
|
||||||
|
|
||||||
|
if((this->state != Initing && this->waitingCommands > 0) || (this->state == Initing && this->waitingCommands > 1)) {
|
||||||
|
QEventLoop loop;
|
||||||
|
loop.connect(this, &LedDisplayBackend::commandFinished, &loop, &QEventLoop::quit);
|
||||||
|
loop.exec();
|
||||||
|
if(this->state == Idle) return;
|
||||||
|
}
|
||||||
|
|
||||||
this->waitingCommands ++;
|
this->waitingCommands ++;
|
||||||
|
|
||||||
if(this->state == Connected)
|
if(this->state == Connected)
|
||||||
|
@ -169,6 +178,8 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
|
||||||
QVariantMap data = doc.toVariant().toMap()["data"].toMap();
|
QVariantMap data = doc.toVariant().toMap()["data"].toMap();
|
||||||
OmobiDisplayStatusCode status = OmobiDisplayStatusCode(doc.toVariant().toMap()["status"].toInt());
|
OmobiDisplayStatusCode status = OmobiDisplayStatusCode(doc.toVariant().toMap()["status"].toInt());
|
||||||
|
|
||||||
|
qDebug() << "Header is:" << header;
|
||||||
|
|
||||||
switch (header) {
|
switch (header) {
|
||||||
case AuthenticateCommand: {
|
case AuthenticateCommand: {
|
||||||
if(status != Success) {
|
if(status != Success) {
|
||||||
|
@ -180,9 +191,9 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
|
||||||
this->settings->setValue(this->bleClient->getCurrentDevice()->getAddress(), this->lastDisplaySecret);
|
this->settings->setValue(this->bleClient->getCurrentDevice()->getAddress(), this->lastDisplaySecret);
|
||||||
|
|
||||||
this->waitingCommands = 0;
|
this->waitingCommands = 0;
|
||||||
|
emit this->commandFinished();
|
||||||
this->setState(Initing);
|
this->setState(Initing);
|
||||||
this->sendBluetoothCommand(GetAllTextSetsCommand);
|
this->sendBluetoothCommand(GetAllTextSetsCommand);
|
||||||
this->sendBluetoothCommand(GetDisplayBrightnessCommand);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +202,7 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
|
||||||
}
|
}
|
||||||
|
|
||||||
case GetAllTextSetsCommand: {
|
case GetAllTextSetsCommand: {
|
||||||
// indicates that all existing txt sets have been sent over after GetAllTextSetsCommand was called
|
// indicates that all existing text sets have been sent over after GetAllTextSetsCommand was called
|
||||||
if(status != Success)
|
if(status != Success)
|
||||||
// TODO: handle error
|
// TODO: handle error
|
||||||
break;
|
break;
|
||||||
|
@ -199,11 +210,16 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
|
||||||
this->displayTextModel->maximumTextLength = data["maximumTextLength"].toInt();
|
this->displayTextModel->maximumTextLength = data["maximumTextLength"].toInt();
|
||||||
this->displayTextModel->maximumTextSets = data["maximumTextSets"].toInt();
|
this->displayTextModel->maximumTextSets = data["maximumTextSets"].toInt();
|
||||||
|
|
||||||
qDebug() << "text sets are: " << this->textSetsBuffer;
|
this->displayTextModel->setTexts({});
|
||||||
|
|
||||||
this->displayTextModel->setTexts(this->textSetsBuffer);
|
|
||||||
this->textSetsBuffer.clear();
|
this->textSetsBuffer.clear();
|
||||||
|
|
||||||
|
for(int i = 0; i < this->displayTextModel->maximumTextSets; i++) {
|
||||||
|
for(int param = 0; param < DisplayTextSetParameterCount; param++) {
|
||||||
|
this->sendBluetoothCommand(GetTextSetParameterCommand, QVariantMap({{"index", i}, {"parameter", param}}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->sendBluetoothCommand(GetDisplayBrightnessCommand);
|
||||||
|
|
||||||
this->refreshLoadingState();
|
this->refreshLoadingState();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -224,8 +240,8 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
|
||||||
this->textSetsBuffer[index].insert(parameter, QVariant());
|
this->textSetsBuffer[index].insert(parameter, QVariant());
|
||||||
|
|
||||||
this->textSetsBuffer[index][parameter] = data["value"].toString();
|
this->textSetsBuffer[index][parameter] = data["value"].toString();
|
||||||
|
qDebug() << "Got value: " << this->textSetsBuffer[index][parameter];
|
||||||
if(this->state != Initing)
|
this->displayTextModel->setTexts(this->textSetsBuffer);
|
||||||
this->refreshLoadingState();
|
this->refreshLoadingState();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -284,6 +300,7 @@ void LedDisplayBackend::refreshLoadingState() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qDebug() << "Refreshing loading state! Waiting: " << this->waitingCommands;
|
qDebug() << "Refreshing loading state! Waiting: " << this->waitingCommands;
|
||||||
|
emit this->commandFinished();
|
||||||
|
|
||||||
if(this->waitingCommands <= 1) {
|
if(this->waitingCommands <= 1) {
|
||||||
this->waitingCommands = 0;
|
this->waitingCommands = 0;
|
||||||
|
@ -302,9 +319,12 @@ void LedDisplayBackend::setState(OmobiDisplayAppState state) {
|
||||||
|
|
||||||
qDebug() << "Now in " << state << " state";
|
qDebug() << "Now in " << state << " state";
|
||||||
|
|
||||||
if(this->state == Idle)
|
if(this->state == Idle) {
|
||||||
|
this->waitingCommands = 0;
|
||||||
|
emit this->commandFinished();
|
||||||
this->bleClient->startScanningForDevices();
|
this->bleClient->startScanningForDevices();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap LedDisplayBackend::getDisplayBrightness() {
|
QVariantMap LedDisplayBackend::getDisplayBrightness() {
|
||||||
return this->displayBrightness;
|
return this->displayBrightness;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QEventLoop>
|
||||||
|
|
||||||
#include <qbluetoothleuartclient.h>
|
#include <qbluetoothleuartclient.h>
|
||||||
#include <leddisplaytextmodel.h>
|
#include <leddisplaytextmodel.h>
|
||||||
|
@ -54,6 +55,21 @@ private:
|
||||||
SetDisplayNameCommand = 23
|
SetDisplayNameCommand = 23
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum OmobiDisplayTextSetParameter
|
||||||
|
{
|
||||||
|
TextParameter = 0,
|
||||||
|
ActiveParameter,
|
||||||
|
RuntimeParameter,
|
||||||
|
ColorParameter,
|
||||||
|
AlignmentParameter,
|
||||||
|
ScrollParameter,
|
||||||
|
ScrollDirectionParameter,
|
||||||
|
ScrollSpeedParameter,
|
||||||
|
ScrollCountParameter,
|
||||||
|
IndexParameter,
|
||||||
|
DisplayTextSetParameterCount /*!< Just for helping purposes */
|
||||||
|
};
|
||||||
|
|
||||||
enum OmobiDisplayStatusCode {
|
enum OmobiDisplayStatusCode {
|
||||||
Success = 200,
|
Success = 200,
|
||||||
DisplayControllerError = 501
|
DisplayControllerError = 501
|
||||||
|
@ -105,6 +121,7 @@ signals:
|
||||||
void bleClientChanged();
|
void bleClientChanged();
|
||||||
void displayTextModelChanged();
|
void displayTextModelChanged();
|
||||||
void displayBrightnessChanged();
|
void displayBrightnessChanged();
|
||||||
|
void commandFinished();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -135,8 +135,10 @@ bool LedDisplayTextModel::setTexts(QList<QMap<int, QVariant>> texts) {
|
||||||
this->texts.clear();
|
this->texts.clear();
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
|
|
||||||
for(QMap<int, QVariant> text : texts)
|
for(QMap<int, QVariant> text : texts) {
|
||||||
|
if(text[0].toString().isEmpty()) continue;
|
||||||
this->append(text);
|
this->append(text);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,6 @@ ApplicationWindow {
|
||||||
|
|
||||||
state: backend.state
|
state: backend.state
|
||||||
|
|
||||||
onStateChanged: {
|
|
||||||
console.log("new state: " + state)
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Material.accent: "#0094ff"
|
Material.accent: "#0094ff"
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
"ostream": "cpp",
|
"ostream": "cpp",
|
||||||
"numeric": "cpp",
|
"numeric": "cpp",
|
||||||
"streambuf": "cpp",
|
"streambuf": "cpp",
|
||||||
"utility": "cpp"
|
"utility": "cpp",
|
||||||
|
"string_view": "cpp"
|
||||||
},
|
},
|
||||||
"svn.ignoreMissingSvnWarning": true
|
"svn.ignoreMissingSvnWarning": true
|
||||||
}
|
}
|
|
@ -86,44 +86,6 @@ void OmobiLedDisplay::onDataReceived(String dataString)
|
||||||
|
|
||||||
case GetAllTextSetsCommand:
|
case GetAllTextSetsCommand:
|
||||||
{
|
{
|
||||||
// cycle through all text sets
|
|
||||||
for (int textSetIndex = 0; textSetIndex < LedDisplayController::maximumTextSets; textSetIndex++)
|
|
||||||
{
|
|
||||||
if (this->ledDisplayController->getTextSetParameter(textSetIndex, LedDisplayController::TextParameter) == "")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Serial.println("Adding index " + String(textSetIndex) + " with text: " + this->ledDisplayController->getTextSetParameter(textSetIndex, LedDisplayController::TextParameter));
|
|
||||||
|
|
||||||
// if a set isn't empty, go through all parameters
|
|
||||||
for (int textSetParameter = 0; textSetParameter < LedDisplayController::DisplayTextSetParameterCount; textSetParameter++)
|
|
||||||
{
|
|
||||||
// send each parameter to the client
|
|
||||||
const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + LedDisplayController::maximumTextLength; //200;
|
|
||||||
DynamicJsonDocument doc(capacity);
|
|
||||||
|
|
||||||
doc["header"] = GetTextSetParameterCommand;
|
|
||||||
|
|
||||||
JsonObject data = doc.createNestedObject("data");
|
|
||||||
data["index"] = textSetIndex;
|
|
||||||
data["parameter"] = textSetParameter;
|
|
||||||
|
|
||||||
data["value"] = this->ledDisplayController->getTextSetParameter(
|
|
||||||
textSetIndex,
|
|
||||||
LedDisplayController::DisplayTextSetParameter(textSetParameter));
|
|
||||||
|
|
||||||
|
|
||||||
Serial.println("sending parameter: " + String(textSetParameter) + " with value: '" + this->ledDisplayController->getTextSetParameter(
|
|
||||||
textSetIndex,
|
|
||||||
LedDisplayController::DisplayTextSetParameter(textSetParameter)) + "'");
|
|
||||||
|
|
||||||
String json;
|
|
||||||
serializeJson(doc, json);
|
|
||||||
Serial.println("JSON: '" + json + "'");
|
|
||||||
this->bleServer->sendData(json);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
replyStatus = Success;
|
replyStatus = Success;
|
||||||
replyData["maximumTextSets"] = LedDisplayController::maximumTextSets;
|
replyData["maximumTextSets"] = LedDisplayController::maximumTextSets;
|
||||||
replyData["maximumTextLength"] = LedDisplayController::maximumTextLength;
|
replyData["maximumTextLength"] = LedDisplayController::maximumTextLength;
|
||||||
|
@ -137,6 +99,25 @@ void OmobiLedDisplay::onDataReceived(String dataString)
|
||||||
replyStatus = Success;
|
replyStatus = Success;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GetTextSetParameterCommand:
|
||||||
|
{
|
||||||
|
int index = requestData["index"];
|
||||||
|
LedDisplayController::DisplayTextSetParameter parameter = requestData["parameter"];
|
||||||
|
// send each parameter to the client
|
||||||
|
replyData["index"] = index;
|
||||||
|
replyData["parameter"] = parameter;
|
||||||
|
replyStatus = Success;
|
||||||
|
|
||||||
|
replyData["value"] = this->ledDisplayController->getTextSetParameter(
|
||||||
|
index,
|
||||||
|
parameter);
|
||||||
|
|
||||||
|
|
||||||
|
Serial.println("sending parameter: " + String(parameter) + " with value: '" + this->ledDisplayController->getTextSetParameter(
|
||||||
|
index,
|
||||||
|
parameter) + "'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SetTextSetParameterCommand:
|
case SetTextSetParameterCommand:
|
||||||
{
|
{
|
||||||
|
@ -195,6 +176,7 @@ void OmobiLedDisplay::onDataReceived(String dataString)
|
||||||
replyDoc["status"] = replyStatus;
|
replyDoc["status"] = replyStatus;
|
||||||
String json;
|
String json;
|
||||||
serializeJson(replyDoc, json);
|
serializeJson(replyDoc, json);
|
||||||
|
Serial.println("Primary JSON: '" + json + "'");
|
||||||
this->bleServer->sendData(json);
|
this->bleServer->sendData(json);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue