Fix: race problems when reading and writing data

This commit is contained in:
Dorian Zedler 2022-08-02 22:08:30 +02:00
parent ae659ac875
commit bd9bfe858e
Signed by: dorian
GPG key ID: 989DE36109AFA354
6 changed files with 71 additions and 53 deletions

View file

@ -110,6 +110,8 @@ void LedDisplayBackend::handleFoundNewDevice(QBluetoothLeUartDevice* device) {
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;
for(int role : roles)
@ -140,6 +142,13 @@ void LedDisplayBackend::sendBluetoothCommand(OmobiDisplayCommand command, QVaria
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 ++;
if(this->state == Connected)
@ -169,6 +178,8 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
QVariantMap data = doc.toVariant().toMap()["data"].toMap();
OmobiDisplayStatusCode status = OmobiDisplayStatusCode(doc.toVariant().toMap()["status"].toInt());
qDebug() << "Header is:" << header;
switch (header) {
case AuthenticateCommand: {
if(status != Success) {
@ -180,9 +191,9 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
this->settings->setValue(this->bleClient->getCurrentDevice()->getAddress(), this->lastDisplaySecret);
this->waitingCommands = 0;
emit this->commandFinished();
this->setState(Initing);
this->sendBluetoothCommand(GetAllTextSetsCommand);
this->sendBluetoothCommand(GetDisplayBrightnessCommand);
break;
}
@ -191,7 +202,7 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
}
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)
// TODO: handle error
break;
@ -199,11 +210,16 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
this->displayTextModel->maximumTextLength = data["maximumTextLength"].toInt();
this->displayTextModel->maximumTextSets = data["maximumTextSets"].toInt();
qDebug() << "text sets are: " << this->textSetsBuffer;
this->displayTextModel->setTexts(this->textSetsBuffer);
this->displayTextModel->setTexts({});
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();
break;
@ -224,8 +240,8 @@ void LedDisplayBackend::handleBluetoothDataReceived(QString s){
this->textSetsBuffer[index].insert(parameter, QVariant());
this->textSetsBuffer[index][parameter] = data["value"].toString();
if(this->state != Initing)
qDebug() << "Got value: " << this->textSetsBuffer[index][parameter];
this->displayTextModel->setTexts(this->textSetsBuffer);
this->refreshLoadingState();
break;
@ -284,6 +300,7 @@ void LedDisplayBackend::refreshLoadingState() {
return;
qDebug() << "Refreshing loading state! Waiting: " << this->waitingCommands;
emit this->commandFinished();
if(this->waitingCommands <= 1) {
this->waitingCommands = 0;
@ -302,8 +319,11 @@ void LedDisplayBackend::setState(OmobiDisplayAppState state) {
qDebug() << "Now in " << state << " state";
if(this->state == Idle)
if(this->state == Idle) {
this->waitingCommands = 0;
emit this->commandFinished();
this->bleClient->startScanningForDevices();
}
}
QVariantMap LedDisplayBackend::getDisplayBrightness() {

View file

@ -6,6 +6,7 @@
#include <QJsonDocument>
#include <QCryptographicHash>
#include <QSettings>
#include <QEventLoop>
#include <qbluetoothleuartclient.h>
#include <leddisplaytextmodel.h>
@ -54,6 +55,21 @@ private:
SetDisplayNameCommand = 23
};
enum OmobiDisplayTextSetParameter
{
TextParameter = 0,
ActiveParameter,
RuntimeParameter,
ColorParameter,
AlignmentParameter,
ScrollParameter,
ScrollDirectionParameter,
ScrollSpeedParameter,
ScrollCountParameter,
IndexParameter,
DisplayTextSetParameterCount /*!< Just for helping purposes */
};
enum OmobiDisplayStatusCode {
Success = 200,
DisplayControllerError = 501
@ -105,6 +121,7 @@ signals:
void bleClientChanged();
void displayTextModelChanged();
void displayBrightnessChanged();
void commandFinished();
};

View file

@ -135,8 +135,10 @@ bool LedDisplayTextModel::setTexts(QList<QMap<int, QVariant>> texts) {
this->texts.clear();
this->endResetModel();
for(QMap<int, QVariant> text : texts)
for(QMap<int, QVariant> text : texts) {
if(text[0].toString().isEmpty()) continue;
this->append(text);
}
return true;
}

View file

@ -17,10 +17,6 @@ ApplicationWindow {
state: backend.state
onStateChanged: {
console.log("new state: " + state)
}
anchors.fill: parent
Material.accent: "#0094ff"

View file

@ -17,7 +17,8 @@
"ostream": "cpp",
"numeric": "cpp",
"streambuf": "cpp",
"utility": "cpp"
"utility": "cpp",
"string_view": "cpp"
},
"svn.ignoreMissingSvnWarning": true
}

View file

@ -86,44 +86,6 @@ void OmobiLedDisplay::onDataReceived(String dataString)
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;
replyData["maximumTextSets"] = LedDisplayController::maximumTextSets;
replyData["maximumTextLength"] = LedDisplayController::maximumTextLength;
@ -137,6 +99,25 @@ void OmobiLedDisplay::onDataReceived(String dataString)
replyStatus = Success;
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:
{
@ -195,6 +176,7 @@ void OmobiLedDisplay::onDataReceived(String dataString)
replyDoc["status"] = replyStatus;
String json;
serializeJson(replyDoc, json);
Serial.println("Primary JSON: '" + json + "'");
this->bleServer->sendData(json);