#pragma once #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include #include class WithTransaction { protected: virtual esp_err_t end_transaction_() = 0; virtual esp_err_t begin_transaction_(TickType_t timeout, uint32_t& out_id) = 0; friend class TransactionGuard; }; class TransactionGuard { public: TransactionGuard(WithTransaction& handler, TickType_t timeout = portMAX_DELAY) : handler_(handler) { } ~TransactionGuard() { if (transaction_id_) handler_.end_transaction_(); } esp_err_t begin(TickType_t timeout = portMAX_DELAY) { esp_err_t err = handler_.begin_transaction_(timeout, transaction_id_); return err; } uint32_t transaction_id() const { return transaction_id_; } bool is_active() const { return transaction_id_ != 0; } private: // delete copy constructor and assignment operator TransactionGuard(const TransactionGuard&) = delete; TransactionGuard& operator=(const TransactionGuard&) = delete; WithTransaction& handler_; uint32_t transaction_id_ = 0; };