Preparations for dmx thread reading global state with mutex lockers

This commit is contained in:
2023-02-20 01:13:33 +01:00
parent 9611823a77
commit f9b54ea2d8
8 changed files with 134 additions and 66 deletions

View File

@ -3,6 +3,7 @@
#include <QDebug> #include <QDebug>
#include <QCoreApplication> #include <QCoreApplication>
#include <QQmlEngine> #include <QQmlEngine>
#include <QMutexLocker>
void DeviceRegisterValueHelper::setController(DmxController *controller) void DeviceRegisterValueHelper::setController(DmxController *controller)
{ {
@ -125,7 +126,10 @@ void DeviceRegisterValueHelper::setValue(quint8 value)
if (sliderState.size() <= m_registerIndex) if (sliderState.size() <= m_registerIndex)
sliderState.resize(m_registerIndex + 1); sliderState.resize(m_registerIndex + 1);
sliderState[m_registerIndex] = value; {
QMutexLocker locker{&m_controller->mutex()};
sliderState[m_registerIndex] = value;
}
emit valueChanged(value); emit valueChanged(value);
} }

View File

@ -5,6 +5,7 @@
#include <QDebug> #include <QDebug>
#include <QCoreApplication> #include <QCoreApplication>
#include <QQmlEngine> #include <QQmlEngine>
#include <QMutexLocker>
enum { enum {
IdRole = Qt::UserRole, IdRole = Qt::UserRole,
@ -211,21 +212,27 @@ bool DevicesModel::setData(const QModelIndex &index, const QVariant &value, int
return true; return true;
case IdRole: case IdRole:
if (value.userType() != QMetaType::Int) // if (value.userType() != QMetaType::Int)
{ // {
qWarning() << "hilfe" << __LINE__ << value.userType(); // qWarning() << "hilfe" << __LINE__ << value.userType();
return false; // return false;
} // }
device.id = value.toInt(); // device.id = value.toInt();
emit dataChanged(index, index, { IdRole }); // emit dataChanged(index, index, { IdRole });
return true; // return true;
qWarning() << "hilfe" << __LINE__;
return false;
case DeviceTypeIdRole: case DeviceTypeIdRole:
if (value.userType() != QMetaType::Int) if (value.userType() != QMetaType::Int)
{ {
qWarning() << "hilfe" << __LINE__ << value.userType(); qWarning() << "hilfe" << __LINE__ << value.userType();
return false; return false;
} }
device.deviceTypeId = value.toInt();
{
QMutexLocker locker{&m_controller->mutex()};
device.deviceTypeId = value.toInt();
}
emit dataChanged(index, index, { DeviceTypeIdRole }); emit dataChanged(index, index, { DeviceTypeIdRole });
disconnect(m_controller, &DmxController::deviceDeviceTypeIdChanged, disconnect(m_controller, &DmxController::deviceDeviceTypeIdChanged,
@ -241,7 +248,11 @@ bool DevicesModel::setData(const QModelIndex &index, const QVariant &value, int
qWarning() << "hilfe" << __LINE__ << value.userType(); qWarning() << "hilfe" << __LINE__ << value.userType();
return false; return false;
} }
device.address = value.toInt();
{
QMutexLocker locker{&m_controller->mutex()};
device.address = value.toInt();
}
emit dataChanged(index, index, { AddressRole }); emit dataChanged(index, index, { AddressRole });
disconnect(m_controller, &DmxController::deviceAddressChanged, disconnect(m_controller, &DmxController::deviceAddressChanged,
@ -257,7 +268,11 @@ bool DevicesModel::setData(const QModelIndex &index, const QVariant &value, int
qWarning() << "hilfe" << __LINE__ << value.userType(); qWarning() << "hilfe" << __LINE__ << value.userType();
return false; return false;
} }
device.position = value.value<QVector3D>();
{
QMutexLocker locker{&m_controller->mutex()};
device.position = value.value<QVector3D>();
}
emit dataChanged(index, index, { PositionRole }); emit dataChanged(index, index, { PositionRole });
disconnect(m_controller, &DmxController::devicePositionChanged, disconnect(m_controller, &DmxController::devicePositionChanged,
@ -305,9 +320,12 @@ bool DevicesModel::insertRows(int row, int count, const QModelIndex &parent)
auto id = max_iter != std::cend(devices) ? max_iter->id + 1 : 0; auto id = max_iter != std::cend(devices) ? max_iter->id + 1 : 0;
beginInsertRows({}, row, row+count-1); beginInsertRows({}, row, row+count-1);
auto iter = std::begin(devices) + row; {
for (auto i = 0; i < count; i++) QMutexLocker locker{&m_controller->mutex()};
iter = devices.insert(iter, DeviceConfig{ .id=id++, .name="<neu>", .deviceTypeId=0, .address=0, .position={} }) + 1; auto iter = std::begin(devices) + row;
for (auto i = 0; i < count; i++)
iter = devices.insert(iter, DeviceConfig{ .id=id++, .name="<neu>", .deviceTypeId=0, .address=0, .position={} }) + 1;
}
endInsertRows(); endInsertRows();
disconnect(m_controller, &DmxController::deviceInserted, disconnect(m_controller, &DmxController::deviceInserted,
@ -354,9 +372,12 @@ bool DevicesModel::removeRows(int row, int count, const QModelIndex &parent)
} }
beginRemoveRows({}, row, row+count-1); beginRemoveRows({}, row, row+count-1);
auto begin = std::begin(devices) + row; {
auto end = begin + count; QMutexLocker locker{&m_controller->mutex()};
devices.erase(begin, end); auto begin = std::begin(devices) + row;
auto end = begin + count;
devices.erase(begin, end);
}
endRemoveRows(); endRemoveRows();
disconnect(m_controller, &DmxController::deviceRemoved, disconnect(m_controller, &DmxController::deviceRemoved,

View File

@ -5,6 +5,7 @@
#include <QDebug> #include <QDebug>
#include <QCoreApplication> #include <QCoreApplication>
#include <QQmlEngine> #include <QQmlEngine>
#include <QMutexLocker>
void DeviceTypeRegistersModel::setController(DmxController *controller) void DeviceTypeRegistersModel::setController(DmxController *controller)
{ {
@ -240,7 +241,10 @@ bool DeviceTypeRegistersModel::setData(const QModelIndex &index, const QVariant
switch (role) switch (role)
{ {
case Qt::EditRole: case Qt::EditRole:
deviceTypeRegister.type = value.value<DeviceTypeRegisterType>(); {
QMutexLocker locker{&m_controller->mutex()};
deviceTypeRegister.type = value.value<DeviceTypeRegisterType>();
}
emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole }); emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole });
disconnect(m_controller, &DmxController::deviceTypeRegisterTypeChanged, disconnect(m_controller, &DmxController::deviceTypeRegisterTypeChanged,
@ -295,9 +299,12 @@ bool DeviceTypeRegistersModel::insertRows(int row, int count, const QModelIndex
auto &registers = deviceType.registers; auto &registers = deviceType.registers;
beginInsertRows({}, row, row+count-1); beginInsertRows({}, row, row+count-1);
auto iter = std::begin(registers) + row; {
for (auto i = 0; i < count; i++) QMutexLocker locker{&m_controller->mutex()};
iter = registers.insert(iter, DeviceTypeRegisterConfig{ .type = DeviceTypeRegisterType::Dummy }) + 1; auto iter = std::begin(registers) + row;
for (auto i = 0; i < count; i++)
iter = registers.insert(iter, DeviceTypeRegisterConfig{ .type = DeviceTypeRegisterType::Dummy }) + 1;
}
endInsertRows(); endInsertRows();
disconnect(m_controller, &DmxController::deviceTypeRegisterInserted, disconnect(m_controller, &DmxController::deviceTypeRegisterInserted,
@ -360,9 +367,12 @@ bool DeviceTypeRegistersModel::removeRows(int row, int count, const QModelIndex
} }
beginRemoveRows({}, row, row+count-1); beginRemoveRows({}, row, row+count-1);
auto begin = std::begin(registers) + row; {
auto end = begin + count; QMutexLocker locker{&m_controller->mutex()};
registers.erase(begin, end); auto begin = std::begin(registers) + row;
auto end = begin + count;
registers.erase(begin, end);
}
endRemoveRows(); endRemoveRows();
disconnect(m_controller, &DmxController::deviceTypeRegisterRemoved, disconnect(m_controller, &DmxController::deviceTypeRegisterRemoved,

View File

@ -5,6 +5,7 @@
#include <QDebug> #include <QDebug>
#include <QCoreApplication> #include <QCoreApplication>
#include <QQmlEngine> #include <QQmlEngine>
#include <QMutexLocker>
enum { enum {
IdRole = Qt::UserRole, IdRole = Qt::UserRole,
@ -198,14 +199,16 @@ bool DeviceTypesModel::setData(const QModelIndex &index, const QVariant &value,
return true; return true;
case IdRole: case IdRole:
if (value.userType() != QMetaType::Int) // if (value.userType() != QMetaType::Int)
{ // {
qWarning() << "hilfe" << __LINE__ << value.userType(); // qWarning() << "hilfe" << __LINE__ << value.userType();
return false; // return false;
} // }
deviceType.id = value.toInt(); // deviceType.id = value.toInt();
emit dataChanged(index, index, { IdRole }); // emit dataChanged(index, index, { IdRole });
return true; // return true;
qWarning() << "hilfe" << __LINE__;
return false;
case IconNameRole: case IconNameRole:
if (value.userType() != QMetaType::QString) if (value.userType() != QMetaType::QString)
{ {
@ -260,9 +263,12 @@ bool DeviceTypesModel::insertRows(int row, int count, const QModelIndex &parent)
auto id = max_iter != std::cend(deviceTypes) ? max_iter->id + 1 : 0; auto id = max_iter != std::cend(deviceTypes) ? max_iter->id + 1 : 0;
beginInsertRows({}, row, row+count-1); beginInsertRows({}, row, row+count-1);
auto iter = std::begin(deviceTypes) + row; {
for (auto i = 0; i < count; i++) QMutexLocker locker{&m_controller->mutex()};
iter = deviceTypes.insert(iter, DeviceTypeConfig{ .id=id++, .name="<neu>" }) + 1; auto iter = std::begin(deviceTypes) + row;
for (auto i = 0; i < count; i++)
iter = deviceTypes.insert(iter, DeviceTypeConfig{ .id=id++, .name="<neu>" }) + 1;
}
endInsertRows(); endInsertRows();
disconnect(m_controller, &DmxController::deviceTypeInserted, disconnect(m_controller, &DmxController::deviceTypeInserted,
@ -309,9 +315,12 @@ bool DeviceTypesModel::removeRows(int row, int count, const QModelIndex &parent)
} }
beginRemoveRows({}, row, row+count-1); beginRemoveRows({}, row, row+count-1);
auto begin = std::begin(deviceTypes) + row; {
auto end = begin + count; QMutexLocker locker{&m_controller->mutex()};
deviceTypes.erase(begin, end); auto begin = std::begin(deviceTypes) + row;
auto end = begin + count;
deviceTypes.erase(begin, end);
}
endRemoveRows(); endRemoveRows();
disconnect(m_controller, &DmxController::deviceTypeRemoved, disconnect(m_controller, &DmxController::deviceTypeRemoved,

View File

@ -4,6 +4,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <QDebug> #include <QDebug>
#include <QMutexLocker>
DmxController::DmxController(QObject *parent) : DmxController::DmxController(QObject *parent) :
QObject{parent}, QObject{parent},
@ -124,7 +125,6 @@ DmxController::DmxController(QObject *parent) :
} }
} }
{ {
std::fill(std::begin(buf), std::end(buf), 0);
} }
bool DmxController::start() bool DmxController::start()
@ -173,13 +173,19 @@ void DmxController::setRegisterGroup(int registerGroupId, quint8 value)
void DmxController::setSliderStates(sliders_state_t &&sliderStates) void DmxController::setSliderStates(sliders_state_t &&sliderStates)
{ {
m_sliderStates = std::move(sliderStates); {
QMutexLocker locker{&m_mutex};
m_sliderStates = std::move(sliderStates);
}
emit sliderStatesChanged(m_sliderStates); emit sliderStatesChanged(m_sliderStates);
} }
void DmxController::setSliderStates(const sliders_state_t &sliderStates) void DmxController::setSliderStates(const sliders_state_t &sliderStates)
{ {
m_sliderStates = sliderStates; {
QMutexLocker locker{&m_mutex};
m_sliderStates = sliderStates;
}
emit sliderStatesChanged(m_sliderStates); emit sliderStatesChanged(m_sliderStates);
} }
@ -187,6 +193,14 @@ void DmxController::sendDmxBuffer()
{ {
const auto now = QDateTime::currentDateTime(); const auto now = QDateTime::currentDateTime();
char buf[513] {0};
{
QMutexLocker locker{&m_mutex};
// TODO magic
}
m_serialPort.setBreakEnabled(true); m_serialPort.setBreakEnabled(true);
QThread::usleep(88); QThread::usleep(88);
m_serialPort.setBreakEnabled(false); m_serialPort.setBreakEnabled(false);

View File

@ -3,7 +3,7 @@
#include <QObject> #include <QObject>
#include <QSerialPort> #include <QSerialPort>
#include <QDateTime> #include <QDateTime>
#include <QReadWriteLock> #include <QMutex>
#include "dmxcontrollerthread.h" #include "dmxcontrollerthread.h"
#include "lightproject.h" #include "lightproject.h"
@ -23,15 +23,15 @@ public:
LightProject &lightProject() { return m_lightProject; } LightProject &lightProject() { return m_lightProject; }
const LightProject &lightProject() const { return m_lightProject; } const LightProject &lightProject() const { return m_lightProject; }
QReadWriteLock &projectLock() { return m_projectLock; } QMutex &mutex() { return m_mutex; }
int performance() const { return m_lastCounter; }
sliders_state_t &sliderStates() { return m_sliderStates; } sliders_state_t &sliderStates() { return m_sliderStates; }
const sliders_state_t &sliderStates() const { return m_sliderStates; } const sliders_state_t &sliderStates() const { return m_sliderStates; }
void setSliderStates(sliders_state_t &&sliderStates); void setSliderStates(sliders_state_t &&sliderStates);
void setSliderStates(const sliders_state_t &sliderStates); void setSliderStates(const sliders_state_t &sliderStates);
int performance() const { return m_lastCounter; }
signals: signals:
void performanceChanged(int performance); void performanceChanged(int performance);
@ -67,14 +67,11 @@ private:
DmxControllerThread m_thread; DmxControllerThread m_thread;
char buf[513];
LightProject m_lightProject; LightProject m_lightProject;
QReadWriteLock m_projectLock; QMutex m_mutex;
sliders_state_t m_sliderStates;
QDateTime m_lastInfo; QDateTime m_lastInfo;
int m_counter; int m_counter;
std::atomic<int> m_lastCounter; std::atomic<int> m_lastCounter;
sliders_state_t m_sliderStates;
}; };

View File

@ -3,6 +3,7 @@
#include <QDebug> #include <QDebug>
#include <QCoreApplication> #include <QCoreApplication>
#include <QQmlEngine> #include <QQmlEngine>
#include <QMutexLocker>
void RegisterGroupModel::setController(DmxController *controller) void RegisterGroupModel::setController(DmxController *controller)
{ {
@ -59,7 +60,10 @@ void RegisterGroupModel::copyFromFaders()
auto &registerGroup = *registerGroupPtr; auto &registerGroup = *registerGroupPtr;
registerGroup.sliders = m_controller->sliderStates(); {
QMutexLocker locker{&m_controller->mutex()};
registerGroup.sliders = m_controller->sliderStates();
}
} }
void RegisterGroupModel::copyToFaders() void RegisterGroupModel::copyToFaders()

View File

@ -5,6 +5,7 @@
#include <QDebug> #include <QDebug>
#include <QCoreApplication> #include <QCoreApplication>
#include <QQmlEngine> #include <QQmlEngine>
#include <QMutexLocker>
enum { enum {
IdRole = Qt::UserRole, IdRole = Qt::UserRole,
@ -190,14 +191,16 @@ bool RegisterGroupsModel::setData(const QModelIndex &index, const QVariant &valu
return true; return true;
case IdRole: case IdRole:
if (value.userType() != QMetaType::Int) // if (value.userType() != QMetaType::Int)
{ // {
qWarning() << "hilfe" << __LINE__ << value.userType(); // qWarning() << "hilfe" << __LINE__ << value.userType();
return false; // return false;
} // }
registerGroup.id = value.toInt(); // registerGroup.id = value.toInt();
emit dataChanged(index, index, { IdRole }); // emit dataChanged(index, index, { IdRole });
return true; // return true;
qWarning() << "hilfe" << __LINE__;
return false;
default: default:
qWarning() << "hilfe" << __LINE__; qWarning() << "hilfe" << __LINE__;
return false; return false;
@ -236,9 +239,12 @@ bool RegisterGroupsModel::insertRows(int row, int count, const QModelIndex &pare
auto id = max_iter != std::cend(registerGroups) ? max_iter->id + 1 : 0; auto id = max_iter != std::cend(registerGroups) ? max_iter->id + 1 : 0;
beginInsertRows({}, row, row+count-1); beginInsertRows({}, row, row+count-1);
auto iter = std::begin(registerGroups) + row; {
for (auto i = 0; i < count; i++) QMutexLocker locker{&m_controller->mutex()};
iter = registerGroups.insert(iter, RegisterGroupConfig{ .id=id++, .name="<neu>" }) + 1; auto iter = std::begin(registerGroups) + row;
for (auto i = 0; i < count; i++)
iter = registerGroups.insert(iter, RegisterGroupConfig{ .id=id++, .name="<neu>" }) + 1;
}
endInsertRows(); endInsertRows();
disconnect(m_controller, &DmxController::registerGroupInserted, disconnect(m_controller, &DmxController::registerGroupInserted,
@ -285,9 +291,12 @@ bool RegisterGroupsModel::removeRows(int row, int count, const QModelIndex &pare
} }
beginRemoveRows({}, row, row+count-1); beginRemoveRows({}, row, row+count-1);
auto begin = std::begin(registerGroups) + row; {
auto end = begin + count; QMutexLocker locker{&m_controller->mutex()};
registerGroups.erase(begin, end); auto begin = std::begin(registerGroups) + row;
auto end = begin + count;
registerGroups.erase(begin, end);
}
endRemoveRows(); endRemoveRows();
disconnect(m_controller, &DmxController::registerGroupRemoved, disconnect(m_controller, &DmxController::registerGroupRemoved,