intermediate: allow to exchange simple data between tasks
This commit is contained in:
parent
015b4762f8
commit
371372f1f4
|
@ -32,6 +32,29 @@ class GwApi{
|
|||
return format;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* a simple value container
|
||||
* to exchange data between tasks
|
||||
*/
|
||||
class Value{
|
||||
long lvalue=0;
|
||||
String svalue;
|
||||
bool isString=false;
|
||||
bool isValid=false;
|
||||
public:
|
||||
Value(const String &v){isString=true;svalue=v;isValid=true;}
|
||||
Value(long l){lvalue=l;isValid=true;}
|
||||
Value(){}
|
||||
long getLValue() const{
|
||||
if(!isString) return lvalue;
|
||||
return atol(svalue.c_str());
|
||||
}
|
||||
String getSValue() const{
|
||||
if(isString) return svalue;
|
||||
return String(lvalue);
|
||||
}
|
||||
bool valid() const{return isValid;}
|
||||
};
|
||||
|
||||
class Status{
|
||||
public:
|
||||
|
@ -133,6 +156,15 @@ class GwApi{
|
|||
virtual void increment(int idx,const String &name,bool failed=false){}
|
||||
virtual void reset(int idx){}
|
||||
virtual void remove(int idx){}
|
||||
|
||||
/**
|
||||
* exchange data between different user tasks
|
||||
* each task can set arbitrary items
|
||||
* that can be accessed by other tasks
|
||||
*/
|
||||
virtual void setTaskValue(const String &name,const Value &v){}
|
||||
virtual Value getTaskValue(const String &taskName,const String &name){return Value();}
|
||||
|
||||
/**
|
||||
* not thread safe methods
|
||||
* accessing boat data must only be executed from within the main thread
|
||||
|
|
|
@ -46,23 +46,65 @@ class GwUserCapability{
|
|||
}
|
||||
};
|
||||
#include "GwUserTasks.h"
|
||||
class TaskData{
|
||||
SemaphoreHandle_t lock;
|
||||
std::map<String,GwApi::Value> data;
|
||||
GwLog *logger;
|
||||
String computeKey(const String &taskName,const String &name) const{
|
||||
return taskName+":#:"+name;
|
||||
}
|
||||
public:
|
||||
TaskData(GwLog *l){
|
||||
lock=xSemaphoreCreateMutex();
|
||||
logger=l;
|
||||
}
|
||||
~TaskData(){
|
||||
vSemaphoreDelete(lock);
|
||||
}
|
||||
void setTaskValue(const String &taskName,const String &name,const GwApi::Value &v){
|
||||
String key=computeKey(taskName,name);
|
||||
LOG_DEBUG(GwLog::DEBUG,"set task data %s=%s",key.c_str(),v.getSValue().c_str());
|
||||
GWSYNCHRONIZED(&lock);
|
||||
data[key]=v;
|
||||
}
|
||||
GwApi::Value getTaskValue(const String &taskName,const String &name){
|
||||
GwApi::Value rt;
|
||||
String key=computeKey(taskName,name);
|
||||
{
|
||||
GWSYNCHRONIZED(&lock);
|
||||
auto it=data.find(key);
|
||||
if (it != data.end()) rt=it->second;
|
||||
}
|
||||
LOG_DEBUG(GwLog::DEBUG,"get task data %s:%s (valid=%d)",key.c_str(),rt.getSValue().c_str(),(int)rt.valid());
|
||||
return rt;
|
||||
}
|
||||
|
||||
};
|
||||
class TaskApi : public GwApiInternal
|
||||
{
|
||||
GwApiInternal *api;
|
||||
GwApiInternal *api=nullptr;
|
||||
TaskData *taskData=nullptr;
|
||||
int sourceId;
|
||||
SemaphoreHandle_t *mainLock;
|
||||
SemaphoreHandle_t localLock;
|
||||
std::map<int,GwCounter<String>> counter;
|
||||
String name;
|
||||
bool counterUsed=false;
|
||||
int counterIdx=0;
|
||||
|
||||
public:
|
||||
TaskApi(GwApiInternal *api, int sourceId, SemaphoreHandle_t *mainLock, const String &name)
|
||||
TaskApi(GwApiInternal *api,
|
||||
int sourceId,
|
||||
SemaphoreHandle_t *mainLock,
|
||||
const String &name,
|
||||
TaskData *d)
|
||||
{
|
||||
this->sourceId = sourceId;
|
||||
this->api = api;
|
||||
this->mainLock=mainLock;
|
||||
this->name=name;
|
||||
localLock=xSemaphoreCreateMutex();
|
||||
taskData=d;
|
||||
}
|
||||
virtual GwRequestQueue *getQueue()
|
||||
{
|
||||
|
@ -160,12 +202,20 @@ public:
|
|||
else it->second=GwCounter<String>("count"+name);
|
||||
return counterIdx;
|
||||
}
|
||||
virtual void setTaskValue(const String &name,const Value &v){
|
||||
taskData->setTaskValue(this->name,name,v);
|
||||
}
|
||||
virtual Value getTaskValue(const String &taskName,const String &name){
|
||||
return taskData->getTaskValue(taskName,name);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
GwUserCode::GwUserCode(GwApiInternal *api,SemaphoreHandle_t *mainLock){
|
||||
this->logger=api->getLogger();
|
||||
this->api=api;
|
||||
this->mainLock=mainLock;
|
||||
this->taskData=new TaskData(this->logger);
|
||||
}
|
||||
void userTaskStart(void *p){
|
||||
GwUserTask *task=(GwUserTask*)p;
|
||||
|
@ -179,7 +229,7 @@ void userTaskStart(void *p){
|
|||
task->api=NULL;
|
||||
}
|
||||
void GwUserCode::startAddOnTask(GwApiInternal *api,GwUserTask *task,int sourceId,String name){
|
||||
task->api=new TaskApi(api,sourceId,mainLock,name);
|
||||
task->api=new TaskApi(api,sourceId,mainLock,name,taskData);
|
||||
xTaskCreate(userTaskStart,name.c_str(),task->stackSize,task,3,NULL);
|
||||
}
|
||||
void GwUserCode::startUserTasks(int baseId){
|
||||
|
@ -194,7 +244,7 @@ void GwUserCode::startInitTasks(int baseId){
|
|||
LOG_DEBUG(GwLog::DEBUG,"starting %d user init tasks",initTasks.size());
|
||||
for (auto it=initTasks.begin();it != initTasks.end();it++){
|
||||
LOG_DEBUG(GwLog::LOG,"starting user init task %s with id %d",it->name.c_str(),baseId);
|
||||
it->api=new TaskApi(api,baseId,mainLock,it->name);
|
||||
it->api=new TaskApi(api,baseId,mainLock,it->name,taskData);
|
||||
userTaskStart(&(*it));
|
||||
baseId++;
|
||||
}
|
||||
|
|
|
@ -34,11 +34,12 @@ class GwUserTask{
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
class TaskData;
|
||||
class GwUserCode{
|
||||
GwLog *logger;
|
||||
GwApiInternal *api;
|
||||
SemaphoreHandle_t *mainLock;
|
||||
TaskData *taskData;
|
||||
void startAddOnTask(GwApiInternal *api,GwUserTask *task,int sourceId,String name);
|
||||
public:
|
||||
typedef std::map<String,String> Capabilities;
|
||||
|
|
Loading…
Reference in New Issue