// CEventQueue.h // Fester Ring-Buffer FIFO für SEvent-Objekte. // // Bewusst ohne Heap (kein new/delete) und ohne STL (kein std::vector/queue) // um auf dem SAMD21 mit 16KB RAM deterministisches Verhalten zu garantieren. // // Kapazität: QUEUE_SIZE - 1 = 16 Events (ein Slot bleibt leer damit // is_full() und is_empty() ohne extra Zähler unterscheidbar sind). // // Nebenläufigkeit: // push() wird aus Encoder-ISRs und aus dem Matrixcallback im Loop aufgerufen. // Der Matrixcallback maskiert Interrupts während push(); Encoder-ISRs können // sich auf dem Single-Core-M0+ nicht gleichpriorisiert gegenseitig unterbrechen. // pop() läuft im Loop; ein gleichzeitig eintreffender Push wird spätestens // im nächsten processEvents()-Durchlauf sichtbar. #pragma once #include "SEvent.h" #include class CEventQueue { public: // Event einreihen. Gibt false zurück wenn Queue voll (Event wird verworfen). bool push(SEvent ev); // Ältestes Event abholen (FIFO). Gibt false zurück wenn Queue leer. bool pop(SEvent& out); bool is_empty() const; bool is_full() const; private: static const uint8_t QUEUE_SIZE = 17; // 16 nutzbare Slots SEvent m_buf[QUEUE_SIZE]; volatile uint8_t m_head = 0; // Nächster Lese-Index (Consumer: pop) volatile uint8_t m_tail = 0; // Nächster Schreib-Index (Producer: push) };