esp32-nmea2000-obp60/lib/converterlist/ConverterList.h

212 lines
6.5 KiB
C++

#ifndef _NMEA0183CONVERTERLIST_H
#define _NMEA0183CONVERTERLIST_H
#include "WString.h"
#include "GwJsonDocument.h"
#include <map>
template <class T, class Msg>
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<String, ConverterEntry> 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