diff --git a/lib/api/GwApi.h b/lib/api/GwApi.h index 9d79ef3..e7b5dad 100644 --- a/lib/api/GwApi.h +++ b/lib/api/GwApi.h @@ -43,11 +43,7 @@ class GwApi{ * the core part will not handle this data at all but * this interface ensures that there is a correct locking of the * data to correctly handle multi threading - * The user code should not use this intterface directly - * but instead it should use the static functions - * apiGetXXX(GwApi *,...) - * apiSetXXX(GwApi *,...) - * that will be created by the macro DECLARE_TASK_INTERFACE + * there is no protection - i.e. every task can get and set the data */ class TaskInterfaces { @@ -61,9 +57,8 @@ class GwApi{ }; using Ptr = std::shared_ptr; protected: - virtual bool iset(const String &file, const String &name, Ptr v) = 0; + virtual bool iset(const String &name, Ptr v) = 0; virtual Ptr iget(const String &name, int &result) = 0; - virtual bool iclaim(const String &name, const String &task)=0; public: template bool set(const T &v){ @@ -76,7 +71,7 @@ class GwApi{ } template bool claim(const String &task){ - return false; + return true; } }; class Status{ @@ -255,27 +250,20 @@ static void checkDef(T... args){}; * int ival2=99; * String sval="unset"; * }; - * DECLARE_TASKIF(testTask,TestTaskApi); - * The macro will generate 2 static funtions: + * DECLARE_TASKIF(TestTaskApi); * - * bool apiSetTestTaskApi(GwApi *api, const TestTaskApi &v); - * TestTaskApi apiGetTestTaskApi(GwApi *api, int &result); - * - * The setter will return true on success. - * It is intended to be used by the task that did declare the api. - * The getter will set the result to -1 if no data is available, otherwise - * it will return the update count (so you can check if there was a change - * compared to the last call). * It is intended to be used by any task. * Be aware that all the apis share a common namespace - so be sure to somehow * make your API names unique. - * + * To utilize this interface a task can call: + * api->taskInterfaces()->get(res) //and check the result in res + * api->taskInterfaces()->set(value) * */ #define DECLARE_TASKIF_IMPL(type) \ template<> \ inline bool GwApi::TaskInterfaces::set(const type & v) {\ - return iset(__FILE__,#type,GwApi::TaskInterfaces::Ptr(new type(v))); \ + return iset(#type,GwApi::TaskInterfaces::Ptr(new type(v))); \ }\ template<> \ inline type GwApi::TaskInterfaces::get(int &result) {\ @@ -286,11 +274,7 @@ static void checkDef(T... args){}; }\ type *tp=(type*)ptr.get(); \ return type(*tp); \ - }\ - template<> \ - inline bool GwApi::TaskInterfaces::claim(const String &task) {\ - return iclaim(#type,task);\ - }\ + } #ifndef DECLARE_TASKIF #define DECLARE_TASKIF(type) DECLARE_TASKIF_IMPL(type) diff --git a/lib/iictask/GwIicTask.cpp b/lib/iictask/GwIicTask.cpp index 81dc0cc..def5545 100644 --- a/lib/iictask/GwIicTask.cpp +++ b/lib/iictask/GwIicTask.cpp @@ -65,7 +65,7 @@ static void addGroveItems(std::vector &creators,GwApi *a if (scfg->ok) { LOG_DEBUG(GwLog::LOG, "adding %s from grove config", prfx.c_str()); - sensors.add(api, scfg); + sensors.add(api, SensorBase::Ptr(scfg)); found=true; break; } diff --git a/lib/iictask/GwIicTask.h b/lib/iictask/GwIicTask.h index e26eb28..f2db0e4 100644 --- a/lib/iictask/GwIicTask.h +++ b/lib/iictask/GwIicTask.h @@ -1,6 +1,12 @@ #ifndef _GWIICTASK_H #define _GWIICTASK_H #include "GwApi.h" +#include "GwSensor.h" void initIicTask(GwApi *api); DECLARE_INITFUNCTION(initIicTask); +class IICSensors : public GwApi::TaskInterfaces::Base{ + public: + SensorList sensors; +}; +DECLARE_TASKIF(IICSensors); #endif \ No newline at end of file diff --git a/lib/sensors/GwSensor.h b/lib/sensors/GwSensor.h index 1f85d3b..3f821d4 100644 --- a/lib/sensors/GwSensor.h +++ b/lib/sensors/GwSensor.h @@ -16,6 +16,7 @@ #define _GWSENSORS_H #include "GwApi.h" #include "GwLog.h" +#include class SensorBase{ public: using BusType=enum{ @@ -23,6 +24,7 @@ class SensorBase{ SPI=1, UNKNOWN=-1 }; + using Ptr=std::shared_ptr; BusType busType=BusType::UNKNOWN; int busId=0; int iid=99; //N2K instanceId @@ -59,14 +61,14 @@ class SensorTemplate : public SensorBase{ }; -class SensorList : public std::vector{ +class SensorList : public std::vector{ public: - void add(GwApi *api, SensorBase *sensor){ + void add(GwApi *api, SensorBase::Ptr sensor){ sensor->readConfig(api->getConfig()); api->getLogger()->logDebug(GwLog::LOG,"configured sensor %s, status %d",sensor->prefix.c_str(),(int)sensor->ok); this->push_back(sensor); } - using std::vector::vector; + using std::vector::vector; }; diff --git a/lib/usercode/GwUserCode.cpp b/lib/usercode/GwUserCode.cpp index bf4502b..bc2fd54 100644 --- a/lib/usercode/GwUserCode.cpp +++ b/lib/usercode/GwUserCode.cpp @@ -5,7 +5,7 @@ #define DECLARE_STRING_CAPABILITY(name,value) GwUserCapability __CAP##name##__(#name,value); #define DECLARE_TASKIF(type) \ DECLARE_TASKIF_IMPL(type) \ - GwIreg __register##type(__FILE__,#type) + static int __taskInterface##type=0; //avoid duplicate declarations #include "GwUserCode.h" #include "GwSynchronized.h" @@ -28,45 +28,6 @@ bool taskExists(V &list, const String &name){ } return false; } -class RegEntry{ - public: - String file; - String task; - RegEntry(const String &t, const String &f):file(f),task(t){} - RegEntry(){} -}; -using RegMap=std::map; -static RegMap ®istrations(){ - static RegMap *regMap=new RegMap(); - return *regMap; -} - -static void registerInterface(const String &task,const String &file, const String &name){ - auto it=registrations().find(name); - if (it != registrations().end()){ - if (it->second.file != file){ - ESP_LOGE("Assert","type %s redefined in %s original in %s",name,file,it->second.file); - std::abort(); - }; - if (it->second.task != task){ - ESP_LOGE("Assert","type %s registered for multiple tasks %s and %s",name,task,it->second.task); - std::abort(); - }; - } - else{ - registrations()[name]=RegEntry(task,file); - } -} - -class GwIreg{ - public: - GwIreg(const String &file, const String &name){ - registerInterface("",file,name); - } - }; - - - class GwUserTaskDef{ public: GwUserTaskDef(TaskFunction_t task,String name, int stackSize=2000){ @@ -112,21 +73,8 @@ class TaskInterfacesStorage{ logger(l){ lock=xSemaphoreCreateMutex(); } - bool set(const String &file, const String &name, const String &task,GwApi::TaskInterfaces::Ptr v){ + bool set(const String &name, GwApi::TaskInterfaces::Ptr v){ GWSYNCHRONIZED(&lock); - auto it=registrations().find(name); - if (it == registrations().end()){ - LOG_DEBUG(GwLog::ERROR,"TaskInterfaces: invalid set %s not known",name.c_str()); - return false; - } - if (it->second.file != file){ - LOG_DEBUG(GwLog::ERROR,"TaskInterfaces: invalid set %s wrong file, expected %s , got %s",name.c_str(),it->second.file.c_str(),file.c_str()); - return false; - } - if (it->second.task != task){ - LOG_DEBUG(GwLog::ERROR,"TaskInterfaces: invalid set %s wrong task, expected %s , got %s",name.c_str(),it->second.task.c_str(),task.c_str()); - return false; - } auto vit=values.find(name); if (vit != values.end()){ vit->second.updates++; @@ -153,34 +101,20 @@ class TaskInterfacesStorage{ } }; class TaskInterfacesImpl : public GwApi::TaskInterfaces{ - String task; + TaskInterfacesStorage *storage; GwLog *logger; bool isInit=false; public: - TaskInterfacesImpl(const String &n,TaskInterfacesStorage *s, GwLog *l,bool i): - task(n),storage(s),isInit(i),logger(l){} - virtual bool iset(const String &file, const String &name, Ptr v){ - return storage->set(file,name,task,v); + TaskInterfacesImpl(TaskInterfacesStorage *s, GwLog *l,bool i): + storage(s),isInit(i),logger(l){} + protected: + virtual bool iset(const String &name, Ptr v){ + return storage->set(name,v); } virtual Ptr iget(const String &name, int &result){ return storage->get(name,result); } - virtual bool iclaim(const String &name, const String &task){ - if (! isInit) return false; - auto it=registrations().find(name); - if (it == registrations().end()){ - LOG_DEBUG(GwLog::ERROR,"unable to claim interface %s for task %s, not registered",name.c_str(),task.c_str()); - return false; - } - if (!it->second.task.isEmpty()){ - LOG_DEBUG(GwLog::ERROR,"unable to claim interface %s for task %s, already claimed by %s",name.c_str(),task.c_str(),it->second.task.c_str()); - return false; - } - it->second.task=task; - LOG_DEBUG(GwLog::LOG,"claimed interface %s for task %s",name.c_str(),task.c_str()); - return true; - } }; @@ -210,7 +144,7 @@ public: this->mainLock=mainLock; this->name=name; localLock=xSemaphoreCreateMutex(); - interfaces=new TaskInterfacesImpl(name,s,api->getLogger(),init); + interfaces=new TaskInterfacesImpl(s,api->getLogger(),init); isInit=init; } virtual GwRequestQueue *getQueue() diff --git a/src/main.cpp b/src/main.cpp index ae8f3d5..dd54944 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -849,7 +849,7 @@ void setup() { buffer[29]=0; request->send(200,"text/plain",buffer); }); - webserver.registerHandler((USERPREFIX+"*").c_str(),[&USERPREFIX](AsyncWebServerRequest *req){ + webserver.registerHandler((USERPREFIX+"*").c_str(),[](AsyncWebServerRequest *req){ String turl=req->url().substring(USERPREFIX.length()); logger.logDebug(GwLog::DEBUG,"user web request for %s",turl.c_str()); userCodeHandler.handleWebRequest(turl,req);