diff --git a/README.md b/README.md index 5c08da1..d89cb62 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,8 @@ new call with different data is sent before the previous interval is up. Sending a frame with an interval of -1 will cancel the repeat, and not send the frame. Sending with an interval of 0 will schedule the new frame once, then stop -repeating. +repeating. Unlike with a positive interval, an interval of 0 +guarantees that each new message will be sent. ## Build Requirements diff --git a/src/main/native/include/rev/Drivers/DriverDeviceThread.h b/src/main/native/include/rev/Drivers/DriverDeviceThread.h index b01d7ff..c56d553 100644 --- a/src/main/native/include/rev/Drivers/DriverDeviceThread.h +++ b/src/main/native/include/rev/Drivers/DriverDeviceThread.h @@ -75,9 +75,9 @@ class DriverDeviceThread { } } - detail::CANThreadSendQueueElement* findFirstMatchingId(int targetId) { + detail::CANThreadSendQueueElement* findFirstMatchingIdWithNonZeroInterval(int targetId) { for (auto& element : m_sendQueue) { - if (element.m_msg.GetMessageId() == targetId) { + if (element.m_msg.GetMessageId() == targetId && element.m_intervalMs > 0) { return &element; } } @@ -91,13 +91,25 @@ class DriverDeviceThread { bool EnqueueMessage(const CANMessage& msg, int32_t timeIntervalMs) { std::lock_guard lock(m_writeMutex); - detail::CANThreadSendQueueElement* existing = findFirstMatchingId(msg.GetMessageId()); + if(timeIntervalMs == 0) { + // If the time interval is 0, we want to allow duplicates. + m_sendQueue.push_back(detail::CANThreadSendQueueElement(msg, timeIntervalMs)); - if(existing) { - existing->m_intervalMs = timeIntervalMs; - existing->m_msg = msg; + // Cancel existing repeating frame with same id + detail::CANThreadSendQueueElement* existing = findFirstMatchingIdWithNonZeroInterval(msg.GetMessageId()); + if(existing) { + existing->m_intervalMs = -1; + } } else { - m_sendQueue.push_back(detail::CANThreadSendQueueElement(msg, timeIntervalMs)); + // We don't want to replace elements with zero as the interval. Those should be guaranteed to be sent + detail::CANThreadSendQueueElement* existing = findFirstMatchingIdWithNonZeroInterval(msg.GetMessageId()); + + if(existing) { + existing->m_intervalMs = timeIntervalMs; + existing->m_msg = msg; + } else { + m_sendQueue.push_back(detail::CANThreadSendQueueElement(msg, timeIntervalMs)); + } } // TODO: Limit the max queue size