#include "IR_Decoder.h" std::list &IR_Decoder::get_dec_list() // определение функции { static std::list dec_list; // статическая локальная переменная return dec_list; // возвращается ссылка на переменную } // IR_Decoder::IR_Decoder() {}; IR_Decoder::IR_Decoder(const uint8_t pin, uint16_t addr, IR_Encoder *encPair, bool autoHandle) : IR_DecoderRaw(pin, addr, encPair) { get_dec_list().push_back(this); if(autoHandle){ enable(); } }; void IR_Decoder::enable() { auto &dec_list = get_dec_list(); if (std::find(dec_list.begin(), dec_list.end(), this) == dec_list.end()) { dec_list.push_back(this); } pinMode(pin, INPUT_PULLUP); attachInterrupt(pin, (*this)(), CHANGE); } void IR_Decoder::disable() { detachInterrupt(pin); pinMode(pin, INPUT); auto &dec_list = get_dec_list(); auto it = std::find(dec_list.begin(), dec_list.end(), this); if (it != dec_list.end()) { dec_list.erase(it); } } std::function IR_Decoder::operator()() { return std::bind(&IR_Decoder::isr, this); } IR_Decoder::~IR_Decoder() { IR_Decoder::get_dec_list().remove(this); } void IR_Decoder::tick() { for (const auto &element : IR_Decoder::get_dec_list()) { element->_tick(); } } void IR_Decoder::_tick() { IR_DecoderRaw::tick(); if (availableRaw()) { #ifdef IRDEBUG_INFO Serial.println("PARSING RAW DATA"); #endif isWaitingAcceptSend = false; switch (packInfo.buffer[0] >> 5 & IR_MASK_MSG_TYPE) { case IR_MSG_DATA_ACCEPT: case IR_MSG_DATA_NOACCEPT: gotData.set(&packInfo, id); break; case IR_MSG_BACK: case IR_MSG_BACK_TO: gotBackData.set(&packInfo, id); break; case IR_MSG_REQUEST: gotRequest.set(&packInfo, id); break; case IR_MSG_ACCEPT: gotAccept.set(&packInfo, id); break; default: break; } if (gotData.isAvailable && (gotData.getMsgType() == IR_MSG_DATA_ACCEPT)) { acceptSendTimer = millis(); addrAcceptSendTo = gotData.getAddrFrom(); acceptCustomByte = crc8(gotData.getDataPrt(), 0, gotData.getDataSize(), poly1); if (addrAcceptSendTo && addrAcceptSendTo < IR_Broadcast) isWaitingAcceptSend = true; } gotRaw.set(&packInfo, id); } if (isWaitingAcceptSend && millis() - acceptSendTimer > 75) { encoder->sendAccept(addrAcceptSendTo, acceptCustomByte); isWaitingAcceptSend = false; } }