#include #include #include BCTransmitter::BCTransmitter(QObject *parent) : QObject(parent), _isBusy(false) { } void BCTransmitter::onToggleConnectionState( bool connect ) { if( connect ) { if( BCCanDriver::sIdle == _canDriver.getState() ) _canDriver.onStartDriver(); int hwVersion = _canDriver.getValue( BCDevice::ID::Console, BC::ID::Cons_Rev_Hw); if (hwVersion == 0) { qDebug() << "Console not responding"; } else { /* swVersion = getValue(CONSOLE, CONSOLE_REF_SW); printf( "Console information:" _NL " hardware version ........: %02d" _NL " software version ........: %02d" _NL " assistance level ........: %d" _NL, hwVersion, swVersion, getValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL) ); if (!gNoSerialNumbers) printf( " part number .............: %05d" _NL " item number .............: %05d" _NL _NL, ((getValue(CONSOLE, CONSOLE_SN_PN_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_PN_LO)), ((getValue(CONSOLE, CONSOLE_SN_ITEM_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_ITEM_LO)) ); */ } qDebug() << " ---HAIL to the kings: " << hwVersion; } } void BCTransmitter::enqueueValueCommand(BC::OpID opID, const BCValue& value) { QMutexLocker locker(&_mutex); _valueQueue.enqueue( std::ref(value) ); // Logging (Thread-safe via Signal) //emit messageLogged(QString("Command %1 queued.").arg(cmd.label)); // wir wollen nicht den ganzen Value verschicken, erstrecht // wollen wir den Value in verschiedenen Threads gleichzeitig // in die Hand nehmen, also hantieren wir nur mit den Inidizes. // Trigger processing im Event-Loop des Worker Threads // invokeMethod mit QueuedConnection entkoppelt den Aufruf, // damit enqueueValueCommand sofort zurückkehrt (non-blocking für den Aufrufer). //QMetaObject::invokeMethod(this, "processValueCommand", Qt::QueuedConnection); QMetaObject::invokeMethod(this, [this, opID]() { this->processValueCommand(opID); }, Qt::QueuedConnection ); } void BCTransmitter::processValueCommand( BC::OpID opID ) { if (_isBusy) return; _isBusy = true; while (true) { BCValue currentValue; { QMutexLocker locker(&_mutex); if (_valueQueue.isEmpty()) { _isBusy = false; break; // Schleife verlassen, warten auf neue Events } currentValue =_valueQueue.dequeue(); } // Mutex wird hier freigegeben! WICHTIG: Execute ohne Lock! std::optional result; // 3. Ausführung (Dauert potentiell lange) if( opID == BC::OpID::ReadValue ) result = executeRead(currentValue); else if( opID == BC::OpID::WriteValue ) result = executeRead(currentValue); //emit commandFinished(cmd.id, true); //emit commandFinished(0, true); } } std::optional BCTransmitter::executeRead(const BCValue& value) { std::optional result; switch( value.deviceID ) { // hier lacht der blaue riesenhase! case BCDevice::ID::Invalid: case BCDevice::ID::Console: case BCDevice::ID::Console_Master: case BCDevice::ID::Battery: case BCDevice::ID::Motor: case BCDevice::ID::BIB: case BCDevice::ID::Sensor: break; }; } std::optional BCTransmitter::executeWrite(const BCValue& value) { }