#ifndef _NMEA0183CONVERTERLIST_H #define _NMEA0183CONVERTERLIST_H #include "WString.h" #include "GwJsonDocument.h" #include template class ConverterList { public: typedef void (T::*Converter)(const Msg &msg); typedef void (*LConverter)(const Msg &msg, T *); private: String keyList; bool keyListFilled=false; class ConverterEntry { public: unsigned long count = 0; unsigned long *pgn; unsigned int numPgn = 0; Converter converter = NULL; LConverter lconverter = NULL; ConverterEntry() { pgn = NULL; converter = NULL; } ConverterEntry(int num,unsigned long *pgn, LConverter cv) { lconverter = cv; numPgn=num; this->pgn = pgn; } ConverterEntry(int num,unsigned long *pgn, Converter cv) { converter = cv; numPgn=num; this->pgn = pgn; } }; typedef std::map ConverterMap; ConverterMap converters; public: /** * register a converter * each of the converter functions must be registered in the constructor **/ void registerConverter(unsigned long pgn, Converter converter) { unsigned long *lpgn=new unsigned long[1]{pgn}; ConverterEntry e(1,lpgn, converter); converters[String(pgn)] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, LConverter converter) { unsigned long *lpgn=new unsigned long[1]{pgn}; ConverterEntry e(1,lpgn, converter); converters[String(pgn)] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, String sentence, Converter converter) { unsigned long *lpgn=new unsigned long[1]{pgn}; ConverterEntry e(1,lpgn, converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, String sentence, LConverter converter) { unsigned long *lpgn=new unsigned long[1]{pgn}; ConverterEntry e(1,lpgn, converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(int num,unsigned long *lpgn, String sentence, Converter converter) { ConverterEntry e(num,lpgn, converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(int num,unsigned long *lpgn, String sentence, LConverter converter) { ConverterEntry e(num,lpgn, converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, unsigned long pgn2, String sentence, Converter converter) { unsigned long *lpgn=new unsigned long[2]{pgn,pgn2}; ConverterEntry e(2, lpgn, converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, unsigned long pgn2, String sentence, LConverter converter) { unsigned long *lpgn=new unsigned long[2]{pgn,pgn2}; ConverterEntry e(2, lpgn, converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,String sentence, Converter converter) { unsigned long *lpgn=new unsigned long[3]{pgn,pgn2,pgn3}; ConverterEntry e(3, lpgn,converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,String sentence, LConverter converter) { unsigned long *lpgn=new unsigned long[3]{pgn,pgn2,pgn3}; ConverterEntry e(3, lpgn,converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,unsigned long pgn4,String sentence, Converter converter) { unsigned long *lpgn=new unsigned long[4]{pgn,pgn2,pgn3,pgn4}; ConverterEntry e(4, lpgn,converter); converters[sentence] = e; keyListFilled=false; } void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,unsigned long pgn4,String sentence, LConverter converter) { unsigned long *lpgn=new unsigned long[4]{pgn,pgn2,pgn3,pgn4}; ConverterEntry e(4, lpgn,converter); converters[sentence] = e; keyListFilled=false; } bool handleMessage(String code, const Msg &msg, T *base) { auto it = converters.find(code); if (it != converters.end()) { (it->second).count++; if (it->second.converter) { //call to member function - see e.g. https://isocpp.org/wiki/faq/pointers-to-members ((*base).*((it->second).converter))(msg); } else { (*(it->second).lconverter)(msg, base); } } else { return false; } return true; } virtual unsigned long *handledPgns() { //for now max 4 pgns per converter unsigned long *rt = new unsigned long[converters.size() * 4 + 1]; int idx = 0; for (auto it = converters.begin(); it != converters.end(); it++) { for (int i = 0; i < it->second.numPgn && i < 4; i++) { bool found = false; for (int e = 0; e < idx; e++) { if (rt[e] == it->second.pgn[i]) { found = true; break; } } if (!found) { rt[idx] = it->second.pgn[i]; idx++; } } } rt[idx] = 0; return rt; } int numConverters(){ return converters.size(); } void toJson(String prefix, GwJsonDocument *json){ for (auto it = converters.begin(); it != converters.end(); it++) { (*json)[prefix][String(it->first)] = it->second.count; } } String handledKeys(){ if (! keyListFilled){ keyList=String(); bool first=true; for (auto it=converters.begin();it != converters.end();it++){ if (! first) keyList.concat(','); first=false; keyList.concat(it->first); } keyListFilled=true; } return keyList; } }; #endif