LCOV - code coverage report
Current view: top level - src/MIDI_Interfaces/BLEMIDI - ThreadedBLEMIDISender.hpp (source / functions) Hit Total Coverage
Test: 169c36a3797bc662d84b5726f34a3f37d3c58247 Lines: 2 2 100.0 %
Date: 2024-11-09 15:32:27 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <Settings/NamespaceSettings.hpp>
       4             : 
       5             : #include <chrono>
       6             : #include <condition_variable>
       7             : #include <mutex>
       8             : #include <thread>
       9             : 
      10             : #include "BLEAPI.hpp"
      11             : #include <MIDI_Interfaces/BLEMIDI/BLEMIDIPacketBuilder.hpp>
      12             : 
      13             : BEGIN_CS_NAMESPACE
      14             : 
      15             : /// Class that manages a background thread that sends BLE packets asynchronously.
      16             : template <class Derived>
      17             : class ThreadedBLEMIDISender {
      18             :   public:
      19          58 :     ThreadedBLEMIDISender() = default;
      20             :     ThreadedBLEMIDISender(const ThreadedBLEMIDISender &) = delete;
      21             :     ThreadedBLEMIDISender &operator=(const ThreadedBLEMIDISender &) = delete;
      22             :     ~ThreadedBLEMIDISender();
      23             : 
      24             :     /// Start the background thread.
      25             :     void begin();
      26             : 
      27             :     struct ProtectedBuilder;
      28             : 
      29             :     /// Acquire exclusive access to the buffer to be sent by the timer.
      30             :     /// @return A RAII wrapper that automatically releases the buffer upon
      31             :     ///         destruction. Just make sure you don't keep any pointers to the
      32             :     ///         `packet` member.
      33             :     ProtectedBuilder acquirePacket();
      34             :     /// Release exclusive access to the buffer and notify the sender thread that
      35             :     /// data is available.
      36             :     void releasePacketAndNotify(ProtectedBuilder &lck);
      37             : 
      38             :     /// Sends the data immediately without waiting for the timeout.
      39             :     void sendNow(ProtectedBuilder &lck);
      40             : 
      41             :     /// Set the maximum transmission unit of the Bluetooth link. Used to compute
      42             :     /// the MIDI BLE packet size.
      43             :     void updateMTU(uint16_t mtu);
      44             :     /// Get the minimum MTU of all connected clients.
      45             :     uint16_t getMinMTU() const { return min_mtu; }
      46             :     /// Force the MTU to an artificially small value (used for testing).
      47             :     void forceMinMTU(uint16_t mtu);
      48             : 
      49             :     /// Set the timeout, the number of milliseconds to buffer the outgoing MIDI
      50             :     /// messages.
      51             :     void setTimeout(std::chrono::milliseconds timeout);
      52             : 
      53             :   private:
      54             :     /// Actually perform the BLE notification with the given data.
      55             :     void sendData(BLEDataView) = delete; // should be implemented by subclass
      56             : 
      57             :     /// Function that waits for BLE packets and sends them in the background.
      58             :     /// It either sends them after a timeout (a given number of milliseconds
      59             :     /// after the first data was added to the packet), or immediately when it
      60             :     /// receives a flush signal from the main thread.
      61             :     bool handleSendEvents();
      62             : 
      63             :   private:
      64             :     struct {
      65             :         /// View of the data to send
      66             :         BLEMIDIPacketBuilder packet;
      67             :         /// Flag to stop the background thread.
      68             :         bool stop = false;
      69             :         /// Flag to tell the sender thread to send the packet immediately.
      70             :         bool flush = false;
      71             :         /// Timeout before the sender thread sends a packet.
      72             :         /// @see @ref setTimeout()
      73          29 :         std::chrono::milliseconds timeout {10};
      74             :         /// Lock to protect all shared data in this struct.
      75             :         std::mutex mtx;
      76             :     } shared {};
      77             :     /// Condition variable used by the background sender thread to wait for
      78             :     /// data to send, and for the main thread to wait for the data to be flushed
      79             :     /// by the sender thread.
      80             :     std::condition_variable cv;
      81             :     /// Lock type used to lock the mutex
      82             :     using lock_t = std::unique_lock<std::mutex>;
      83             :     /// The background thread responsible for sending the data.
      84             :     std::thread send_thread;
      85             : 
      86             :   private:
      87             :     /// The minimum MTU of all connected clients.
      88             :     std::atomic_uint_fast16_t min_mtu {23};
      89             :     /// Override the minimum MTU (0 means don't override, nonzero overrides if
      90             :     /// it's smaller than the minimum MTU of the clients).
      91             :     /// @see    @ref forceMinMTU()
      92             :     std::atomic_uint_fast16_t force_min_mtu {515};
      93             : 
      94             :   public:
      95             :     struct ProtectedBuilder {
      96             :         BLEMIDIPacketBuilder *packet;
      97             :         lock_t lck;
      98             :     };
      99             : };
     100             : 
     101             : END_CS_NAMESPACE
     102             : 
     103             : #include "ThreadedBLEMIDISender.ipp"

Generated by: LCOV version 1.15