change api for getBoatDataValues
This commit is contained in:
parent
461d4924ad
commit
7b4ab178c2
|
@ -5,13 +5,28 @@
|
|||
#include "NMEA0183Msg.h"
|
||||
#include "GWConfig.h"
|
||||
#include "GwBoatData.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
//API to be used for additional tasks
|
||||
class GwApi{
|
||||
public:
|
||||
typedef std::map<String,double> ValueMap;
|
||||
typedef std::vector<String> StringList;
|
||||
class BoatValue{
|
||||
const String name;
|
||||
String format;
|
||||
bool formatSet=false;
|
||||
public:
|
||||
double value=0;
|
||||
bool valid=false;
|
||||
BoatValue(){}
|
||||
BoatValue(String n):name(n){
|
||||
}
|
||||
void setFormat(const String &format){
|
||||
if (formatSet) return;
|
||||
this->format=format;
|
||||
formatSet=true;
|
||||
}
|
||||
const String & getName() const{
|
||||
return name;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* thread safe methods - can directly be called from a user task
|
||||
*/
|
||||
|
@ -31,13 +46,14 @@ class GwApi{
|
|||
virtual GwLog *getLogger()=0;
|
||||
virtual const char* getTalkerId()=0;
|
||||
/**
|
||||
* get a set of boat data values by their names
|
||||
* the returned map will have the keys being the strings in the names list
|
||||
* the values are the boat data values converted to double
|
||||
* invalid values are not returned in the map
|
||||
* this method is thread safe and can directly be used from a user task
|
||||
* get a set of boat data values
|
||||
* the provided list of BoatValue must be initialized with
|
||||
* empty boatValues (see exampleTask source code)
|
||||
* the method will fill the valid flag, the value and the format string of
|
||||
* each boat value
|
||||
* just make sure to have the list being of appropriate size (numValues)
|
||||
*/
|
||||
virtual ValueMap getBoatDataValues(StringList)=0;
|
||||
virtual void getBoatDataValues(int numValues,BoatValue **list)=0;
|
||||
/**
|
||||
* not thread safe methods
|
||||
* accessing boat data must only be executed from within the main thread
|
||||
|
|
|
@ -334,6 +334,11 @@ bool GwBoatData::isValid(String name){
|
|||
if (it == values.end()) return false;
|
||||
return it->second->isValid();
|
||||
}
|
||||
GwBoatItemBase* GwBoatData::getBase(String name){
|
||||
auto it=values.find(name);
|
||||
if (it == values.end()) return NULL;
|
||||
return it->second;
|
||||
}
|
||||
double GwBoatData::getDoubleValue(String name,double defaultv){
|
||||
auto it=values.find(name);
|
||||
if (it == values.end()) return defaultv;
|
||||
|
|
|
@ -71,7 +71,7 @@ class GwBoatItemBase{
|
|||
virtual void refresh(unsigned long ts=0){uls(ts);}
|
||||
virtual double getDoubleValue()=0;
|
||||
String getName(){return name;}
|
||||
String getFormat(){return format;}
|
||||
const String & getFormat() const{return format;}
|
||||
};
|
||||
class GwBoatData;
|
||||
template<class T> class GwBoatItem : public GwBoatItemBase{
|
||||
|
@ -208,6 +208,7 @@ class GwBoatData{
|
|||
template<class T> T getDataWithDefault(T defaultv, GwBoatItemNameProvider *provider);
|
||||
bool isValid(String name);
|
||||
double getDoubleValue(String name,double defaultv);
|
||||
GwBoatItemBase *getBase(String name);
|
||||
String toJson() const;
|
||||
String toString();
|
||||
};
|
||||
|
|
|
@ -51,9 +51,9 @@ void exampleTask(GwApi *api){
|
|||
bool hasPosition=false;
|
||||
bool hasPosition2=false;
|
||||
LOG_DEBUG(GwLog::DEBUG,"example switch ist %s",exampleSwitch?"true":"false");
|
||||
GwApi::StringList itemNames;
|
||||
itemNames.push_back(F("Latitude"));
|
||||
itemNames.push_back(F("Longitude"));
|
||||
GwApi::BoatValue *longitude=new GwApi::BoatValue(F("Longitude"));
|
||||
GwApi::BoatValue *latitude=new GwApi::BoatValue(F("Latitude"));
|
||||
GwApi::BoatValue *valueList[]={longitude,latitude};
|
||||
while(true){
|
||||
delay(1000);
|
||||
/*
|
||||
|
@ -96,30 +96,19 @@ void exampleTask(GwApi *api){
|
|||
r->unref(); //delete the request
|
||||
|
||||
/** second example with string based functions to access boatData
|
||||
uses STL vector and map - but does not need any request handling
|
||||
this uses a reasonable amount of mmeory on the stack:
|
||||
up to 2x the size of the list of names and 2x the size of the returned map
|
||||
the default stack size of 2000 will not fit.
|
||||
So be sure to use DECLARA_USERTASK_PARAM(taskFuntion,stackSize) and provide
|
||||
a reasonable stack size (e.g. 4000 in this example).
|
||||
This does not need the request handling approach
|
||||
Finally it only makes sense to use one of the versions - either with the request
|
||||
or with the ValueMap approach.
|
||||
The request access to boatData gives you more options on how to access the data
|
||||
and ueses less ressources and runtime but this one is maybe easier to understand and implement
|
||||
**/
|
||||
//fetch the current values of the items that we have in itemNames
|
||||
GwApi::ValueMap boatItems=api->getBoatDataValues(itemNames);
|
||||
//get the values out of the map
|
||||
//the returned item is a map iterator
|
||||
auto longitude=boatItems.find(itemNames[1]);
|
||||
auto latitude=boatItems.find(itemNames[0]);
|
||||
//check if the iterators are valid (i.e. the values we requested have been found in boatData)
|
||||
if (longitude != boatItems.end() && latitude != boatItems.end()){
|
||||
api->getBoatDataValues(2,valueList);
|
||||
//check if the values are valid (i.e. the values we requested have been found in boatData)
|
||||
if (longitude->valid && latitude->valid){
|
||||
//both values are there - so we have a valid position
|
||||
if (! hasPosition2){
|
||||
//access to the values via iterator->second (iterator->first would be the name)
|
||||
if (exampleSwitch) LOG_DEBUG(GwLog::LOG,"(2)position availale lat=%f, lon=%f",
|
||||
latitude->second,longitude->second);
|
||||
latitude->value,longitude->value);
|
||||
hasPosition2=true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ void exampleTask(GwApi *param);
|
|||
void exampleInit(GwApi *param);
|
||||
//make the task known to the core
|
||||
//the task function should not return (unless you delete the task - see example code)
|
||||
//we create our task with a stack size of 4000 bytes
|
||||
DECLARE_USERTASK_PARAM(exampleTask,4000)
|
||||
//if your task is happy with the default 2000 bytes of stack, replace the DECLARE_USERTASK_PARAM
|
||||
//with: DECLARE_USERTASK(exampleTask);
|
||||
DECLARE_USERTASK(exampleTask)
|
||||
//if your task is not happy with the default 2000 bytes of stack, replace the DECLARE_USERTASK
|
||||
//with: DECLARE_USERTASK_PARAM(exampleTask,4000);
|
||||
//this would create our task with a stack size of 4000 bytes
|
||||
|
||||
|
||||
//let the core call an init function before the
|
||||
|
|
|
@ -95,9 +95,9 @@ public:
|
|||
virtual const char* getTalkerId(){
|
||||
return api->getTalkerId();
|
||||
}
|
||||
virtual ValueMap getBoatDataValues(StringList names){
|
||||
virtual void getBoatDataValues(int num,BoatValue **list){
|
||||
GWSYNCHRONIZED(mainLock);
|
||||
return api->getBoatDataValues(names);
|
||||
api->getBoatDataValues(num,list);
|
||||
}
|
||||
virtual ~TaskApi(){};
|
||||
};
|
||||
|
|
16
src/main.cpp
16
src/main.cpp
|
@ -340,14 +340,18 @@ public:
|
|||
virtual GwLog* getLogger(){
|
||||
return &logger;
|
||||
}
|
||||
virtual GwApi::ValueMap getBoatDataValues(GwApi::StringList names){
|
||||
std::map<String,double> rt;
|
||||
for (auto it=names.begin();it!= names.end();it++){
|
||||
if (boatData.isValid(*it)){
|
||||
rt[*it]=boatData.getDoubleValue(*it,0);
|
||||
virtual void getBoatDataValues(int numValues,BoatValue **list){
|
||||
for (int i=0;i<numValues;i++){
|
||||
GwBoatItemBase *item=boatData.getBase(list[i]->getName());
|
||||
if (item){
|
||||
list[i]->valid=item->isValid();
|
||||
if (list[i]->valid) list[i]->value=item->getDoubleValue();
|
||||
list[i]->setFormat(item->getFormat());
|
||||
}
|
||||
else{
|
||||
list[i]->valid=false;
|
||||
}
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
virtual GwBoatData *getBoatData(){
|
||||
return &boatData;
|
||||
|
|
Loading…
Reference in New Issue