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;
|
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{
|
class Status{
|
||||||
public:
|
public:
|
||||||
|
@ -133,6 +156,15 @@ class GwApi{
|
||||||
virtual void increment(int idx,const String &name,bool failed=false){}
|
virtual void increment(int idx,const String &name,bool failed=false){}
|
||||||
virtual void reset(int idx){}
|
virtual void reset(int idx){}
|
||||||
virtual void remove(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
|
* not thread safe methods
|
||||||
* accessing boat data must only be executed from within the main thread
|
* accessing boat data must only be executed from within the main thread
|
||||||
|
|
|
@ -46,23 +46,65 @@ class GwUserCapability{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#include "GwUserTasks.h"
|
#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
|
class TaskApi : public GwApiInternal
|
||||||
{
|
{
|
||||||
GwApiInternal *api;
|
GwApiInternal *api=nullptr;
|
||||||
|
TaskData *taskData=nullptr;
|
||||||
int sourceId;
|
int sourceId;
|
||||||
SemaphoreHandle_t *mainLock;
|
SemaphoreHandle_t *mainLock;
|
||||||
SemaphoreHandle_t localLock;
|
SemaphoreHandle_t localLock;
|
||||||
std::map<int,GwCounter<String>> counter;
|
std::map<int,GwCounter<String>> counter;
|
||||||
|
String name;
|
||||||
bool counterUsed=false;
|
bool counterUsed=false;
|
||||||
int counterIdx=0;
|
int counterIdx=0;
|
||||||
|
|
||||||
public:
|
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->sourceId = sourceId;
|
||||||
this->api = api;
|
this->api = api;
|
||||||
this->mainLock=mainLock;
|
this->mainLock=mainLock;
|
||||||
|
this->name=name;
|
||||||
localLock=xSemaphoreCreateMutex();
|
localLock=xSemaphoreCreateMutex();
|
||||||
|
taskData=d;
|
||||||
}
|
}
|
||||||
virtual GwRequestQueue *getQueue()
|
virtual GwRequestQueue *getQueue()
|
||||||
{
|
{
|
||||||
|
@ -160,12 +202,20 @@ public:
|
||||||
else it->second=GwCounter<String>("count"+name);
|
else it->second=GwCounter<String>("count"+name);
|
||||||
return counterIdx;
|
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){
|
GwUserCode::GwUserCode(GwApiInternal *api,SemaphoreHandle_t *mainLock){
|
||||||
this->logger=api->getLogger();
|
this->logger=api->getLogger();
|
||||||
this->api=api;
|
this->api=api;
|
||||||
this->mainLock=mainLock;
|
this->mainLock=mainLock;
|
||||||
|
this->taskData=new TaskData(this->logger);
|
||||||
}
|
}
|
||||||
void userTaskStart(void *p){
|
void userTaskStart(void *p){
|
||||||
GwUserTask *task=(GwUserTask*)p;
|
GwUserTask *task=(GwUserTask*)p;
|
||||||
|
@ -179,7 +229,7 @@ void userTaskStart(void *p){
|
||||||
task->api=NULL;
|
task->api=NULL;
|
||||||
}
|
}
|
||||||
void GwUserCode::startAddOnTask(GwApiInternal *api,GwUserTask *task,int sourceId,String name){
|
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);
|
xTaskCreate(userTaskStart,name.c_str(),task->stackSize,task,3,NULL);
|
||||||
}
|
}
|
||||||
void GwUserCode::startUserTasks(int baseId){
|
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());
|
LOG_DEBUG(GwLog::DEBUG,"starting %d user init tasks",initTasks.size());
|
||||||
for (auto it=initTasks.begin();it != initTasks.end();it++){
|
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);
|
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));
|
userTaskStart(&(*it));
|
||||||
baseId++;
|
baseId++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,12 @@ class GwUserTask{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TaskData;
|
||||||
class GwUserCode{
|
class GwUserCode{
|
||||||
GwLog *logger;
|
GwLog *logger;
|
||||||
GwApiInternal *api;
|
GwApiInternal *api;
|
||||||
SemaphoreHandle_t *mainLock;
|
SemaphoreHandle_t *mainLock;
|
||||||
|
TaskData *taskData;
|
||||||
void startAddOnTask(GwApiInternal *api,GwUserTask *task,int sourceId,String name);
|
void startAddOnTask(GwApiInternal *api,GwUserTask *task,int sourceId,String name);
|
||||||
public:
|
public:
|
||||||
typedef std::map<String,String> Capabilities;
|
typedef std::map<String,String> Capabilities;
|
||||||
|
|
Loading…
Reference in New Issue