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) {
|
||||
|
||||
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,9 +319,12 @@ 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() {
|
||||
return this->displayBrightness;
|
||||
|
|
|
@ -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();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -17,10 +17,6 @@ ApplicationWindow {
|
|||
|
||||
state: backend.state
|
||||
|
||||
onStateChanged: {
|
||||
console.log("new state: " + state)
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Material.accent: "#0094ff"
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
"ostream": "cpp",
|
||||
"numeric": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"utility": "cpp"
|
||||
"utility": "cpp",
|
||||
"string_view": "cpp"
|
||||
},
|
||||
"svn.ignoreMissingSvnWarning": true
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue