Added BCTransmitter & woker thread.

This commit is contained in:
2025-12-18 20:34:38 +01:00
parent 1d558198c9
commit 059f3081d3
12 changed files with 90 additions and 252 deletions

View File

@@ -26,15 +26,14 @@ windows
SOURCES += \ SOURCES += \
bc.cpp \ bc.cpp \
bcdatamodel.cpp \
bcitemdelegate.cpp \
bctransmitter.cpp \
lib/can_drv_win.c \ lib/can_drv_win.c \
bccandriver.cpp \ bccandriver.cpp \
bccandrivertinycan.cpp \ bccandrivertinycan.cpp \
bccommand.cpp \
bccommandrunner.cpp \
bcvalue.cpp \ bcvalue.cpp \
bcvaluedelegate.cpp \
bcvaluemanager.cpp \ bcvaluemanager.cpp \
bcvaluemodel.cpp \
main.cpp \ main.cpp \
bcmainwindow.cpp bcmainwindow.cpp
@@ -42,13 +41,12 @@ HEADERS += \
bc.h \ bc.h \
bccandriver.h \ bccandriver.h \
bccandrivertinycan.h \ bccandrivertinycan.h \
bccommand.h \ bcdatamodel.h \
bccommandrunner.h \ bcitemdelegate.h \
bcmainwindow.h \ bcmainwindow.h \
bctransmitter.h \
bcvalue.h \ bcvalue.h \
bcvaluedelegate.h \ bcvaluemanager.h
bcvaluemanager.h \
bcvaluemodel.h
FORMS += \ FORMS += \
bcmainwindow.ui bcmainwindow.ui

View File

@@ -1,49 +0,0 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
BigXionFlasher USB V 0.2.4 rev. 97
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
@see www.bigxionflasher.org
Bionx Bike Info
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
@see www.ts-soft.de
mhs_can_drv.c 3.00
© 2011 - 2015 by MHS-Elektronik GmbH & Co. KG, Germany
Demlehner Klaus, info@mhs-elektronik.de
@see www.mhs-elektronik.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
@see https://github.com/bikemike/bionx-bikeinfo
***************************************************************************/
#include <bccommand.h>
BCCommand::BCCommand(BCDevice::ID deviceID_, BC::ID targetID_)
: deviceID{deviceID_}, targetID{targetID_}
{
}
void BCCommand::setLongValue( uint8_t value)
{
}
uint8_t BCCommand::getLongValue()
{
return 0;
}

View File

@@ -1,59 +0,0 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
BigXionFlasher USB V 0.2.4 rev. 97
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
@see www.bigxionflasher.org
Bionx Bike Info
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
@see www.ts-soft.de
mhs_can_drv.c 3.00
© 2011 - 2015 by MHS-Elektronik GmbH & Co. KG, Germany
Demlehner Klaus, info@mhs-elektronik.de
@see www.mhs-elektronik.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
@see https://github.com/bikemike/bionx-bikeinfo
***************************************************************************/
#ifndef BCCOMMAND_H
#define BCCOMMAND_H
#include <QString>
#include <bc.h>
struct BCCommand
{
BCCommand( BCDevice::ID deviceID, BC::ID targetID );
void setLongValue( uint8_t value);
uint8_t getLongValue();
QString label;
BCDevice::ID deviceID{BCDevice::ID::Invalid};
BC::ID targetID{BC::ID::Invalid};
};
class BCCommandRunner;
#endif // BCCOMMAND_H

View File

@@ -1,30 +0,0 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
BigXionFlasher USB V 0.2.4 rev. 97
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
@see www.bigxionflasher.org
Bionx Bike Info
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
@see www.ts-soft.de
mhs_can_drv.c 3.00
© 2011 - 2015 by MHS-Elektronik GmbH & Co. KG, Germany
Demlehner Klaus, info@mhs-elektronik.de
@see www.mhs-elektronik.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
@see https://github.com/bikemike/bionx-bikeinfo
***************************************************************************/
#include <bccommandrunner.h>

View File

@@ -1,81 +0,0 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
BigXionFlasher USB V 0.2.4 rev. 97
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
@see www.bigxionflasher.org
Bionx Bike Info
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
@see www.ts-soft.de
mhs_can_drv.c 3.00
© 2011 - 2015 by MHS-Elektronik GmbH & Co. KG, Germany
Demlehner Klaus, info@mhs-elektronik.de
@see www.mhs-elektronik.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
@see https://github.com/bikemike/bionx-bikeinfo
***************************************************************************/
#ifndef BCCOMMANDRUNNER_H
#define BCCOMMANDRUNNER_H
#include <QThread>
#include <QObject>
#include <QQueue>
#include <QMutex>
#include <QSemaphore>
#include <atomic>
#include <QVariant>
#include "bccommand.h"
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork(const QString &parameter)
{
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
/*
class BCCommandRunner : public QObject
{
Q_OBJECT
public:
BCCommandRunner();
virtual ~BCCommandRunner() = default;
protected:
};
*/
#endif // BCCOMMANDRUNNER_H

View File

@@ -28,7 +28,7 @@
***************************************************************************/ ***************************************************************************/
#include <bcvaluemodel.h> #include <bcdatamodel.h>

View File

@@ -28,8 +28,8 @@
***************************************************************************/ ***************************************************************************/
#ifndef BCVALUEMODEL_H #ifndef BCDATAMODEL_H
#define BCVALUEMODEL_H #define BCDATAMODEL_H
#include <QAbstractTableModel> #include <QAbstractTableModel>
@@ -60,4 +60,4 @@ private:
}; };
#endif // BCVALUEMODEL_H #endif // BCDATAMODEL_H

View File

@@ -4,19 +4,19 @@
#include <QWidget> #include <QWidget>
#include <QDebug> #include <QDebug>
#include "bcvaluedelegate.h" #include "bcitemdelegate.h"
#include "bcvalue.h" #include "bcvalue.h"
#include "qapplication.h" #include "qapplication.h"
BCValueDelegate::BCValueDelegate(QObject *parent) BCItemDelegate::BCItemDelegate(QObject *parent)
: QStyledItemDelegate(parent) : QStyledItemDelegate(parent)
{ {
} }
QString BCValueDelegate::displayText(const QVariant& dataValue, const QLocale& locale) const QString BCItemDelegate::displayText(const QVariant& dataValue, const QLocale& locale) const
{ {
// Wir prüfen, ob im Variant unser Struct steckt // Wir prüfen, ob im Variant unser Struct steckt
if (dataValue.canConvert<BCValue>()) if (dataValue.canConvert<BCValue>())
@@ -34,7 +34,7 @@ QString BCValueDelegate::displayText(const QVariant& dataValue, const QLocale& l
} }
QWidget *BCValueDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const QWidget *BCItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
QVariant rawData = index.data(Qt::EditRole); QVariant rawData = index.data(Qt::EditRole);
if (!rawData.canConvert<BCValue>()) if (!rawData.canConvert<BCValue>())
@@ -82,7 +82,7 @@ QWidget *BCValueDelegate::createEditor(QWidget *parent, const QStyleOptionViewIt
return QStyledItemDelegate::createEditor(parent, option, index); return QStyledItemDelegate::createEditor(parent, option, index);
} }
void BCValueDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const void BCItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{ {
// Daten vom Model in den Editor laden // Daten vom Model in den Editor laden
BCValue bc = index.data(Qt::EditRole).value<BCValue>(); BCValue bc = index.data(Qt::EditRole).value<BCValue>();
@@ -101,7 +101,7 @@ void BCValueDelegate::setEditorData(QWidget *editor, const QModelIndex &index) c
} }
} }
void BCValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const void BCItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{ {
// Daten vom Editor zurück ins Model speichern (Beim Schließen) // Daten vom Editor zurück ins Model speichern (Beim Schließen)
QSlider *slider = editor->findChild<QSlider*>("slider"); QSlider *slider = editor->findChild<QSlider*>("slider");
@@ -114,12 +114,12 @@ void BCValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, c
} }
} }
void BCValueDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const void BCItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
editor->setGeometry(option.rect); editor->setGeometry(option.rect);
} }
QSize BCValueDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const QSize BCItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
return QStyledItemDelegate::sizeHint(option,index); return QStyledItemDelegate::sizeHint(option,index);
/* /*
@@ -132,7 +132,7 @@ QSize BCValueDelegate::sizeHint(const QStyleOptionViewItem &option, const QModel
*/ */
} }
QString BCValueDelegate::formatDisplayString(const QModelIndex &index) const QString BCItemDelegate::formatDisplayString(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return QString(); return QString();

View File

@@ -1,17 +1,17 @@
// BCValueDelegate.h // BCItemDelegate.h
#ifndef BCVALUEDELEGATE_H #ifndef BCITEMDELEGATE_H
#define BCVALUEDELEGATE_H #define BCITEMDELEGATE_H
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
class BCValueDelegate : public QStyledItemDelegate class BCItemDelegate : public QStyledItemDelegate
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit BCValueDelegate(QObject *parent = nullptr); explicit BCItemDelegate(QObject *parent = nullptr);
// WICHTIG: Zuständig für die normale Anzeige (ohne Editor) // WICHTIG: Zuständig für die normale Anzeige (ohne Editor)
QString displayText(const QVariant& dataValue, const QLocale& locale) const override; QString displayText(const QVariant& dataValue, const QLocale& locale) const override;
@@ -29,4 +29,4 @@ private:
}; };
#endif // BCVALUEDELEGATE_H #endif // BCITEMDELEGATE_H

View File

@@ -28,7 +28,7 @@
***************************************************************************/ ***************************************************************************/
#include <bcmainwindow.h> #include <bcmainwindow.h>
#include <bcvaluedelegate.h> #include <bcitemdelegate.h>
#include <ui_bcmainwindow.h> #include <ui_bcmainwindow.h>
BCMainWindow::BCMainWindow(QWidget *parent) BCMainWindow::BCMainWindow(QWidget *parent)
@@ -39,7 +39,7 @@ BCMainWindow::BCMainWindow(QWidget *parent)
auto model = _valueManager.getModel( "Console"_L1 ); auto model = _valueManager.getModel( "Console"_L1 );
if( model) if( model)
_valueView->setModel( *model ); _valueView->setModel( *model );
_valueView->setItemDelegate( new BCValueDelegate( _valueView) ); _valueView->setItemDelegate( new BCItemDelegate( _valueView) );
connect( _connectButton, &QPushButton::clicked, &_valueManager, &BCValueManager::onToggleConnectionState ); connect( _connectButton, &QPushButton::clicked, &_valueManager, &BCValueManager::onToggleConnectionState );
} }

View File

@@ -47,15 +47,56 @@ using namespace Qt::StringLiterals;
BCValueManager::BCValueManager() BCValueManager::BCValueManager()
{ {
qRegisterMetaType<BCValue>("BCValue");
_transmitter.moveToThread(&_worker);
// 4. Verbindungen herstellen (Signal/Slot über Thread-Grenzen)
// A) Befehl senden (Manager -> Runner)
connect(this, &BCValueManager::newCommandArrived, &_transmitter, &BCTransmitter::addCommand);
// B) Ergebnisse empfangen (Runner -> Manager)
connect(&_transmitter, &BCTransmitter::commandFinished, this, &BCValueManager::onCommandFinished);
connect(&_transmitter, &BCTransmitter::messageLogged, this, &BCValueManager::onRunnerMessage);
// C) Aufräumen: Wenn Thread endet, lösche den Runner
connect(&_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
// 5. Thread starten
_worker.start();
} }
BCValueManager::~BCValueManager() BCValueManager::~BCValueManager()
{ {
// nothing to do here for now, // nothing to do here for now,
// our models are autokilled. // our models are autokilled.
_worker.quit(); // Event Loop stoppen
_worker.wait(); // Warten bis Thread wirklich fertig ist
} }
void BCValueManager::transmitValue(const BCValue& value)
{
// Wir rufen keine Methode am Runner direkt auf!
// Wir emitten ein Signal. Qt kümmert sich um den Thread-Wechsel.
emit newCommandArrived(value);
}
void BCValueManager::onCommandFinished(int id, bool success)
{
qDebug() << "[Manager] Command" << id << "finished. Success:" << success;
}
void BCValueManager::onRunnerMessage(const QString &msg)
{
qDebug() << "[Worker says]:" << msg;
}
void BCValueManager::onToggleConnectionState( bool connect ) void BCValueManager::onToggleConnectionState( bool connect )
{ {
if( connect ) if( connect )
@@ -69,7 +110,8 @@ void BCValueManager::onToggleConnectionState( bool connect )
{ {
qDebug() << "Console not responding"; qDebug() << "Console not responding";
} }
else { else
{
/* /*
swVersion = getValue(CONSOLE, CONSOLE_REF_SW); swVersion = getValue(CONSOLE, CONSOLE_REF_SW);
printf( "Console information:" _NL printf( "Console information:" _NL

View File

@@ -36,8 +36,10 @@
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QMetaEnum> #include <QMetaEnum>
#include <bcvaluemodel.h> #include <QThread>
#include <bcdatamodel.h>
#include <bccandrivertinycan.h> #include <bccandrivertinycan.h>
#include <bctransmitter.h>
class BCValueManager : public QObject class BCValueManager : public QObject
{ {
@@ -45,13 +47,16 @@ class BCValueManager : public QObject
public: public:
BCValueManager(); BCValueManager( );
virtual ~BCValueManager(); virtual ~BCValueManager();
std::optional<BCValueModel*> getModel(const QString& key ); std::optional<BCValueModel*> getModel(const QString& key );
BCValue makeValue(BCDevice::ID deviceID, const BCValueParams& params ); BCValue makeValue(BCDevice::ID deviceID, const BCValueParams& params );
// Public API für die Applikation
void transmitValue( const BCValue& value);
public slots: public slots:
void loadXml(); void loadXml();
@@ -60,6 +65,14 @@ public slots:
signals: signals:
// Internes Signal, um Daten an den Worker Thread zu senden
void newCommandArrived(BCValue cmd);
private slots:
// Slots für Rückmeldungen vom Runner
void onCommandFinished(int id, bool success);
void onRunnerMessage(const QString &msg);
protected: protected:
@@ -71,6 +84,10 @@ protected:
QMetaEnum _bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()}; QMetaEnum _bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};
BCCanDriverTinyCan _canDriver; BCCanDriverTinyCan _canDriver;
QThread _worker;
BCTransmitter _transmitter;
}; };
#endif // BCVALUEMANAGER_H #endif // BCVALUEMANAGER_H