Syncrhonize slot() calls
-
Hi,
Im using QSerialPort to communicate with an hardware platform Im developing and for each packet sent I wait for an ACK.
Whenever the value of a QSpinBox is changed a new packet is sent to the platform. Im doing this with a queue in between, so I can be sure only one packet is sent at a time and that I wait for the corresponding ACK. So I have one class that is responsible to insert packets into that queue, emiting packetReady(), signal, and then in the other class I have the slot slotPacketReady where Im doing this:@void Connection::slotFrameReady()
{
while(packetsToSend()->count() > 0)
{
QByteArray packet = packetsToSend()->dequeue();
qDebug() << "SENDING...";
sendPacket(packet);
waitForACK();
}
}@However, if the QSpinBox's value changes too fast, and as far as I can understand, the slotPacketReady() is called multiple times NOT waiting for the ACK of the previously sent packet.
=========
SENDING... // here I wait until I get the ACK
sendPacket
waitForACK
ACK id 17 code 58 type 1
acknowledged! "id:17 type:1 code:58"
elapsed time: 92SENDING... // then I scroll the mouse wheel fast so the QSpinBox's value changes fast
sendPacket
waitForACKSENDING...
sendPacket
waitForACKSENDING...
sendPacket
waitForACK// Communication gets scrambled because the embedded buffer of the platform gets full and data is lost...
=========
So my question is: how can I avoid the slotPacketReady() being called multiple times? Actually I want this behavior: "call the slot only if it's not already running (while(packetsToSend()->count() > 0)".
-
I see at least two solutions:
- Block your spinbox for the time of sending (I understand that waitForACK processes the events and this way you get redundand events)
- Synchronise your 'in between' buffer to be read after ACK response received, not for every spinbox event. But here you probably need to run another thread which reads/sends your data.