#pragma once #include "Arduino.h" template class RingBuffer { public: RingBuffer() : start(0), end(0) {} bool isFull() const { return ((end + 1) % BufferSize) == start; } bool isEmpty() const { return start == end; } bool push(T element) { bool pushed = false; noInterrupts(); if (!isFull()) { data[end] = element; end = (end + 1) % BufferSize; pushed = true; } interrupts(); return pushed; } T* pop() { noInterrupts(); T* value = nullptr; if (!isEmpty()) { value = &data[start]; start = (start + 1) % BufferSize; } interrupts(); return value; } // B5: безопасный pop — копирует элемент под ОДНОЙ критсекцией и отдаёт по значению. // (T* pop() отдаёт указатель во внутренний слот; его внутренний interrupts() снимает внешнюю // защиту вызывающего ДО чтения *ptr → торн-рид, если кольцо переполнится в этом окне.) bool pop(T &out) { bool popped = false; noInterrupts(); if (!isEmpty()) { out = data[start]; start = (start + 1) % BufferSize; popped = true; } interrupts(); return popped; } private: T data[BufferSize]; unsigned int start, end; };