#pragma once #include #include #include #include struct CalibrationData; // forward declare class ProximityAlgorithm { public: explicit ProximityAlgorithm(int avgLength = 8); // Configure with calibration data (called from reader thread on connect/reconnect) void Reset(const CalibrationData& cal); // Process one HID sample (already cal-subtracted by firmware) void ProcessSample(uint16_t hid_distance); // Lock-free read (called from RunFrame on main thread) bool GetPersonDetected() const; // Diagnostic snapshot (called from HandlePipeCommand) struct DiagState { uint32_t averaged_prox; bool detected; uint16_t effective_threshold; uint32_t total_samples; }; DiagState GetDiagState() const; private: int m_averageLength; // Calibration (set on Reset, used only from reader thread) uint16_t m_trimmedThreshold = 0; uint16_t m_hysteresis = 100; // Circular buffer (reader thread only) std::vector m_buffer; int m_writeIndex = 0; // Output (atomic for cross-thread reads) std::atomic m_personDetected{false}; // Diagnostics (mutex-protected for multi-field consistency) mutable std::mutex m_diagMutex; uint32_t m_averagedProx = 0; uint32_t m_totalSamples = 0; };