intermediate: reorganize boatData code
This commit is contained in:
parent
f5fcfa25c3
commit
3944735190
|
@ -1,4 +1,153 @@
|
||||||
#include "GwBoatData.h"
|
#include "GwBoatData.h"
|
||||||
|
#define GWTYPE_DOUBLE 1
|
||||||
|
#define GWTYPE_UINT32 2
|
||||||
|
#define GWTYPE_UINT16 3
|
||||||
|
#define GWTYPE_INT16 4
|
||||||
|
#define GWTYPE_USER 100
|
||||||
|
class GwBoatItemTypes{
|
||||||
|
public:
|
||||||
|
static int getType(const uint32_t &x){return GWTYPE_UINT32;}
|
||||||
|
static int getType(const uint16_t &x){return GWTYPE_UINT16;}
|
||||||
|
static int getType(const int16_t &x){return GWTYPE_INT16;}
|
||||||
|
static int getType(const double &x){return GWTYPE_DOUBLE;}
|
||||||
|
static int getType(const GwSatInfoList &x){ return GWTYPE_USER+1;}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool GwBoatItemBase::isValid(unsigned long now) const
|
||||||
|
{
|
||||||
|
if (lastSet == 0)
|
||||||
|
return false;
|
||||||
|
if (invalidTime == 0)
|
||||||
|
return true;
|
||||||
|
if (now == 0)
|
||||||
|
now = millis();
|
||||||
|
return (lastSet + invalidTime) >= now;
|
||||||
|
}
|
||||||
|
GwBoatItemBase::GwBoatItemBase(String name, String format, unsigned long invalidTime)
|
||||||
|
{
|
||||||
|
lastSet = 0;
|
||||||
|
this->invalidTime = invalidTime;
|
||||||
|
this->name = name;
|
||||||
|
this->format = format;
|
||||||
|
this->type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> GwBoatItem<T>::GwBoatItem(String name,String formatInfo,unsigned long invalidTime,GwBoatItemMap *map):
|
||||||
|
GwBoatItemBase(name,formatInfo,invalidTime){
|
||||||
|
T dummy;
|
||||||
|
this->type=GwBoatItemTypes::getType(dummy);
|
||||||
|
if (map){
|
||||||
|
(*map)[name]=this;
|
||||||
|
}
|
||||||
|
lastUpdateSource=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool GwBoatItem<T>::update(T nv, int source)
|
||||||
|
{
|
||||||
|
unsigned long now = millis();
|
||||||
|
if (isValid(now))
|
||||||
|
{
|
||||||
|
//priority handling
|
||||||
|
//sources with lower ids will win
|
||||||
|
//and we will not overwrite their value
|
||||||
|
if (lastUpdateSource < source && lastUpdateSource >= 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = nv;
|
||||||
|
lastUpdateSource = source;
|
||||||
|
uls(now);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
bool GwBoatItem<T>::updateMax(T nv, int sourceId)
|
||||||
|
{
|
||||||
|
unsigned long now = millis();
|
||||||
|
if (!isValid(now))
|
||||||
|
{
|
||||||
|
return update(nv, sourceId);
|
||||||
|
}
|
||||||
|
if (getData() < nv)
|
||||||
|
{
|
||||||
|
data = nv;
|
||||||
|
lastUpdateSource = sourceId;
|
||||||
|
uls(now);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void GwBoatItem<T>::toJsonDoc(JsonDocument *doc, unsigned long minTime)
|
||||||
|
{
|
||||||
|
JsonObject o = doc->createNestedObject(name);
|
||||||
|
o[F("value")] = getData();
|
||||||
|
o[F("update")] = minTime - lastSet;
|
||||||
|
o[F("source")] = lastUpdateSource;
|
||||||
|
o[F("valid")] = isValid(minTime);
|
||||||
|
o[F("format")] = format;
|
||||||
|
}
|
||||||
|
template class GwBoatItem<double>;
|
||||||
|
template class GwBoatItem<uint32_t>;
|
||||||
|
template class GwBoatItem<uint16_t>;
|
||||||
|
template class GwBoatItem<int16_t>;
|
||||||
|
void GwSatInfoList::houseKeeping(unsigned long ts)
|
||||||
|
{
|
||||||
|
if (ts == 0)
|
||||||
|
ts = millis();
|
||||||
|
sats.erase(std::remove_if(
|
||||||
|
sats.begin(),
|
||||||
|
sats.end(),
|
||||||
|
[ts, this](const GwSatInfo &info)
|
||||||
|
{
|
||||||
|
return (info.timestamp + lifeTime) < ts;
|
||||||
|
}),
|
||||||
|
sats.end());
|
||||||
|
}
|
||||||
|
void GwSatInfoList::update(GwSatInfo entry)
|
||||||
|
{
|
||||||
|
unsigned long now = millis();
|
||||||
|
entry.timestamp = now;
|
||||||
|
for (auto it = sats.begin(); it != sats.end(); it++)
|
||||||
|
{
|
||||||
|
if (it->PRN == entry.PRN)
|
||||||
|
{
|
||||||
|
*it = entry;
|
||||||
|
houseKeeping();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
houseKeeping();
|
||||||
|
sats.push_back(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
GwBoatDataSatList::GwBoatDataSatList(String name, String formatInfo, unsigned long invalidTime , GwBoatItemMap *map) :
|
||||||
|
GwBoatItem<GwSatInfoList>(name, formatInfo, invalidTime, map) {}
|
||||||
|
|
||||||
|
bool GwBoatDataSatList::update(GwSatInfo info, int source)
|
||||||
|
{
|
||||||
|
unsigned long now = millis();
|
||||||
|
if (isValid(now))
|
||||||
|
{
|
||||||
|
//priority handling
|
||||||
|
//sources with lower ids will win
|
||||||
|
//and we will not overwrite their value
|
||||||
|
if (lastUpdateSource < source)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastUpdateSource = source;
|
||||||
|
uls(now);
|
||||||
|
data.update(info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void GwBoatDataSatList::toJsonDoc(JsonDocument *doc, unsigned long minTime)
|
||||||
|
{
|
||||||
|
data.houseKeeping();
|
||||||
|
GwBoatItem<GwSatInfoList>::toJsonDoc(doc, minTime);
|
||||||
|
}
|
||||||
|
|
||||||
GwBoatData::GwBoatData(GwLog *logger){
|
GwBoatData::GwBoatData(GwLog *logger){
|
||||||
this->logger=logger;
|
this->logger=logger;
|
||||||
|
@ -23,7 +172,7 @@ template<class T> GwBoatItem<T> *GwBoatData::getOrCreate(T initial, GwBoatItemNa
|
||||||
}
|
}
|
||||||
return (GwBoatItem<T>*)(it->second);
|
return (GwBoatItem<T>*)(it->second);
|
||||||
}
|
}
|
||||||
GwBoatItem<T> *rt=new GwBoatItem<T>(GwBoatItemTypes::getType(initial), name,
|
GwBoatItem<T> *rt=new GwBoatItem<T>(name,
|
||||||
provider->getBoatItemFormat(),
|
provider->getBoatItemFormat(),
|
||||||
provider->getInvalidTime(),
|
provider->getInvalidTime(),
|
||||||
&values);
|
&values);
|
||||||
|
@ -101,4 +250,19 @@ double mtr2nm(double m)
|
||||||
|
|
||||||
bool convertToJson(const GwSatInfoList &si,JsonVariant &variant){
|
bool convertToJson(const GwSatInfoList &si,JsonVariant &variant){
|
||||||
return variant.set(si.getNumSats());
|
return variant.set(si.getNumSats());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _UNDEF
|
||||||
|
#include <ArduinoJson/Json/TextFormatter.hpp>
|
||||||
|
|
||||||
|
class XWriter{
|
||||||
|
public:
|
||||||
|
void write(uint8_t c) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(const uint8_t* s, size_t n) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static XWriter xwriter;
|
||||||
|
ARDUINOJSON_NAMESPACE::TextFormatter<XWriter> testWriter(xwriter);
|
||||||
|
#endif
|
|
@ -7,18 +7,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#define GW_BOAT_VALUE_LEN 32
|
#define GW_BOAT_VALUE_LEN 32
|
||||||
#define GWSC(name) static constexpr const __FlashStringHelper* name=F(#name)
|
#define GWSC(name) static constexpr const __FlashStringHelper* name=F(#name)
|
||||||
#define GWTYPE_DOUBLE 1
|
|
||||||
#define GWTYPE_UINT32 2
|
|
||||||
#define GWTYPE_UINT16 3
|
|
||||||
#define GWTYPE_INT16 4
|
|
||||||
#define GWTYPE_USER 100
|
|
||||||
class GwBoatItemTypes{
|
|
||||||
public:
|
|
||||||
static int getType(const uint32_t &x){return GWTYPE_UINT32;}
|
|
||||||
static int getType(const uint16_t &x){return GWTYPE_UINT16;}
|
|
||||||
static int getType(const int16_t &x){return GWTYPE_INT16;}
|
|
||||||
static int getType(const double &x){return GWTYPE_DOUBLE;}
|
|
||||||
};
|
|
||||||
class GwBoatItemBase{
|
class GwBoatItemBase{
|
||||||
public:
|
public:
|
||||||
static const unsigned long INVALID_TIME=60000;
|
static const unsigned long INVALID_TIME=60000;
|
||||||
|
@ -49,19 +38,8 @@ class GwBoatItemBase{
|
||||||
public:
|
public:
|
||||||
int getCurrentType(){return type;}
|
int getCurrentType(){return type;}
|
||||||
unsigned long getLastSet() const {return lastSet;}
|
unsigned long getLastSet() const {return lastSet;}
|
||||||
bool isValid(unsigned long now=0) const {
|
bool isValid(unsigned long now=0) const ;
|
||||||
if (lastSet == 0) return false;
|
GwBoatItemBase(String name,String format,unsigned long invalidTime=INVALID_TIME);
|
||||||
if (invalidTime == 0) return true;
|
|
||||||
if (now == 0) now=millis();
|
|
||||||
return (lastSet + invalidTime) >= now;
|
|
||||||
}
|
|
||||||
GwBoatItemBase(String name,String format,unsigned long invalidTime=INVALID_TIME){
|
|
||||||
lastSet=0;
|
|
||||||
this->invalidTime=invalidTime;
|
|
||||||
this->name=name;
|
|
||||||
this->format=format;
|
|
||||||
this->type=0;
|
|
||||||
}
|
|
||||||
virtual ~GwBoatItemBase(){}
|
virtual ~GwBoatItemBase(){}
|
||||||
void invalidate(){
|
void invalidate(){
|
||||||
lastSet=0;
|
lastSet=0;
|
||||||
|
@ -78,43 +56,10 @@ template<class T> class GwBoatItem : public GwBoatItemBase{
|
||||||
T data;
|
T data;
|
||||||
int lastUpdateSource;
|
int lastUpdateSource;
|
||||||
public:
|
public:
|
||||||
GwBoatItem(int type,String name,String formatInfo,unsigned long invalidTime=INVALID_TIME,GwBoatItemMap *map=NULL):
|
GwBoatItem(String name,String formatInfo,unsigned long invalidTime=INVALID_TIME,GwBoatItemMap *map=NULL);
|
||||||
GwBoatItemBase(name,formatInfo,invalidTime){
|
|
||||||
this->type=type;
|
|
||||||
if (map){
|
|
||||||
(*map)[name]=this;
|
|
||||||
}
|
|
||||||
lastUpdateSource=-1;
|
|
||||||
}
|
|
||||||
virtual ~GwBoatItem(){}
|
virtual ~GwBoatItem(){}
|
||||||
bool update(T nv, int source=-1){
|
bool update(T nv, int source=-1);
|
||||||
unsigned long now=millis();
|
bool updateMax(T nv,int sourceId=-1);
|
||||||
if (isValid(now)){
|
|
||||||
//priority handling
|
|
||||||
//sources with lower ids will win
|
|
||||||
//and we will not overwrite their value
|
|
||||||
if (lastUpdateSource < source && lastUpdateSource >= 0){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data=nv;
|
|
||||||
lastUpdateSource=source;
|
|
||||||
uls(now);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool updateMax(T nv,int sourceId=-1){
|
|
||||||
unsigned long now=millis();
|
|
||||||
if (! isValid(now)){
|
|
||||||
return update(nv,sourceId);
|
|
||||||
}
|
|
||||||
if (getData() < nv){
|
|
||||||
data=nv;
|
|
||||||
lastUpdateSource=sourceId;
|
|
||||||
uls(now);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
T getData(){
|
T getData(){
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -122,14 +67,7 @@ template<class T> class GwBoatItem : public GwBoatItemBase{
|
||||||
if (! isValid(millis())) return defaultv;
|
if (! isValid(millis())) return defaultv;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
virtual void toJsonDoc(JsonDocument *doc, unsigned long minTime){
|
virtual void toJsonDoc(JsonDocument *doc, unsigned long minTime);
|
||||||
JsonObject o=doc->createNestedObject(name);
|
|
||||||
o[F("value")]=getData();
|
|
||||||
o[F("update")]=minTime-lastSet;
|
|
||||||
o[F("source")]=lastUpdateSource;
|
|
||||||
o[F("valid")]=isValid(minTime);
|
|
||||||
o[F("format")]=format;
|
|
||||||
}
|
|
||||||
virtual int getLastSource(){return lastUpdateSource;}
|
virtual int getLastSource(){return lastUpdateSource;}
|
||||||
};
|
};
|
||||||
double formatCourse(double cv);
|
double formatCourse(double cv);
|
||||||
|
@ -151,29 +89,8 @@ class GwSatInfoList{
|
||||||
public:
|
public:
|
||||||
static const unsigned long lifeTime=32000;
|
static const unsigned long lifeTime=32000;
|
||||||
std::vector<GwSatInfo> sats;
|
std::vector<GwSatInfo> sats;
|
||||||
void houseKeeping(unsigned long ts=0){
|
void houseKeeping(unsigned long ts=0);
|
||||||
if (ts == 0) ts=millis();
|
void update(GwSatInfo entry);
|
||||||
sats.erase(std::remove_if(
|
|
||||||
sats.begin(),
|
|
||||||
sats.end(),
|
|
||||||
[ts,this](const GwSatInfo &info){
|
|
||||||
return (info.timestamp + lifeTime) < ts;
|
|
||||||
}
|
|
||||||
),sats.end());
|
|
||||||
}
|
|
||||||
void update(GwSatInfo entry){
|
|
||||||
unsigned long now=millis();
|
|
||||||
entry.timestamp=now;
|
|
||||||
for (auto it=sats.begin();it!=sats.end();it++){
|
|
||||||
if (it->PRN == entry.PRN){
|
|
||||||
*it=entry;
|
|
||||||
houseKeeping();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
houseKeeping();
|
|
||||||
sats.push_back(entry);
|
|
||||||
}
|
|
||||||
int getNumSats() const{
|
int getNumSats() const{
|
||||||
return sats.size();
|
return sats.size();
|
||||||
}
|
}
|
||||||
|
@ -183,34 +100,12 @@ class GwSatInfoList{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool convertToJson(const GwSatInfoList &si,JsonVariant &variant);
|
|
||||||
class GwBoatDataSatList : public GwBoatItem<GwSatInfoList>
|
class GwBoatDataSatList : public GwBoatItem<GwSatInfoList>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GwBoatDataSatList(String name, String formatInfo, unsigned long invalidTime = INVALID_TIME, GwBoatItemMap *map = NULL) :
|
GwBoatDataSatList(String name, String formatInfo, unsigned long invalidTime = INVALID_TIME, GwBoatItemMap *map = NULL);
|
||||||
GwBoatItem<GwSatInfoList>(GWTYPE_USER+1, name, formatInfo, invalidTime, map) {}
|
bool update(GwSatInfo info, int source);
|
||||||
bool update(GwSatInfo info, int source)
|
virtual void toJsonDoc(JsonDocument *doc, unsigned long minTime);
|
||||||
{
|
|
||||||
unsigned long now = millis();
|
|
||||||
if (isValid(now))
|
|
||||||
{
|
|
||||||
//priority handling
|
|
||||||
//sources with lower ids will win
|
|
||||||
//and we will not overwrite their value
|
|
||||||
if (lastUpdateSource < source)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastUpdateSource = source;
|
|
||||||
uls(now);
|
|
||||||
data.update(info);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
virtual void toJsonDoc(JsonDocument *doc, unsigned long minTime){
|
|
||||||
data.houseKeeping();
|
|
||||||
GwBoatItem<GwSatInfoList>::toJsonDoc(doc,minTime);
|
|
||||||
}
|
|
||||||
GwSatInfo *getAt(int idx){
|
GwSatInfo *getAt(int idx){
|
||||||
if (! isValid()) return NULL;
|
if (! isValid()) return NULL;
|
||||||
return data.getAt(idx);
|
return data.getAt(idx);
|
||||||
|
@ -231,7 +126,7 @@ public:
|
||||||
virtual ~GwBoatItemNameProvider() {}
|
virtual ~GwBoatItemNameProvider() {}
|
||||||
};
|
};
|
||||||
#define GWBOATDATA(type,name,time,fmt) \
|
#define GWBOATDATA(type,name,time,fmt) \
|
||||||
GwBoatItem<type> *name=new GwBoatItem<type>(GwBoatItemTypes::getType((type)0),F(#name),GwBoatItemBase::fmt,time,&values) ;
|
GwBoatItem<type> *name=new GwBoatItem<type>(F(#name),GwBoatItemBase::fmt,time,&values) ;
|
||||||
#define GWSPECBOATDATA(clazz,name,time,fmt) \
|
#define GWSPECBOATDATA(clazz,name,time,fmt) \
|
||||||
clazz *name=new clazz(F(#name),GwBoatItemBase::fmt,time,&values) ;
|
clazz *name=new clazz(F(#name),GwBoatItemBase::fmt,time,&values) ;
|
||||||
class GwBoatData{
|
class GwBoatData{
|
||||||
|
|
Loading…
Reference in New Issue