aqhome-react: major rebuild of unit handling.

now nested networks are allowed to allow for complex networks.
This commit is contained in:
Martin Preuss
2024-04-17 22:26:17 +02:00
parent ec816bddcf
commit 1050ee1c75
34 changed files with 1336 additions and 1616 deletions

View File

@@ -11,6 +11,7 @@
#endif #endif
#include "./aqhome_react_p.h" #include "./aqhome_react_p.h"
#include "./net_read.h"
#include "aqhome-react/units/u_logical.h" #include "aqhome-react/units/u_logical.h"
#include "aqhome-react/units/u_valuefilter.h" #include "aqhome-react/units/u_valuefilter.h"
#include "aqhome-react/units/u_valueset.h" #include "aqhome-react/units/u_valueset.h"
@@ -30,7 +31,6 @@ AQHOME_REACT *AqHomeReact_new()
AQHOME_REACT *aqh; AQHOME_REACT *aqh;
GWEN_NEW_OBJECT(AQHOME_REACT, aqh); GWEN_NEW_OBJECT(AQHOME_REACT, aqh);
aqh->unitNetList=AQHREACT_UnitNet_List_new();
aqh->unitList=AQHREACT_Unit_List_new(); aqh->unitList=AQHREACT_Unit_List_new();
return aqh; return aqh;
@@ -41,7 +41,6 @@ AQHOME_REACT *AqHomeReact_new()
void AqHomeReact_free(AQHOME_REACT *aqh) void AqHomeReact_free(AQHOME_REACT *aqh)
{ {
if (aqh) { if (aqh) {
AQHREACT_UnitNet_List_free(aqh->unitNetList);
AQHREACT_Unit_List_free(aqh->unitList); AQHREACT_Unit_List_free(aqh->unitList);
GWEN_MsgEndpoint_free(aqh->brokerEndpoint); GWEN_MsgEndpoint_free(aqh->brokerEndpoint);
GWEN_DB_Group_free(aqh->dbArgs); GWEN_DB_Group_free(aqh->dbArgs);
@@ -121,57 +120,17 @@ AQHREACT_UNIT *AqHomeReact_GetVarChangeUnit(const AQHOME_REACT *aqh)
AQHREACT_UNIT_NET_LIST *AqHomeReact_GetUnitNetList(const AQHOME_REACT *aqh) AQHREACT_UNIT *AqHomeReact_FindUnitByUnitId(const AQHOME_REACT *aqh, const char *unitId)
{
return aqh?aqh->unitNetList:NULL;
}
void AqHomeReact_AddUnitNet(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet)
{
if (aqh)
AQHREACT_UnitNet_List_Add(unitNet, aqh->unitNetList);
}
AQHREACT_UNIT_NET *AqHomeReact_GetUnitNetByName(const AQHOME_REACT *aqh, const char *s)
{
return (aqh && s && *s)?AQHREACT_UnitNet_List_GetByName(aqh->unitNetList, s):NULL;
}
AQHREACT_UNIT *AqHomeReact_FindUnitByNetNameAndUnitId(const AQHOME_REACT *aqh, const char *netName, const char *unitId)
{ {
if (aqh && unitId && *unitId) { if (aqh && unitId && *unitId) {
AQHREACT_UNIT_LIST *unitList=NULL; AQHREACT_UNIT *unit;
if (netName && *netName) { unit=AQHREACT_Unit_List_GetById(aqh->unitList, unitId);
AQHREACT_UNIT_NET *unitNet; if (unit==NULL) {
DBG_ERROR(NULL, "Unit \"%s\" not found", unitId);
unitNet=AQHREACT_UnitNet_List_GetByName(aqh->unitNetList, netName); return NULL;
if (unitNet)
unitList=AQHREACT_UnitNet_GetUnitList(unitNet);
else {
DBG_ERROR(NULL, "Unit net \"%s\" not found", netName);
return NULL;
}
}
else
unitList=aqh->unitList;
if (unitList) {
AQHREACT_UNIT *unit;
unit=AQHREACT_Unit_List_GetById(unitList, unitId);
if (unit==NULL) {
DBG_ERROR(NULL, "Unit \"%s/%s\" not found", netName, unitId);
return NULL;
}
return unit;
} }
return unit;
} }
return NULL; return NULL;
@@ -210,8 +169,25 @@ AQHREACT_UNIT *AqHomeReact_CreateUnitByName(AQHOME_REACT *aqh, const char *unitT
else if (strcasecmp(unitType, "zeroPosNegString")==0) else if (strcasecmp(unitType, "zeroPosNegString")==0)
return AqHomeReact_UnitZeroPosNegString_new(aqh); return AqHomeReact_UnitZeroPosNegString_new(aqh);
else { else {
DBG_ERROR(NULL, "Unknown unit type \"%s\"", unitType); AQHREACT_UNIT *unit;
return NULL;
DBG_INFO(NULL, "Trying to load network \"%s\"", unitType);
unit=AQHomeReact_FindAndReadDataDirNetwork(aqh, unitType);
if (unit==NULL) {
DBG_ERROR(NULL, "Unknown unit type \"%s\"", unitType);
return NULL;
}
else {
const char *s;
s=AQHREACT_Unit_GetName(unit);
if (!(s && *s && strcasecmp(s, unitType)==0)) {
DBG_ERROR(NULL, "ERROR: Network file for type \"%s\" contains type \"%s\" instead", unitType, s?s:"<no name>");
AQHREACT_Unit_free(unit);
return NULL;
}
}
return unit;
} }
} }

View File

@@ -37,11 +37,7 @@ void AqHomeReact_SetLatestNetworkFileTime(AQHOME_REACT *aqh, time_t t);
AQHREACT_UNIT *AqHomeReact_GetTimerUnit(const AQHOME_REACT *aqh); AQHREACT_UNIT *AqHomeReact_GetTimerUnit(const AQHOME_REACT *aqh);
AQHREACT_UNIT *AqHomeReact_GetVarChangeUnit(const AQHOME_REACT *aqh); AQHREACT_UNIT *AqHomeReact_GetVarChangeUnit(const AQHOME_REACT *aqh);
AQHREACT_UNIT_NET_LIST *AqHomeReact_GetUnitNetList(const AQHOME_REACT *aqh); AQHREACT_UNIT *AqHomeReact_FindUnitByUnitId(const AQHOME_REACT *aqh, const char *unitId);
void AqHomeReact_AddUnitNet(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet);
AQHREACT_UNIT_NET *AqHomeReact_GetUnitNetById(const AQHOME_REACT *aqh);
AQHREACT_UNIT *AqHomeReact_FindUnitByNetNameAndUnitId(const AQHOME_REACT *aqh, const char *netName, const char *unitId);
void AqHomeReact_AddUnit(AQHOME_REACT *aqh, AQHREACT_UNIT *unit); void AqHomeReact_AddUnit(AQHOME_REACT *aqh, AQHREACT_UNIT *unit);
AQHREACT_UNIT *AqHomeReact_CreateUnitByName(AQHOME_REACT *aqh, const char *unitType); AQHREACT_UNIT *AqHomeReact_CreateUnitByName(AQHOME_REACT *aqh, const char *unitType);

View File

@@ -34,7 +34,6 @@ struct AQHOME_REACT {
AQHREACT_UNIT *timerUnit; AQHREACT_UNIT *timerUnit;
AQHREACT_UNIT *varChangeUnit; AQHREACT_UNIT *varChangeUnit;
AQHREACT_UNIT_LIST *unitList; AQHREACT_UNIT_LIST *unitList;
AQHREACT_UNIT_NET_LIST *unitNetList;
time_t latestNetworkFileTime; time_t latestNetworkFileTime;
}; };

View File

@@ -48,7 +48,6 @@ int AqHomeReact_Fini(AQHOME_REACT *aqh)
GWEN_MsgEndpoint_free(aqh->brokerEndpoint); GWEN_MsgEndpoint_free(aqh->brokerEndpoint);
aqh->brokerEndpoint=NULL; aqh->brokerEndpoint=NULL;
AQHREACT_UnitNet_List_Clear(aqh->unitNetList);
AQHREACT_Unit_List_Clear(aqh->unitList); AQHREACT_Unit_List_Clear(aqh->unitList);
aqh->timerUnit=NULL; aqh->timerUnit=NULL;
aqh->varChangeUnit=NULL; aqh->varChangeUnit=NULL;

View File

@@ -96,7 +96,11 @@ int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv)
} }
} }
AqHomeReact_ReloadUnitNets(aqh); rv=AqHomeReact_ReloadUnitNets(aqh);
if (rv<0) {
DBG_ERROR(NULL, "Error reading unit network files (%d)", rv);
return rv;
}
rv=_setupBroker(aqh, dbArgs); rv=_setupBroker(aqh, dbArgs);
if (rv<0) { if (rv<0) {
@@ -109,33 +113,31 @@ int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv)
void AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh) int AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT_NET_LIST *unitNetList; int rv;
AQHREACT_UnitNet_List_Clear(aqh->unitNetList);
AQHREACT_Unit_List_Clear(aqh->unitList); AQHREACT_Unit_List_Clear(aqh->unitList);
aqh->timerUnit=NULL; aqh->timerUnit=NULL;
aqh->varChangeUnit=NULL; aqh->varChangeUnit=NULL;
_setupBuiltinUnits(aqh); _setupBuiltinUnits(aqh);
unitNetList=AQHomeReact_ReadUnitNetFiles(aqh); rv=AQHomeReact_ReadUnitNetFiles(aqh);
if (unitNetList) { if (rv<0) {
AQHREACT_UnitNet_List_free(aqh->unitNetList); DBG_ERROR(NULL, "Error reading network files (%d)", rv);
aqh->unitNetList=unitNetList; return rv;
{ }
GWEN_BUFFER *dbuf; {
GWEN_BUFFER *dbuf;
dbuf=GWEN_Buffer_new(0, 256, 0, 1); dbuf=GWEN_Buffer_new(0, 256, 0, 1);
AQHREACT_UnitNet_List_Dump(unitNetList, dbuf, 2, "Loaded networks:"); AQHREACT_Unit_List_Dump(aqh->unitList, dbuf, 2, "Loaded networks:");
fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(dbuf)); fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_free(dbuf); GWEN_Buffer_free(dbuf);
} }
}
else { return 0;
DBG_INFO(NULL, "No unit nets read");
}
} }

View File

@@ -15,8 +15,7 @@
int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv); int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv);
void AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh); int AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh);
#endif #endif

View File

@@ -37,8 +37,7 @@
*/ */
static void _handleDataResponse(AQHREACT_UNIT *varChangeUnit, GWEN_MSG *msg); static void _handleDataResponse(AQHREACT_UNIT *varChangeUnit, GWEN_MSG *msg);
static int _processAllNets(AQHOME_REACT *aqh); static int _processAllUnits(AQHOME_REACT *aqh);
static int _processNet(AQHREACT_UNIT_NET *unitNet);
@@ -78,69 +77,31 @@ void AqHomeReact_ProcessAllUnits(AQHOME_REACT *aqh)
int rv; int rv;
do { do {
rv=_processAllNets(aqh); rv=_processAllUnits(aqh);
} while (rv==1); } while (rv==1);
} }
int _processAllNets(AQHOME_REACT *aqh) int _processAllUnits(AQHOME_REACT *aqh)
{ {
int result=0; int result=0;
int rv; AQHREACT_UNIT *unit;
AQHREACT_UNIT_NET *unitNet;
rv=AQHREACT_Unit_Process(aqh->varChangeUnit); unit=AQHREACT_Unit_List_First(aqh->unitList);
if (rv>0) while(unit) {
result=1; int rv;
rv=AQHREACT_Unit_Process(aqh->timerUnit); rv=AQHREACT_Unit_Process(unit);
if (rv>0)
result=1;
unitNet=AQHREACT_UnitNet_List_First(aqh->unitNetList);
while(unitNet) {
rv=_processNet(unitNet);
if (rv>0) if (rv>0)
result=1; result=1;
unit=AQHREACT_Unit_List_Next(unit);
unitNet=AQHREACT_UnitNet_List_Next(unitNet);
} }
return result; return result;
} }
int _processNet(AQHREACT_UNIT_NET *unitNet)
{
AQHREACT_UNIT_LIST *unitList;
const char *netName;
netName=AQHREACT_UnitNet_GetName(unitNet);
DBG_DEBUG(NULL, "Processing net \"%s\"", netName?netName:"<unnamed>");
unitList=AQHREACT_UnitNet_GetUnitList(unitNet);
if (unitList) {
int result=0;
AQHREACT_UNIT *unit;
unit=AQHREACT_Unit_List_First(unitList);
while(unit) {
int rv;
rv=AQHREACT_Unit_Process(unit);
if (rv>0)
result=1;
unit=AQHREACT_Unit_List_Next(unit);
}
return result;
}
return 0;
}
void _handleDataResponse(AQHREACT_UNIT *varChangeUnit, GWEN_MSG *msg) void _handleDataResponse(AQHREACT_UNIT *varChangeUnit, GWEN_MSG *msg)
{ {
AQH_VALUE *value; AQH_VALUE *value;

View File

@@ -151,7 +151,7 @@ void _serve(AQHOME_REACT *aqh)
lastTimerTime=startTime; lastTimerTime=startTime;
lastFileScanTime=startTime; lastFileScanTime=startTime;
AqHomeReact_SetLatestNetworkFileTime(aqh, AQHomeReact_GetNewestUnitNetFiletime(aqh)); AqHomeReact_SetLatestNetworkFileTime(aqh, AQHomeReact_GetNewestUnitNetFiletime());
dbArgs=AqHomeReact_GetDbArgs(aqh); dbArgs=AqHomeReact_GetDbArgs(aqh);
timerUnit=AqHomeReact_GetTimerUnit(aqh); timerUnit=AqHomeReact_GetTimerUnit(aqh);
@@ -184,7 +184,7 @@ void _serve(AQHOME_REACT *aqh)
time_t t; time_t t;
DBG_INFO(NULL, "Checking network files"); DBG_INFO(NULL, "Checking network files");
tNew=AQHomeReact_GetNewestUnitNetFiletime(aqh); tNew=AQHomeReact_GetNewestUnitNetFiletime();
t=AqHomeReact_GetLatestNetworkFileTime(aqh); t=AqHomeReact_GetLatestNetworkFileTime(aqh);
if (tNew && tNew>t) { if (tNew && tNew>t) {
DBG_INFO(NULL, "Reloading network files"); DBG_INFO(NULL, "Reloading network files");

View File

@@ -11,8 +11,10 @@
#endif #endif
#include "./net_read.h" #include "./net_read.h"
#include "aqhome-react/aqhome_react_p.h"
#include "aqhome-react/types/unit.h" #include "aqhome-react/types/unit.h"
#include "aqhome-react/types/unitnet.h" #include "aqhome-react/types/unitnet.h"
#include "aqhome-react/units/u_module.h"
#include "aqhome/aqhome.h" #include "aqhome/aqhome.h"
@@ -32,25 +34,10 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static time_t _getNewestFiletimeFromFileList(const AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl); static time_t _getNewestFiletimeFromFileList(const GWEN_STRINGLIST *sl);
static AQHREACT_UNIT_NET_LIST *_readUnitNetFiles(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl); static AQHREACT_UNIT *_readNetworkFromFile(AQHOME_REACT *aqh, const char *filename);
static int _readAllNetworksFromFileIntoList(AQHOME_REACT *aqh, const char *sFilename, AQHREACT_UNIT_NET_LIST *unitNetList); static GWEN_XMLNODE *_readUnitNetFileToXml(const char *sFilename);
static GWEN_XMLNODE *_readNetworkFromDatadirIntoXml(AQHOME_REACT *aqh, const char *networkName); static int _readUnitNetFilesIntoList(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl, AQHREACT_UNIT_LIST *unitList);
static AQHREACT_UNIT_NET *_readUnitNetFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode);
static AQHREACT_UNIT_NET *_readUnitNetWithTemplate(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode);
static AQHREACT_UNIT_NET *_readUnitNetNoTemplate(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode);
static GWEN_XMLNODE *_readUnitNetFileToXml(AQHOME_REACT *aqh, const char *sFilename);
static void _readNetParamDefsWithList(AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *unitNetNode);
static int _readUnits(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode, GWEN_DB_NODE *dbNetParams);
static int _readLinks(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode, GWEN_DB_NODE *dbNetParams);
static AQHREACT_UNIT *_readUnit(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNode, GWEN_DB_NODE *dbNetParams);
static int _readParamValuesForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *parentNode, GWEN_DB_NODE *dbNetParams);
static int _readParamValueForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *paramNode, GWEN_DB_NODE *dbNetParams);
static int _setParamDataFromString(AQHREACT_PARAM *param, const char *value);
static AQHREACT_PARAM *_readNetParamDef(GWEN_XMLNODE *paramNode);
static int _readLink(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *linkNode);
static int _setParamDoubleValueFromString(AQHREACT_PARAM *param, const char *s);
static int _treeExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars);
@@ -60,18 +47,18 @@ static int _treeExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars);
*/ */
time_t AQHomeReact_GetNewestUnitNetFiletime(const AQHOME_REACT *aqh) time_t AQHomeReact_GetNewestUnitNetFiletime(void)
{ {
GWEN_STRINGLIST *sl; GWEN_STRINGLIST *sl;
time_t t1; time_t t1;
time_t t2; time_t t2;
sl=AQH_GetListOfMatchingDataFiles("aqhome/react/networks", "*.xml"); sl=AQH_GetListOfMatchingDataFiles("aqhome/react/networks", "*.xml");
t1=_getNewestFiletimeFromFileList(aqh, sl); t1=_getNewestFiletimeFromFileList(sl);
GWEN_StringList_free(sl); GWEN_StringList_free(sl);
sl=AQH_GetListOfMatchingSysconfFiles("aqhome/react/networks", "*.xml"); sl=AQH_GetListOfMatchingSysconfFiles("aqhome/react/networks", "*.xml");
t2=_getNewestFiletimeFromFileList(aqh, sl); t2=_getNewestFiletimeFromFileList(sl);
GWEN_StringList_free(sl); GWEN_StringList_free(sl);
return (t1>t2)?t1:t2; return (t1>t2)?t1:t2;
@@ -79,32 +66,60 @@ time_t AQHomeReact_GetNewestUnitNetFiletime(const AQHOME_REACT *aqh)
AQHREACT_UNIT_NET_LIST *AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh) int AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh)
{ {
GWEN_STRINGLIST *sl; GWEN_STRINGLIST *sl;
sl=AQH_GetListOfMatchingSysconfFiles("aqhome/react/networks", "*.xml"); sl=AQH_GetListOfMatchingSysconfFiles("aqhome/react/networks", "*.xml");
if (sl) { if (sl) {
AQHREACT_UNIT_NET_LIST *unitNetList; int rv;
GWEN_StringList_Sort(sl, 1, GWEN_StringList_SortModeNoCase); GWEN_StringList_Sort(sl, 1, GWEN_StringList_SortModeNoCase);
unitNetList=_readUnitNetFiles(aqh, sl); rv=_readUnitNetFilesIntoList(aqh, sl, aqh->unitList);
GWEN_StringList_free(sl); GWEN_StringList_free(sl);
if (unitNetList==NULL) { if (rv<0) {
DBG_INFO(NULL, "Error reading unit network files"); DBG_INFO(NULL, "Error reading unit network files (%d)", rv);
return NULL; return rv;
} }
return unitNetList;
} }
else { else {
DBG_ERROR(NULL, "No unit network files"); DBG_ERROR(NULL, "No unit network files");
return NULL;
} }
return 0;
} }
time_t _getNewestFiletimeFromFileList(const AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl) AQHREACT_UNIT *AQHomeReact_FindAndReadDataDirNetwork(AQHOME_REACT *aqh, const char *networkName)
{
AQHREACT_UNIT *unit;
GWEN_BUFFER *bufFilename;
GWEN_BUFFER *bufPath;
bufFilename=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(bufFilename, "aqhome/react/networks/%s.xml", networkName);
bufPath=AQH_FindPathOfDataFile(GWEN_Buffer_GetStart(bufFilename));
if (bufPath==NULL) {
DBG_ERROR(NULL, "Network file \"%s\" not found in data folders", GWEN_Buffer_GetStart(bufFilename));
GWEN_Buffer_free(bufFilename);
return NULL;
}
GWEN_Buffer_free(bufFilename);
unit=_readNetworkFromFile(aqh, GWEN_Buffer_GetStart(bufPath));
if (unit==NULL) {
DBG_ERROR(NULL, "Error reading network from file \"%s\"", GWEN_Buffer_GetStart(bufPath));
GWEN_Buffer_free(bufPath);
return NULL;
}
GWEN_Buffer_free(bufPath);
return unit;
}
time_t _getNewestFiletimeFromFileList(const GWEN_STRINGLIST *sl)
{ {
time_t resultTime=0; time_t resultTime=0;
@@ -138,263 +153,31 @@ time_t _getNewestFiletimeFromFileList(const AQHOME_REACT *aqh, const GWEN_STRING
GWEN_XMLNODE *_readNetworkFromDatadirIntoXml(AQHOME_REACT *aqh, const char *networkName) AQHREACT_UNIT *_readNetworkFromFile(AQHOME_REACT *aqh, const char *filename)
{ {
GWEN_XMLNODE *n; GWEN_XMLNODE *n;
GWEN_BUFFER *bufFilename; AQHREACT_UNIT *unit;
GWEN_BUFFER *bufPath;
bufFilename=GWEN_Buffer_new(0, 256, 0, 1); n=_readUnitNetFileToXml(filename);
GWEN_Buffer_AppendString(bufFilename, "aqhome/react/networks/");
GWEN_Buffer_AppendString(bufFilename, networkName);
GWEN_Buffer_AppendString(bufFilename, ".xml");
bufPath=AQH_FindPathOfDataFile(GWEN_Buffer_GetStart(bufFilename));
if (bufPath==NULL) {
DBG_ERROR(NULL, "Network file \"%s\" not found in sysconf folders", GWEN_Buffer_GetStart(bufFilename));
GWEN_Buffer_free(bufFilename);
return NULL;
}
GWEN_Buffer_free(bufFilename);
n=_readUnitNetFileToXml(aqh, GWEN_Buffer_GetStart(bufPath));
if (n==NULL) { if (n==NULL) {
DBG_ERROR(NULL, "Error reading network file \"%s\" from sysconf dir", GWEN_Buffer_GetStart(bufPath)); DBG_ERROR(NULL, "Error reading network file \"%s\"", filename);
GWEN_Buffer_free(bufPath);
return NULL; return NULL;
} }
GWEN_Buffer_free(bufPath);
return n; unit=AqHomeReact_UnitModule_fromXml(aqh, n);
if (unit==NULL) {
DBG_ERROR(NULL, "Error reading network from file \"%s\"", filename);
GWEN_XMLNode_free(n);
return NULL;
}
GWEN_XMLNode_free(n);
return unit;
} }
AQHREACT_UNIT_NET_LIST *_readUnitNetFiles(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl) GWEN_XMLNODE *_readUnitNetFileToXml(const char *sFilename)
{
GWEN_STRINGLISTENTRY *se;
AQHREACT_UNIT_NET_LIST *unitNetList;
unitNetList=AQHREACT_UnitNet_List_new();
se=GWEN_StringList_FirstEntry(sl);
while(se) {
const char *s;
s=GWEN_StringListEntry_Data(se);
if (s && *s) {
int rv;
DBG_INFO(NULL, "Reading unit network file \"%s\"", s);
rv=_readAllNetworksFromFileIntoList(aqh, s, unitNetList);
if (rv<0 && rv!=GWEN_ERROR_NO_DATA) {
DBG_WARN(NULL, "Error reading unit network file \"%s\" (%d), ignoring", s, rv);
}
}
se=GWEN_StringListEntry_Next(se);
}
if (AQHREACT_UnitNet_List_GetCount(unitNetList)<1) {
AQHREACT_UnitNet_List_free(unitNetList);
return NULL;
}
return unitNetList;
}
int _readAllNetworksFromFileIntoList(AQHOME_REACT *aqh, const char *sFilename, AQHREACT_UNIT_NET_LIST *unitNetList)
{
GWEN_XMLNODE *rootNode;
GWEN_XMLNODE *netListNode;
GWEN_XMLNODE *netNode;
int rv;
rootNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, NULL);
rv=GWEN_XML_ReadFile(rootNode, sFilename, GWEN_XML_FLAGS_DEFAULT);
if (rv<0) {
DBG_ERROR(NULL, "Error reading XML file \"%s\": %d", sFilename, rv);
GWEN_XMLNode_free(rootNode);
return rv;
}
netListNode=GWEN_XMLNode_FindFirstTag(rootNode, "networks", NULL, NULL);
if (netListNode==NULL)
netListNode=rootNode;
netNode=GWEN_XMLNode_FindFirstTag(netListNode, "network", NULL, NULL);
while(netNode) {
AQHREACT_UNIT_NET *unitNet;
unitNet=_readUnitNetFromXml(aqh, netNode);
if (unitNet)
AQHREACT_UnitNet_List_Add(unitNet, unitNetList);
else {
DBG_ERROR(NULL, "Error loading network from file \"%s\", ignoring.", sFilename);
}
netNode=GWEN_XMLNode_FindNextTag(netNode, "network", NULL, NULL);
}
return 0;
}
AQHREACT_UNIT_NET *_readUnitNetFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode)
{
AQHREACT_UNIT_NET *unitNet;
const char *s;
s=GWEN_XMLNode_GetProperty(unitNetNode, "type", NULL);
if (s && *s)
unitNet=_readUnitNetWithTemplate(aqh, unitNetNode);
else
unitNet=_readUnitNetNoTemplate(aqh, unitNetNode);
if (unitNet==NULL) {
DBG_INFO(NULL, "Error reading unit");
return NULL;
}
return unitNet;
}
AQHREACT_UNIT_NET *_readUnitNetWithTemplate(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetXml)
{
AQHREACT_UNIT_NET *unitNet;
GWEN_XMLNODE *templateNetXml;
const char *s;
int rv;
GWEN_DB_NODE *dbNetParams=NULL;
unitNet=AQHREACT_UnitNet_new();
s=GWEN_XMLNode_GetProperty(unitNetXml, "id", NULL);
AQHREACT_UnitNet_SetName(unitNet, s);
s=GWEN_XMLNode_GetProperty(unitNetXml, "type", NULL);
DBG_INFO(NULL, "Loading base network \"%s\"", s);
templateNetXml=_readNetworkFromDatadirIntoXml(aqh, s);
if (templateNetXml==NULL) {
DBG_ERROR(NULL, "Base network \"%s\" not available (error or missing)", s);
AQHREACT_UnitNet_free(unitNet);
return NULL;
}
/* read netParam definitions from template file */
_readNetParamDefsWithList(AQHREACT_UnitNet_GetParamList(unitNet), templateNetXml);
/* also read netParams from this file (after reading from template) */
rv=_readParamValuesForList(AQHREACT_UnitNet_GetParamList(unitNet), unitNetXml, NULL);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_UnitNet_free(unitNet);
GWEN_XMLNode_free(templateNetXml);
return NULL;
}
dbNetParams=GWEN_DB_Group_new("params");
rv=AQHREACT_Param_List_WriteIntoDb(AQHREACT_UnitNet_GetParamList(unitNet), dbNetParams, GWEN_DB_FLAGS_OVERWRITE_VARS);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
GWEN_DB_Group_free(dbNetParams);
AQHREACT_UnitNet_free(unitNet);
GWEN_XMLNode_free(templateNetXml);
return NULL;
}
/* first read units from this file (if any) */
rv=_readUnits(aqh, unitNet, unitNetXml, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
GWEN_DB_Group_free(dbNetParams);
AQHREACT_UnitNet_free(unitNet);
GWEN_XMLNode_free(templateNetXml);
return NULL;
}
/* then read units from template file */
rv=_readUnits(aqh, unitNet, templateNetXml, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
GWEN_DB_Group_free(dbNetParams);
AQHREACT_UnitNet_free(unitNet);
GWEN_XMLNode_free(templateNetXml);
return NULL;
}
/* read links from template file */
rv=_readLinks(aqh, unitNet, templateNetXml, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
GWEN_DB_Group_free(dbNetParams);
AQHREACT_UnitNet_free(unitNet);
GWEN_XMLNode_free(templateNetXml);
return NULL;
}
/* read additional links from this file (if any) */
rv=_readLinks(aqh, unitNet, unitNetXml, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
GWEN_DB_Group_free(dbNetParams);
AQHREACT_UnitNet_free(unitNet);
GWEN_XMLNode_free(templateNetXml);
return NULL;
}
GWEN_DB_Group_free(dbNetParams);
GWEN_XMLNode_free(templateNetXml);
return unitNet;
}
AQHREACT_UNIT_NET *_readUnitNetNoTemplate(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode)
{
AQHREACT_UNIT_NET *unitNet;
const char *s;
int rv;
GWEN_DB_NODE *dbNetParams=NULL;
unitNet=AQHREACT_UnitNet_new();
s=GWEN_XMLNode_GetProperty(unitNetNode, "id", NULL);
AQHREACT_UnitNet_SetName(unitNet, s);
/* just directly read network from given XML node (no need to load a template file) */
_readNetParamDefsWithList(AQHREACT_UnitNet_GetParamList(unitNet), unitNetNode);
dbNetParams=GWEN_DB_Group_new("params");
rv=AQHREACT_Param_List_WriteIntoDb(AQHREACT_UnitNet_GetParamList(unitNet), dbNetParams, GWEN_DB_FLAGS_OVERWRITE_VARS);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
GWEN_DB_Group_free(dbNetParams);
AQHREACT_UnitNet_free(unitNet);
return NULL;
}
rv=_readUnits(aqh, unitNet, unitNetNode, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
GWEN_DB_Group_free(dbNetParams);
AQHREACT_UnitNet_free(unitNet);
return NULL;
}
rv=_readLinks(aqh, unitNet, unitNetNode, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
GWEN_DB_Group_free(dbNetParams);
AQHREACT_UnitNet_free(unitNet);
return NULL;
}
GWEN_DB_Group_free(dbNetParams);
return unitNet;
}
GWEN_XMLNODE *_readUnitNetFileToXml(AQHOME_REACT *aqh, const char *sFilename)
{ {
GWEN_XMLNODE *rootNode; GWEN_XMLNODE *rootNode;
GWEN_XMLNODE *netNode; GWEN_XMLNODE *netNode;
@@ -422,404 +205,30 @@ GWEN_XMLNODE *_readUnitNetFileToXml(AQHOME_REACT *aqh, const char *sFilename)
int _readUnits(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode, GWEN_DB_NODE *dbNetParams) int _readUnitNetFilesIntoList(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl, AQHREACT_UNIT_LIST *unitList)
{ {
GWEN_XMLNODE *nGroup; GWEN_STRINGLISTENTRY *se;
nGroup=GWEN_XMLNode_FindFirstTag(unitNetNode, "units", NULL, NULL); se=GWEN_StringList_FirstEntry(sl);
if (nGroup) { while(se) {
GWEN_XMLNODE *n; const char *s;
if (dbNetParams) { s=GWEN_StringListEntry_Data(se);
int rv; if (s && *s) {
rv=_treeExpandProperties(nGroup, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
}
n=GWEN_XMLNode_FindFirstTag(nGroup, "unit", NULL, NULL);
while(n) {
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
unit=_readUnit(aqh, n, dbNetParams); DBG_INFO(NULL, "Reading unit network file \"%s\"", s);
if (unit) unit=_readNetworkFromFile(aqh, s);
AQHREACT_UnitNet_AddUnit(unitNet, unit); if (unit==NULL) {
else { DBG_WARN(NULL, "No network read from network file \"%s\"", s);
DBG_ERROR(NULL, "Error reading unit in net \"%s\"", AQHREACT_UnitNet_GetName(unitNet)); return GWEN_ERROR_GENERIC;
return GWEN_ERROR_BAD_DATA;
} }
n=GWEN_XMLNode_FindNextTag(n, "unit", NULL, NULL); AQHREACT_Unit_List_Add(unit, unitList);
}
}
return 0;
}
int _readLinks(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode, GWEN_DB_NODE *dbNetParams)
{
GWEN_XMLNODE *nGroup;
nGroup=GWEN_XMLNode_FindFirstTag(unitNetNode, "links", NULL, NULL);
if (nGroup) {
GWEN_XMLNODE *n;
if (dbNetParams) {
int rv;
rv=_treeExpandProperties(nGroup, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
}
n=GWEN_XMLNode_FindFirstTag(nGroup, "link", NULL, NULL);
while(n) {
int rv;
rv=_readLink(aqh, unitNet, n);
if (rv<0) {
DBG_ERROR(NULL, "Error reading link in net \"%s\" (%d)", AQHREACT_UnitNet_GetName(unitNet), rv);
return GWEN_ERROR_BAD_DATA;
}
n=GWEN_XMLNode_FindNextTag(n, "link", NULL, NULL);
} }
se=GWEN_StringListEntry_Next(se);
} }
return 0; return 0;
} }
AQHREACT_UNIT *_readUnit(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNode, GWEN_DB_NODE *dbNetParams)
{
AQHREACT_UNIT *unit;
const char *unitType;
const char *unitId;
int rv;
unitType=GWEN_XMLNode_GetProperty(unitNode, "type", NULL);
if (!(unitType && *unitType)) {
DBG_ERROR(NULL, "No type name in unit node");
return NULL;
}
unit=AqHomeReact_CreateUnitByName(aqh, unitType);
unitId=GWEN_XMLNode_GetProperty(unitNode, "id", NULL);
AQHREACT_Unit_SetId(unit, unitId);
rv=_readParamValuesForList(AQHREACT_Unit_GetParamList(unit), unitNode, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
return unit;
}
int _readParamValuesForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *parentNode, GWEN_DB_NODE *dbNetParams)
{
GWEN_XMLNODE *nGroup;
nGroup=GWEN_XMLNode_FindFirstTag(parentNode, "params", NULL, NULL);
if (nGroup) {
GWEN_XMLNODE *n;
n=GWEN_XMLNode_FindFirstTag(nGroup, "param", NULL, NULL);
while(n) {
int rv;
rv=_readParamValueForList(paramList, n, dbNetParams);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
n=GWEN_XMLNode_FindNextTag(n, "param", NULL, NULL);
}
}
return 0;
}
int _readParamValueForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *paramNode, GWEN_DB_NODE *dbNetParams)
{
const char *paramName;
paramName=GWEN_XMLNode_GetProperty(paramNode, "name", NULL);
if (paramName && *paramName) {
AQHREACT_PARAM *param;
param=AQHREACT_Param_List_GetParamByName(paramList, paramName);
if (param) {
const char *value;
value=GWEN_XMLNode_GetCharValue(paramNode, NULL, NULL);
if (value && *value) {
if (dbNetParams) {
GWEN_BUFFER *buf;
int rv;
buf=GWEN_Buffer_new(0, 64, 0, 1);
rv=GWEN_DB_ReplaceVars(dbNetParams, value, buf);
if (rv<0) {
DBG_ERROR(NULL, "Error replacing vars for param \"%s\" (%d)", paramName, rv);
GWEN_Buffer_free(buf);
return rv;
}
rv=_setParamDataFromString(param, GWEN_Buffer_GetStart(buf));
if (rv<0) {
DBG_ERROR(NULL, "Error setting param data for param \"%s\" (%d)", paramName, rv);
GWEN_Buffer_free(buf);
return rv;
}
GWEN_Buffer_free(buf);
}
else {
int rv;
rv=_setParamDataFromString(param, value);
if (rv<0) {
DBG_ERROR(NULL, "Error setting param data for param \"%s\" (%d)", paramName, rv);
return rv;
}
}
} /* if value */
}
else {
DBG_ERROR(NULL, "No param name \"%s\" in list", paramName);
return GWEN_ERROR_BAD_DATA;
}
}
return 0;
}
int _setParamDataFromString(AQHREACT_PARAM *param, const char *value)
{
if (value && *value) {
int dataType;
dataType=AQHREACT_Param_GetDataType(param);
switch(dataType) {
case AQHREACT_DATAOBJECTTYPE_DOUBLE:
{
int rv;
double valueAsDouble;
rv=GWEN_Text_StringToDouble(value, &valueAsDouble);
if (rv<0) {
DBG_ERROR(NULL, "Not a DOUBLE value for param \"%s\" [%s]", AQHREACT_Param_GetName(param), value);
return rv;
}
AQHREACT_Param_SetDoubleValue(param, valueAsDouble);
break;
}
case AQHREACT_DATAOBJECTTYPE_STRING:
default:
AQHREACT_Param_SetStringValue(param, value);
break;
}
}
return 0;
}
void _readNetParamDefsWithList(AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *unitNetNode)
{
GWEN_XMLNODE *nGroup;
nGroup=GWEN_XMLNode_FindFirstTag(unitNetNode, "params", NULL, NULL);
if (nGroup) {
GWEN_XMLNODE *n;
n=GWEN_XMLNode_FindFirstTag(nGroup, "param", NULL, NULL);
while(n) {
AQHREACT_PARAM *param;
param=_readNetParamDef(n);
if (param)
AQHREACT_Param_List_Add(param, paramList);
n=GWEN_XMLNode_FindNextTag(n, "param", NULL, NULL);
}
}
}
AQHREACT_PARAM *_readNetParamDef(GWEN_XMLNODE *paramNode)
{
const char *paramName;
const char *paramType;
const char *paramValue;
paramName=GWEN_XMLNode_GetProperty(paramNode, "name", NULL);
paramType=GWEN_XMLNode_GetProperty(paramNode, "type", "string");
paramValue=GWEN_XMLNode_GetCharValue(paramNode, NULL, NULL);
if (paramName && *paramName) {
int t=AQHREACT_DATAOBJECTTYPE_STRING;
AQHREACT_PARAM *param;
if (paramType) {
if (strcasecmp(paramType, "string")==0)
t=AQHREACT_DATAOBJECTTYPE_STRING;
else if (strcasecmp(paramType, "double")==0)
t=AQHREACT_DATAOBJECTTYPE_DOUBLE;
else {
DBG_ERROR(NULL, "Invalid data type in parameter (%s), assuming string", paramType);
t=AQHREACT_DATAOBJECTTYPE_STRING;
}
}
param=AQHREACT_Param_new();
AQHREACT_Param_SetName(param, paramName);
AQHREACT_Param_SetDataType(param, t);
if (paramValue && *paramValue) {
int rv;
switch(t) {
case AQHREACT_DATAOBJECTTYPE_STRING:
AQHREACT_Param_SetStringValue(param, paramValue);
break;
case AQHREACT_DATAOBJECTTYPE_DOUBLE:
rv=_setParamDoubleValueFromString(param, paramValue);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Param_free(param);
return NULL;
}
break;
default:
break;
}
}
return param;
}
return NULL;
}
int _setParamDoubleValueFromString(AQHREACT_PARAM *param, const char *s)
{
int rv;
double value;
rv=GWEN_Text_StringToDouble(s, &value);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
AQHREACT_Param_SetDoubleValue(param, value);
return 0;
}
int _readLink(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *linkNode)
{
const char *sourceNetName;
const char *sourceUnitName;
const char *sourceSlotName;
const char *targetNetName;
const char *targetUnitName;
const char *targetSlotName;
AQHREACT_UNIT *sourceUnit;
AQHREACT_UNIT *targetUnit;
AQHREACT_INPUT_SLOT *inputSlot;
AQHREACT_OUTPUT_SLOT *outputSlot;
AQHREACT_LINK *link;
sourceNetName=GWEN_XMLNode_GetProperty(linkNode, "sourceNet", NULL);
sourceUnitName=GWEN_XMLNode_GetProperty(linkNode, "sourceUnit", NULL);
sourceSlotName=GWEN_XMLNode_GetProperty(linkNode, "sourceSlot", NULL);
targetNetName=GWEN_XMLNode_GetProperty(linkNode, "targetNet", NULL);
targetUnitName=GWEN_XMLNode_GetProperty(linkNode, "targetUnit", NULL);
targetSlotName=GWEN_XMLNode_GetProperty(linkNode, "targetSlot", NULL);
if (!(sourceUnitName && *sourceUnitName && sourceSlotName && *sourceSlotName &&
targetUnitName && *targetUnitName && targetSlotName && *targetSlotName)) {
DBG_ERROR(NULL,
"Link in net \"%s\" needs properties sourceUnit, sourceSlot, targetUnit and targetSlot",
AQHREACT_UnitNet_GetName(unitNet));
return GWEN_ERROR_BAD_DATA;
}
sourceUnit=AQHREACT_UnitNet_GetUnitById(unitNet, sourceUnitName);
if (sourceUnit==NULL && sourceNetName && *sourceNetName)
sourceUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, sourceNetName, sourceUnitName);
if (sourceUnit==NULL)
sourceUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, sourceUnitName);
if (sourceUnit==NULL) {
DBG_ERROR(NULL, "Source unit \"%s\" not found", sourceUnitName);
return GWEN_ERROR_NOT_FOUND;
}
outputSlot=AQHREACT_Unit_GetOutputSlotByName(sourceUnit, sourceSlotName);
if (outputSlot==NULL) {
DBG_ERROR(NULL, "Output slot \"%s\" not found for source unit \"%s\"", sourceSlotName, sourceUnitName);
return GWEN_ERROR_NOT_FOUND;
}
targetUnit=AQHREACT_UnitNet_GetUnitById(unitNet, targetUnitName);
if (targetUnit==NULL && targetNetName && *targetNetName)
targetUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, targetNetName, targetUnitName);
if (targetUnit==NULL)
targetUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, targetUnitName);
if (targetUnit==NULL) {
DBG_ERROR(NULL, "Target unit \"%s\" not found", targetUnitName);
return GWEN_ERROR_NOT_FOUND;
}
inputSlot=AQHREACT_Unit_GetOrCreateUnusedInputSlotByName(targetUnit, targetSlotName);
if (inputSlot==NULL) {
DBG_ERROR(NULL, "Input slot \"%s\" not found for target unit \"%s\"", targetSlotName, targetUnitName);
return GWEN_ERROR_NOT_FOUND;
}
link=AQHREACT_Link_new();
AQHREACT_Link_SetTargetUnitId(link, targetUnitName);
AQHREACT_Link_SetTargetUnit(link, targetUnit);
AQHREACT_Link_SetTargetInputSlotIdForUnit(link, AQHREACT_InputSlot_GetIdForUnit(inputSlot));
AQHREACT_OutputSlot_AddLink(outputSlot, link);
return 0;
}
int _treeExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars)
{
int rv;
const GWEN_XMLNODE *nn;
rv=GWEN_XMLNode_ExpandProperties(n, dbVars);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
nn=GWEN_XMLNode_GetFirstTag(n);
while(nn) {
rv=_treeExpandProperties(nn, dbVars);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
nn=GWEN_XMLNode_GetNextTag(nn);
}
return 0;
}

View File

@@ -13,9 +13,10 @@
#include "./aqhome_react.h" #include "./aqhome_react.h"
AQHREACT_UNIT_NET_LIST *AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh); int AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh);
AQHREACT_UNIT *AQHomeReact_FindAndReadDataDirNetwork(AQHOME_REACT *aqh, const char *networkName);
time_t AQHomeReact_GetNewestUnitNetFiletime(const AQHOME_REACT *aqh); time_t AQHomeReact_GetNewestUnitNetFiletime(void);
#endif #endif

View File

@@ -39,29 +39,23 @@
<headers dist="true" > <headers dist="true" >
dataobject.h dataobject.h
dataobject_p.h dataobject_p.h
inputslot.h port.h
inputslot_p.h port_p.h
outputslot.h
outputslot_p.h
link.h link.h
link_p.h link_p.h
param.h param.h
param_p.h param_p.h
unit.h unit.h
unit_p.h unit_p.h
unitnet.h
unitnet_p.h
</headers> </headers>
<sources> <sources>
$(local/typefiles) $(local/typefiles)
dataobject.c dataobject.c
inputslot.c port.c
outputslot.c
link.c link.c
param.c param.c
unit.c unit.c
unitnet.c
</sources> </sources>
<useTargets> <useTargets>

View File

@@ -199,6 +199,20 @@ const char *AQHREACT_DataObjectType_toString(int t)
int AQHREACT_DataObjectType_fromString(const char *s)
{
if (s && *s) {
if (strcasecmp(s, "double")==0)
return AQHREACT_DATAOBJECTTYPE_DOUBLE;
else if (strcasecmp(s, "string")==0)
return AQHREACT_DATAOBJECTTYPE_STRING;
}
return AQHREACT_DATAOBJECTTYPE_UNKNOWN;
}
void AQHREACT_DataObject_Dump(const AQHREACT_DATAOBJECT *dataObject, GWEN_BUFFER *buf, int indent) void AQHREACT_DataObject_Dump(const AQHREACT_DATAOBJECT *dataObject, GWEN_BUFFER *buf, int indent)
{ {
if (dataObject && buf) { if (dataObject && buf) {

View File

@@ -59,6 +59,7 @@ void AQHREACT_DataObject_Dump(const AQHREACT_DATAOBJECT *dataObject, GWEN_BUFFER
const char *AQHREACT_DataObjectType_toString(int t); const char *AQHREACT_DataObjectType_toString(int t);
int AQHREACT_DataObjectType_fromString(const char *s);
#endif #endif

View File

@@ -90,6 +90,21 @@ void AQHREACT_Link_SetTargetUnit(AQHREACT_LINK *lnk, AQHREACT_UNIT *unit)
AQHREACT_PORT *AQHREACT_Link_GetTargetPort(const AQHREACT_LINK *lnk)
{
return lnk?lnk->targetPort:NULL;
}
void AQHREACT_Link_SetTargetPort(AQHREACT_LINK *lnk, AQHREACT_PORT *port)
{
if (lnk)
lnk->targetPort=port;
}
void AQHREACT_Link_Dump(const AQHREACT_LINK *lnk, GWEN_BUFFER *buf, int indent) void AQHREACT_Link_Dump(const AQHREACT_LINK *lnk, GWEN_BUFFER *buf, int indent)
{ {
if (lnk && buf) { if (lnk && buf) {

View File

@@ -18,6 +18,7 @@ GWEN_LIST_FUNCTION_DEFS(AQHREACT_LINK, AQHREACT_Link)
#include "aqhome-react/types/unit.h" #include "aqhome-react/types/unit.h"
#include "aqhome-react/types/port.h"
AQHREACT_LINK *AQHREACT_Link_new(); AQHREACT_LINK *AQHREACT_Link_new();
@@ -33,6 +34,9 @@ void AQHREACT_Link_SetTargetInputSlotIdForUnit(AQHREACT_LINK *lnk, int i);
AQHREACT_UNIT *AQHREACT_Link_GetTargetUnit(const AQHREACT_LINK *lnk); AQHREACT_UNIT *AQHREACT_Link_GetTargetUnit(const AQHREACT_LINK *lnk);
void AQHREACT_Link_SetTargetUnit(AQHREACT_LINK *lnk, AQHREACT_UNIT *unit); void AQHREACT_Link_SetTargetUnit(AQHREACT_LINK *lnk, AQHREACT_UNIT *unit);
AQHREACT_PORT *AQHREACT_Link_GetTargetPort(const AQHREACT_LINK *lnk);
void AQHREACT_Link_SetTargetPort(AQHREACT_LINK *lnk, AQHREACT_PORT *port);
void AQHREACT_Link_Dump(const AQHREACT_LINK *lnk, GWEN_BUFFER *buf, int indent); void AQHREACT_Link_Dump(const AQHREACT_LINK *lnk, GWEN_BUFFER *buf, int indent);
void AQHREACT_Link_List_Dump(const AQHREACT_LINK_LIST *lnkList, GWEN_BUFFER *buf, int indent, const char *title); void AQHREACT_Link_List_Dump(const AQHREACT_LINK_LIST *lnkList, GWEN_BUFFER *buf, int indent, const char *title);

View File

@@ -20,6 +20,7 @@ struct AQHREACT_LINK {
int targetInputSlotIdForUnit; int targetInputSlotIdForUnit;
AQHREACT_UNIT *targetUnit; AQHREACT_UNIT *targetUnit;
AQHREACT_PORT *targetPort;
}; };

View File

@@ -0,0 +1,313 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2024 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./port_p.h"
#include "aqhome-react/types/dataobject.h"
#include <gwenhywfar/debug.h>
GWEN_LIST_FUNCTIONS(AQHREACT_PORT, AQHREACT_Port)
AQHREACT_PORT *AQHREACT_Port_new()
{
AQHREACT_PORT *port;
GWEN_NEW_OBJECT(AQHREACT_PORT, port);
GWEN_LIST_INIT(AQHREACT_PORT, port);
port->linkList=AQHREACT_Link_List_new();
return port;
}
AQHREACT_PORT *AQHREACT_Port_dup(const AQHREACT_PORT *srcPort)
{
if (srcPort) {
AQHREACT_PORT *newPort;
newPort=AQHREACT_Port_new();
AQHREACT_Port_SetName(newPort, srcPort->name);
newPort->idForUnit=srcPort->idForUnit;
AQHREACT_Port_SetDescription(newPort, srcPort->description);
newPort->flags=srcPort->flags;
newPort->dataType=srcPort->dataType;
/* don't copy current dataObject */
/* don't copy current links */
return newPort;
}
return NULL;
}
void AQHREACT_Port_free(AQHREACT_PORT *port)
{
if (port) {
GWEN_LIST_FINI(AQHREACT_PORT, port);
AQHREACT_DataObject_free(port->currentDataObject);
AQHREACT_Link_List_free(port->linkList);
free(port->name);
free(port->description);
GWEN_FREE_OBJECT(port);
}
}
const char *AQHREACT_Port_GetName(const AQHREACT_PORT *port)
{
return port?port->name:NULL;
}
void AQHREACT_Port_SetName(AQHREACT_PORT *port, const char *s)
{
if (port) {
free(port->name);
port->name=s?strdup(s):NULL;
}
}
int AQHREACT_Port_GetIdForUnit(const AQHREACT_PORT *port)
{
return port?port->idForUnit:0;
}
void AQHREACT_Port_SetIdForUnit(AQHREACT_PORT *port, int i)
{
if (port)
port->idForUnit=i;
}
const char *AQHREACT_Port_GetDescription(const AQHREACT_PORT *port)
{
return port?port->description:NULL;
}
void AQHREACT_Port_SetDescription(AQHREACT_PORT *port, const char *s)
{
if (port) {
free(port->description);
port->description=s?strdup(s):NULL;
}
}
uint32_t AQHREACT_Port_GetFlags(const AQHREACT_PORT *port)
{
return port?port->flags:0;
}
void AQHREACT_Port_SetFlags(AQHREACT_PORT *port, uint32_t f)
{
if (port)
port->flags=f;
}
void AQHREACT_Port_AddFlags(AQHREACT_PORT *port, uint32_t f)
{
if (port)
port->flags|=f;
}
void AQHREACT_Port_SubFlags(AQHREACT_PORT *port, uint32_t f)
{
if (port)
port->flags&=~f;
}
int AQHREACT_Port_GetDataType(const AQHREACT_PORT *port)
{
return port?port->dataType:AQHREACT_DATAOBJECTTYPE_UNKNOWN;
}
void AQHREACT_Port_SetDataType(AQHREACT_PORT *port, int i)
{
if (port)
port->dataType=i;
}
AQHREACT_DATAOBJECT *AQHREACT_Port_GetCurrentDataObject(const AQHREACT_PORT *port)
{
return port?port->currentDataObject:NULL;
}
void AQHREACT_Port_SetCurrentDataObject(AQHREACT_PORT *port, AQHREACT_DATAOBJECT *dataObject)
{
if (port){
AQHREACT_DataObject_free(port->currentDataObject);
port->currentDataObject=dataObject;
}
}
AQHREACT_LINK_LIST *AQHREACT_Port_GetLinkList(const AQHREACT_PORT *port)
{
return port?port->linkList:NULL;
}
void AQHREACT_Port_AddLink(AQHREACT_PORT *port, AQHREACT_LINK *lnk)
{
if (port)
AQHREACT_Link_List_Add(lnk, port->linkList);
}
void AQHREACT_Port_SendData(const AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{
AQHREACT_LINK_LIST *linkList;
linkList=AQHREACT_Port_GetLinkList(port);
if (linkList) {
AQHREACT_LINK *lnk;
lnk=AQHREACT_Link_List_First(linkList);
while(lnk) {
AQHREACT_UNIT *targetUnit;
AQHREACT_PORT *targetPort;
targetUnit=AQHREACT_Link_GetTargetUnit(lnk);
targetPort=AQHREACT_Link_GetTargetPort(lnk);
if (targetUnit && targetPort) {
DBG_DEBUG(NULL, "%s: Sending data to %s:%s",
AQHREACT_Port_GetName(port), AQHREACT_Unit_GetId(targetUnit), AQHREACT_Port_GetName(targetPort));
AQHREACT_Unit_InputData(targetUnit, targetPort, dataObject);
}
lnk=AQHREACT_Link_List_Next(lnk);
} /* while */
} /* if linkList */
}
AQHREACT_PORT *AQHREACT_Port_List_GetByName(const AQHREACT_PORT_LIST *portList, const char *name)
{
if (portList && name) {
AQHREACT_PORT *port;
port=AQHREACT_Port_List_First(portList);
while(port) {
const char *s;
s=AQHREACT_Port_GetName(port);
if (s && strcasecmp(s, name)==0)
return port;
port=AQHREACT_Port_List_Next(port);
}
}
return NULL;
}
AQHREACT_PORT *AQHREACT_Port_List_GetByIdForUnit(const AQHREACT_PORT_LIST *portList, int id)
{
if (portList) {
AQHREACT_PORT *port;
port=AQHREACT_Port_List_First(portList);
while(port) {
if (id==AQHREACT_Port_GetIdForUnit(port))
return port;
port=AQHREACT_Port_List_Next(port);
}
}
return NULL;
}
void AQHREACT_Port_Dump(const AQHREACT_PORT *port, GWEN_BUFFER *buf, int indent)
{
if (port && buf) {
if (indent)
GWEN_Buffer_FillWithBytes(buf, ' ', indent);
GWEN_Buffer_AppendArgs(buf, "name........: %s\n", (port->name)?(port->name):"<empty>");
if (indent)
GWEN_Buffer_FillWithBytes(buf, ' ', indent);
GWEN_Buffer_AppendArgs(buf, "description.: %s\n", (port->description)?(port->description):"<empty>");
if (indent)
GWEN_Buffer_FillWithBytes(buf, ' ', indent);
GWEN_Buffer_AppendArgs(buf, "data type...: %s\n", AQHREACT_DataObjectType_toString(port->dataType));
if (indent)
GWEN_Buffer_FillWithBytes(buf, ' ', indent);
GWEN_Buffer_AppendArgs(buf, "flags.......: %08x\n", port->flags);
AQHREACT_Link_List_Dump(port->linkList, buf, indent, "Link List:");
}
}
void AQHREACT_Port_List_Dump(const AQHREACT_PORT_LIST *portList, GWEN_BUFFER *buf, int indent, const char *title)
{
if (portList && buf) {
const AQHREACT_PORT *port;
if (indent)
GWEN_Buffer_FillWithBytes(buf, ' ', indent);
GWEN_Buffer_AppendArgs(buf, "%s\n", (title && *title)?title:"Port List:\n");
port=AQHREACT_Port_List_First(portList);
while(port) {
GWEN_Buffer_FillWithBytes(buf, ' ', indent+2);
GWEN_Buffer_AppendString(buf, "Port:\n");
AQHREACT_Port_Dump(port, buf, indent+4);
port=AQHREACT_Port_List_Next(port);
}
}
}

View File

@@ -0,0 +1,67 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2024 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_REACT_PORT_H
#define AQHOME_REACT_PORT_H
#include <gwenhywfar/list.h>
typedef struct AQHREACT_PORT AQHREACT_PORT;
GWEN_LIST_FUNCTION_DEFS(AQHREACT_PORT, AQHREACT_Port)
#include "aqhome-react/aqhome_react.h"
#include "aqhome-react/types/link.h"
#include "aqhome-react/types/dataobject.h"
AQHREACT_PORT *AQHREACT_Port_new();
AQHREACT_PORT *AQHREACT_Port_dup(const AQHREACT_PORT *srcPort);
void AQHREACT_Port_free(AQHREACT_PORT *port);
const char *AQHREACT_Port_GetName(const AQHREACT_PORT *port);
void AQHREACT_Port_SetName(AQHREACT_PORT *port, const char *s);
int AQHREACT_Port_GetIdForUnit(const AQHREACT_PORT *port);
void AQHREACT_Port_SetIdForUnit(AQHREACT_PORT *port, int i);
const char *AQHREACT_Port_GetDescription(const AQHREACT_PORT *port);
void AQHREACT_Port_SetDescription(AQHREACT_PORT *port, const char *s);
uint32_t AQHREACT_Port_GetFlags(const AQHREACT_PORT *port);
void AQHREACT_Port_SetFlags(AQHREACT_PORT *port, uint32_t f);
void AQHREACT_Port_AddFlags(AQHREACT_PORT *port, uint32_t f);
void AQHREACT_Port_SubFlags(AQHREACT_PORT *port, uint32_t f);
int AQHREACT_Port_GetDataType(const AQHREACT_PORT *port);
void AQHREACT_Port_SetDataType(AQHREACT_PORT *port, int i);
AQHREACT_DATAOBJECT *AQHREACT_Port_GetCurrentDataObject(const AQHREACT_PORT *port);
void AQHREACT_Port_SetCurrentDataObject(AQHREACT_PORT *port, AQHREACT_DATAOBJECT *dataObject);
void AQHREACT_Port_SendData(const AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
AQHREACT_LINK_LIST *AQHREACT_Port_GetLinkList(const AQHREACT_PORT *port);
void AQHREACT_Port_AddLink(AQHREACT_PORT *port, AQHREACT_LINK *lnk);
AQHREACT_PORT *AQHREACT_Port_List_GetByName(const AQHREACT_PORT_LIST *portList, const char *name);
AQHREACT_PORT *AQHREACT_Port_List_GetByIdForUnit(const AQHREACT_PORT_LIST *portList, int id);
void AQHREACT_Port_Dump(const AQHREACT_PORT *port, GWEN_BUFFER *buf, int indent);
void AQHREACT_Port_List_Dump(const AQHREACT_PORT_LIST *portList, GWEN_BUFFER *buf, int indent, const char *title);
#endif

View File

@@ -0,0 +1,31 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2024 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_REACT_PORT_P_H
#define AQHOME_REACT_PORT_P_H
#include "aqhome-react/types/port.h"
struct AQHREACT_PORT {
GWEN_LIST_ELEMENT(AQHREACT_PORT)
char *name;
char *description;
int idForUnit;
uint32_t flags;
int dataType;
AQHREACT_DATAOBJECT *currentDataObject;
AQHREACT_LINK_LIST *linkList;
};
#endif

View File

@@ -30,9 +30,9 @@ AQHREACT_UNIT *AQHREACT_Unit_new(AQHOME_REACT *aqh)
GWEN_LIST_INIT(AQHREACT_UNIT, unit); GWEN_LIST_INIT(AQHREACT_UNIT, unit);
unit->aqHomeReact=aqh; unit->aqHomeReact=aqh;
unit->inputSlotList=AQHREACT_InputSlot_List_new();
unit->outputSlotList=AQHREACT_OutputSlot_List_new();
unit->paramList=AQHREACT_Param_List_new(); unit->paramList=AQHREACT_Param_List_new();
unit->inputPortList=AQHREACT_Port_List_new();
unit->outputPortList=AQHREACT_Port_List_new();
return unit; return unit;
} }
@@ -46,8 +46,8 @@ void AQHREACT_Unit_free(AQHREACT_UNIT *unit)
GWEN_INHERIT_FINI(AQHREACT_UNIT, unit); GWEN_INHERIT_FINI(AQHREACT_UNIT, unit);
free(unit->name); free(unit->name);
free(unit->description); free(unit->description);
AQHREACT_InputSlot_List_free(unit->inputSlotList); AQHREACT_Port_List_free(unit->outputPortList);
AQHREACT_OutputSlot_List_free(unit->outputSlotList); AQHREACT_Port_List_free(unit->inputPortList);
AQHREACT_Param_List_free(unit->paramList); AQHREACT_Param_List_free(unit->paramList);
GWEN_FREE_OBJECT(unit); GWEN_FREE_OBJECT(unit);
} }
@@ -113,17 +113,10 @@ void AQHREACT_Unit_SetId(AQHREACT_UNIT *unit, const char *s)
int AQHREACT_Unit_GetNextInputSlotId(const AQHREACT_UNIT *unit) void AQHREACT_Unit_SetNextInputPortId(AQHREACT_UNIT *unit, int i)
{
return unit?unit->nextInputSlotId:-1;
}
void AQHREACT_Unit_SetNextInputSlotId(AQHREACT_UNIT *unit, int i)
{ {
if (unit) if (unit)
unit->nextInputSlotId=i; unit->nextInputPortId=i;
} }
@@ -174,36 +167,102 @@ void AQHREACT_Unit_SetGpTimestamp(AQHREACT_UNIT *unit, uint64_t t)
AQHREACT_INPUT_SLOT_LIST *AQHREACT_Unit_GetInputSlots(const AQHREACT_UNIT *unit) AQHREACT_PORT_LIST *AQHREACT_Unit_GetInputPortList(const AQHREACT_UNIT *unit)
{ {
return unit?unit->inputSlotList:NULL; return unit?unit->inputPortList:NULL;
} }
void AQHREACT_Unit_AddInputSlot(AQHREACT_UNIT *unit, AQHREACT_INPUT_SLOT *inSlot) void AQHREACT_Unit_AddInputPort(AQHREACT_UNIT *unit, AQHREACT_PORT *port)
{ {
if (unit) if (unit && port)
AQHREACT_InputSlot_List_Add(inSlot, unit->inputSlotList); AQHREACT_Port_List_Add(port, unit->inputPortList);
} }
AQHREACT_OUTPUT_SLOT_LIST *AQHREACT_Unit_GetOutputSlots(const AQHREACT_UNIT *unit) AQHREACT_PORT *AQHREACT_Unit_GetInputPortByName(const AQHREACT_UNIT *unit, const char *name)
{ {
return unit?unit->outputSlotList:NULL; return (unit && name)?AQHREACT_Port_List_GetByName(unit->inputPortList, name):NULL;
} }
void AQHREACT_Unit_AddOutputSlot(AQHREACT_UNIT *unit, AQHREACT_OUTPUT_SLOT *outSlot) AQHREACT_PORT *AQHREACT_Unit_GetInputPortByIdForUnit(const AQHREACT_UNIT *unit, int id)
{ {
if (unit) return unit?AQHREACT_Port_List_GetByIdForUnit(unit->inputPortList, id):NULL;
AQHREACT_OutputSlot_List_Add(outSlot, unit->outputSlotList);
} }
AQHREACT_PORT *AQHREACT_Unit_GetOrCreateUnusedInputPortByName(AQHREACT_UNIT *unit, const char *s)
{
if (unit && unit->inputPortList && s && *s) {
AQHREACT_PORT *port;
port=AQHREACT_Unit_GetInputPortByName(unit, s);
if (port) {
uint32_t flags;
const char *portName;
portName=AQHREACT_Port_GetName(port);
flags=AQHREACT_Port_GetFlags(port);
if (!(flags & AQHREACT_UNIT_FLAGS_INUSE))
return port;
if (flags & AQHREACT_UNIT_FLAGS_MULTI) { /* can we just duplicate existing? */
AQHREACT_PORT *newPort;
newPort=AQHREACT_Port_dup(port);
AQHREACT_Unit_AddInputPort(unit, newPort);
return newPort;
}
else {
DBG_INFO(NULL, "Port \"%s\" found but in use, no multi flag", portName);
}
}
}
return NULL;
}
AQHREACT_PORT_LIST *AQHREACT_Unit_GetOutputPortList(const AQHREACT_UNIT *unit)
{
return unit?unit->outputPortList:NULL;
}
void AQHREACT_Unit_AddOutputPort(AQHREACT_UNIT *unit, AQHREACT_PORT *port)
{
if (unit && port)
AQHREACT_Port_List_Add(port, unit->outputPortList);
}
AQHREACT_PORT *AQHREACT_Unit_GetOutputPortByName(const AQHREACT_UNIT *unit, const char *name)
{
return (unit && name)?AQHREACT_Port_List_GetByName(unit->outputPortList, name):NULL;
}
AQHREACT_PORT *AQHREACT_Unit_GetOutputPortByIdForUnit(const AQHREACT_UNIT *unit, int id)
{
return unit?AQHREACT_Port_List_GetByIdForUnit(unit->outputPortList, id):NULL;
}
AQHREACT_PARAM_LIST *AQHREACT_Unit_GetParamList(const AQHREACT_UNIT *unit) AQHREACT_PARAM_LIST *AQHREACT_Unit_GetParamList(const AQHREACT_UNIT *unit)
{ {
return unit?unit->paramList:NULL; return unit?unit->paramList:NULL;
@@ -383,94 +442,62 @@ AQHREACT_UNIT_PROCESS_FN AQHREACT_Unit_SetProcessFn(AQHREACT_UNIT *unit, AQHREAC
void AQHREACT_Unit_OutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void AQHREACT_Unit_OutputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
if (unit) { if (unit && port) {
if (unit->outputDataFn) if (unit->outputDataFn)
(unit->outputDataFn)(unit, slotIdForUnit, dataObject); (unit->outputDataFn)(unit, port, dataObject);
else { else {
if (unit->outputSlotList) { AQHREACT_Port_SendData(port, dataObject);
AQHREACT_OUTPUT_SLOT *slot; }
}
slot=AQHREACT_Unit_GetOutputSlotByIdForUnit(unit, slotIdForUnit);
if (slot) {
AQHREACT_LINK_LIST *linkList;
linkList=AQHREACT_OutputSlot_GetLinkList(slot);
if (linkList) {
AQHREACT_LINK *lnk;
lnk=AQHREACT_Link_List_First(linkList);
while(lnk) {
AQHREACT_UNIT *targetUnit;
int targetSlotIdForUnit;
targetUnit=AQHREACT_Link_GetTargetUnit(lnk);
targetSlotIdForUnit=AQHREACT_Link_GetTargetInputSlotIdForUnit(lnk);
if (targetUnit && targetSlotIdForUnit>=0) {
DBG_DEBUG(NULL, "%s: Sending data to %s:%d",
AQHREACT_Unit_GetId(unit),
AQHREACT_Link_GetTargetUnitId(lnk), AQHREACT_Link_GetTargetInputSlotIdForUnit(lnk));
AQHREACT_Unit_InputData(targetUnit, targetSlotIdForUnit, dataObject);
}
lnk=AQHREACT_Link_List_Next(lnk);
} /* while */
} /* if linkList */
} /* if slot */
} /* if output slot list */
} /* else */
} /* if unit */
} }
void AQHREACT_Unit_OutputDoubleData(AQHREACT_UNIT *unit, int slotIndex, double data) void AQHREACT_Unit_OutputDoubleData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, double data)
{ {
if (unit && unit->outputSlotList) { if (unit && unit->outputPortList) {
AQHREACT_DATAOBJECT *dataObject; AQHREACT_DATAOBJECT *dataObject;
dataObject=AQHREACT_DataObject_new(); dataObject=AQHREACT_DataObject_new();
AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_DataObject_SetDoubleData(dataObject, data); AQHREACT_DataObject_SetDoubleData(dataObject, data);
AQHREACT_Unit_OutputData(unit, slotIndex, dataObject); AQHREACT_Unit_OutputData(unit, port, dataObject);
AQHREACT_DataObject_free(dataObject); AQHREACT_DataObject_free(dataObject);
} }
} }
void AQHREACT_Unit_OutputStringData(AQHREACT_UNIT *unit, int slotIndex, const char *data) void AQHREACT_Unit_OutputStringData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const char *data)
{ {
if (unit && unit->outputSlotList) { if (unit && unit->outputPortList) {
AQHREACT_DATAOBJECT *dataObject; AQHREACT_DATAOBJECT *dataObject;
dataObject=AQHREACT_DataObject_new(); dataObject=AQHREACT_DataObject_new();
AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_STRING); AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_STRING);
AQHREACT_DataObject_SetStringData(dataObject, data); AQHREACT_DataObject_SetStringData(dataObject, data);
AQHREACT_Unit_OutputData(unit, slotIndex, dataObject); AQHREACT_Unit_OutputData(unit, port, dataObject);
AQHREACT_DataObject_free(dataObject); AQHREACT_DataObject_free(dataObject);
} }
} }
void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
if (unit) { if (unit && port) {
if (unit->inputDataFn) if (unit->inputDataFn)
(unit->inputDataFn)(unit, slotIdForUnit, dataObject); (unit->inputDataFn)(unit, port, dataObject);
else { else {
if (dataObject) { if (dataObject) {
AQHREACT_INPUT_SLOT *inSlot; if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_Port_GetDataType(port)) {
AQHREACT_Port_SetCurrentDataObject(port, AQHREACT_DataObject_dup(dataObject));
inSlot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, slotIdForUnit); AQHREACT_Port_SendData(port, dataObject);
if (inSlot) { AQHREACT_Port_AddFlags(port, AQHREACT_UNIT_FLAGS_CHANGED);
if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_InputSlot_GetAcceptedDataType(inSlot)) { AQHREACT_Unit_AddFlags(unit, AQHREACT_UNIT_FLAGS_CHANGED);
AQHREACT_InputSlot_SetCurrentDataObject(inSlot, AQHREACT_DataObject_dup(dataObject)); }
AQHREACT_InputSlot_AddFlags(inSlot, AQHREACT_UNIT_FLAGS_CHANGED);
AQHREACT_Unit_AddFlags(unit, AQHREACT_UNIT_FLAGS_CHANGED);
}
}
} }
} }
} }
@@ -481,13 +508,14 @@ void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHRE
int AQHREACT_Unit_Process(AQHREACT_UNIT *unit) int AQHREACT_Unit_Process(AQHREACT_UNIT *unit)
{ {
if (unit) { if (unit) {
if (unit->processFn) if (unit->processFn)
return (unit->processFn)(unit); return (unit->processFn)(unit);
else else
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit); AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit);
} }
return 0; return 0;
@@ -495,129 +523,16 @@ int AQHREACT_Unit_Process(AQHREACT_UNIT *unit)
AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetInputSlotByIdForUnit(const AQHREACT_UNIT *unit, int id) void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(AQHREACT_UNIT *unit)
{
if (unit && unit->inputSlotList && id>=0) {
AQHREACT_INPUT_SLOT *slot;
slot=AQHREACT_InputSlot_List_First(unit->inputSlotList);
while(slot) {
if (AQHREACT_InputSlot_GetIdForUnit(slot)==id)
return slot;
slot=AQHREACT_InputSlot_List_Next(slot);
}
}
return NULL;
}
AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetInputSlotByName(const AQHREACT_UNIT *unit, const char *s)
{
if (unit && unit->inputSlotList && s && *s) {
AQHREACT_INPUT_SLOT *slot;
slot=AQHREACT_InputSlot_List_First(unit->inputSlotList);
while(slot) {
const char *slotName;
slotName=AQHREACT_InputSlot_GetName(slot);
if (slotName && *slotName && strcasecmp(slotName, s)==0)
return slot;
slot=AQHREACT_InputSlot_List_Next(slot);
}
}
return NULL;
}
AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetOrCreateUnusedInputSlotByName(AQHREACT_UNIT *unit, const char *s)
{
if (unit && unit->inputSlotList && s && *s) {
AQHREACT_INPUT_SLOT *slot;
slot=AQHREACT_Unit_GetInputSlotByName(unit, s);
if (slot) {
uint32_t flags;
const char *slotName;
slotName=AQHREACT_InputSlot_GetName(slot);
flags=AQHREACT_InputSlot_GetFlags(slot);
if (!(flags & AQHREACT_UNIT_FLAGS_INUSE))
return slot;
if (flags & AQHREACT_UNIT_FLAGS_MULTI) { /* can we just duplicate existing? */
AQHREACT_INPUT_SLOT *newSlot;
newSlot=AQHREACT_InputSlot_dup(slot);
AQHREACT_InputSlot_SetIdForUnit(newSlot, (unit->nextInputSlotId)++);
AQHREACT_Unit_AddInputSlot(unit, newSlot);
return newSlot;
}
else {
DBG_INFO(NULL, "Slot \"%s\" found but in use, no multi flag", slotName);
}
}
}
return NULL;
}
AQHREACT_OUTPUT_SLOT *AQHREACT_Unit_GetOutputSlotByIdForUnit(const AQHREACT_UNIT *unit, int id)
{
if (unit && unit->outputSlotList && id>=0) {
AQHREACT_OUTPUT_SLOT *slot;
slot=AQHREACT_OutputSlot_List_First(unit->outputSlotList);
while(slot) {
if (AQHREACT_OutputSlot_GetIdForUnit(slot)==id)
return slot;
slot=AQHREACT_OutputSlot_List_Next(slot);
}
}
return NULL;
}
AQHREACT_OUTPUT_SLOT *AQHREACT_Unit_GetOutputSlotByName(const AQHREACT_UNIT *unit, const char *s)
{
if (unit && unit->outputSlotList && s && *s) {
AQHREACT_OUTPUT_SLOT *slot;
slot=AQHREACT_OutputSlot_List_First(unit->outputSlotList);
while(slot) {
const char *slotName;
slotName=AQHREACT_OutputSlot_GetName(slot);
if (slotName && *slotName && strcasecmp(slotName, s)==0)
return slot;
slot=AQHREACT_OutputSlot_List_Next(slot);
}
return slot;
}
return NULL;
}
void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(AQHREACT_UNIT *unit)
{ {
if (unit) { if (unit) {
AQHREACT_INPUT_SLOT *slot; AQHREACT_PORT *port;
unit->flags&=~AQHREACT_UNIT_FLAGS_CHANGED; unit->flags&=~AQHREACT_UNIT_FLAGS_CHANGED;
slot=AQHREACT_InputSlot_List_First(unit->inputSlotList); port=AQHREACT_Port_List_First(unit->inputPortList);
while(slot) { while(port) {
AQHREACT_InputSlot_SubFlags(slot, AQHREACT_UNIT_FLAGS_CHANGED); AQHREACT_Port_SubFlags(port, AQHREACT_UNIT_FLAGS_CHANGED);
slot=AQHREACT_InputSlot_List_Next(slot); port=AQHREACT_Port_List_Next(port);
} }
} }
} }
@@ -627,16 +542,16 @@ void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(AQHREACT_UNIT *unit)
int AQHREACT_Unit_InputHasChanged(const AQHREACT_UNIT *unit) int AQHREACT_Unit_InputHasChanged(const AQHREACT_UNIT *unit)
{ {
if (unit) { if (unit) {
AQHREACT_INPUT_SLOT *slot; AQHREACT_PORT *port;
if (unit->flags & AQHREACT_UNIT_FLAGS_CHANGED) if (unit->flags & AQHREACT_UNIT_FLAGS_CHANGED)
return 1; return 1;
slot=AQHREACT_InputSlot_List_First(unit->inputSlotList); port=AQHREACT_Port_List_First(unit->inputPortList);
while(slot) { while(port) {
if (AQHREACT_InputSlot_GetFlags(slot) & AQHREACT_UNIT_FLAGS_CHANGED) if (AQHREACT_Port_GetFlags(port) & AQHREACT_UNIT_FLAGS_CHANGED)
return 1; return 1;
slot=AQHREACT_InputSlot_List_Next(slot); port=AQHREACT_Port_List_Next(port);
} }
} }
return 0; return 0;
@@ -685,8 +600,8 @@ void AQHREACT_Unit_Dump(const AQHREACT_UNIT *unit, GWEN_BUFFER *buf, int indent)
GWEN_Buffer_AppendArgs(buf, "flags......: %08x\n", unit->flags); GWEN_Buffer_AppendArgs(buf, "flags......: %08x\n", unit->flags);
AQHREACT_Param_List_Dump(unit->paramList, buf, indent, "Unit Parameter List:"); AQHREACT_Param_List_Dump(unit->paramList, buf, indent, "Unit Parameter List:");
AQHREACT_InputSlot_List_Dump(unit->inputSlotList, buf, indent, "Input Slot List:"); AQHREACT_Port_List_Dump(unit->inputPortList, buf, indent, "Input Port List:");
AQHREACT_OutputSlot_List_Dump(unit->outputSlotList, buf, indent, "Output Slot List:"); AQHREACT_Port_List_Dump(unit->outputPortList, buf, indent, "Output Port List:");
} }
} }

View File

@@ -25,19 +25,19 @@ GWEN_INHERIT_FUNCTION_DEFS(AQHREACT_UNIT)
#include "aqhome-react/aqhome_react.h" #include "aqhome-react/aqhome_react.h"
#include "aqhome-react/types/inputslot.h" #include "aqhome-react/types/port.h"
#include "aqhome-react/types/outputslot.h"
#include "aqhome-react/types/param.h" #include "aqhome-react/types/param.h"
#include "aqhome-react/types/dataobject.h" #include "aqhome-react/types/dataobject.h"
typedef void (*AQHREACT_UNIT_INPUTDATA_FN)(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); typedef void (*AQHREACT_UNIT_INPUTDATA_FN)(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
typedef void (*AQHREACT_UNIT_OUTPUTDATA_FN)(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); typedef void (*AQHREACT_UNIT_OUTPUTDATA_FN)(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
typedef AQHREACT_PARAM* (*AQHREACT_UNIT_GETPARAMBYNAME_FN)(const AQHREACT_UNIT *unit, const char *paramName); typedef AQHREACT_PARAM* (*AQHREACT_UNIT_GETPARAMBYNAME_FN)(const AQHREACT_UNIT *unit, const char *paramName);
typedef int (*AQHREACT_UNIT_PROCESS_FN)(AQHREACT_UNIT *unit); typedef int (*AQHREACT_UNIT_PROCESS_FN)(AQHREACT_UNIT *unit);
AQHREACT_UNIT *AQHREACT_Unit_new(AQHOME_REACT *aqh); AQHREACT_UNIT *AQHREACT_Unit_new(AQHOME_REACT *aqh);
void AQHREACT_Unit_free(AQHREACT_UNIT *unit); void AQHREACT_Unit_free(AQHREACT_UNIT *unit);
@@ -52,9 +52,6 @@ void AQHREACT_Unit_SetDescription(AQHREACT_UNIT *unit, const char *s);
const char *AQHREACT_Unit_GetId(const AQHREACT_UNIT *unit); const char *AQHREACT_Unit_GetId(const AQHREACT_UNIT *unit);
void AQHREACT_Unit_SetId(AQHREACT_UNIT *unit, const char *s); void AQHREACT_Unit_SetId(AQHREACT_UNIT *unit, const char *s);
int AQHREACT_Unit_GetNextInputSlotId(const AQHREACT_UNIT *unit);
void AQHREACT_Unit_SetNextInputSlotId(AQHREACT_UNIT *unit, int i);
uint32_t AQHREACT_Unit_GetFlags(const AQHREACT_UNIT *unit); uint32_t AQHREACT_Unit_GetFlags(const AQHREACT_UNIT *unit);
void AQHREACT_Unit_SetFlags(AQHREACT_UNIT *unit, uint32_t i); void AQHREACT_Unit_SetFlags(AQHREACT_UNIT *unit, uint32_t i);
void AQHREACT_Unit_AddFlags(AQHREACT_UNIT *unit, uint32_t i); void AQHREACT_Unit_AddFlags(AQHREACT_UNIT *unit, uint32_t i);
@@ -65,19 +62,20 @@ uint64_t AQHREACT_Unit_GetGpTimestamp(const AQHREACT_UNIT *unit);
void AQHREACT_Unit_SetGpTimestamp(AQHREACT_UNIT *unit, uint64_t t); void AQHREACT_Unit_SetGpTimestamp(AQHREACT_UNIT *unit, uint64_t t);
AQHREACT_INPUT_SLOT_LIST *AQHREACT_Unit_GetInputSlots(const AQHREACT_UNIT *unit); AQHREACT_PORT_LIST *AQHREACT_Unit_GetInputPortList(const AQHREACT_UNIT *unit);
void AQHREACT_Unit_AddInputSlot(AQHREACT_UNIT *unit, AQHREACT_INPUT_SLOT *inSlot); void AQHREACT_Unit_AddInputPort(AQHREACT_UNIT *unit, AQHREACT_PORT *port);
AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetInputSlotByIdForUnit(const AQHREACT_UNIT *unit, int id); AQHREACT_PORT *AQHREACT_Unit_GetInputPortByName(const AQHREACT_UNIT *unit, const char *s);
AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetInputSlotByName(const AQHREACT_UNIT *unit, const char *s); AQHREACT_PORT *AQHREACT_Unit_GetInputPortByIdForUnit(const AQHREACT_UNIT *unit, int id);
AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetOrCreateUnusedInputSlotByName(AQHREACT_UNIT *unit, const char *s); AQHREACT_PORT *AQHREACT_Unit_GetOrCreateUnusedInputPortByName(AQHREACT_UNIT *unit, const char *s);
AQHREACT_PORT_LIST *AQHREACT_Unit_GetOutputPortList(const AQHREACT_UNIT *unit);
void AQHREACT_Unit_AddOutputPort(AQHREACT_UNIT *unit, AQHREACT_PORT *port);
AQHREACT_PORT *AQHREACT_Unit_GetOutputPortByName(const AQHREACT_UNIT *unit, const char *s);
AQHREACT_PORT *AQHREACT_Unit_GetOutputPortByIdForUnit(const AQHREACT_UNIT *unit, int id);
AQHREACT_OUTPUT_SLOT_LIST *AQHREACT_Unit_GetOutputSlots(const AQHREACT_UNIT *unit); void AQHREACT_Unit_SetNextInputPortId(AQHREACT_UNIT *unit, int i);
void AQHREACT_Unit_AddOutputSlot(AQHREACT_UNIT *unit, AQHREACT_OUTPUT_SLOT *outSlot);
AQHREACT_OUTPUT_SLOT *AQHREACT_Unit_GetOutputSlotByIdForUnit(const AQHREACT_UNIT *unit, int idx);
AQHREACT_OUTPUT_SLOT *AQHREACT_Unit_GetOutputSlotByName(const AQHREACT_UNIT *unit, const char *s);
void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(AQHREACT_UNIT *unit); void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(AQHREACT_UNIT *unit);
int AQHREACT_Unit_InputHasChanged(const AQHREACT_UNIT *unit); int AQHREACT_Unit_InputHasChanged(const AQHREACT_UNIT *unit);
@@ -89,12 +87,12 @@ void AQHREACT_Unit_SetParamValueDouble(AQHREACT_UNIT *unit, const char *paramNam
const char *AQHREACT_Unit_GetParamValueString(const AQHREACT_UNIT *unit, const char *paramName, const char *defVal); const char *AQHREACT_Unit_GetParamValueString(const AQHREACT_UNIT *unit, const char *paramName, const char *defVal);
void AQHREACT_Unit_SetParamValueString(AQHREACT_UNIT *unit, const char *paramName, const char *val); void AQHREACT_Unit_SetParamValueString(AQHREACT_UNIT *unit, const char *paramName, const char *val);
void AQHREACT_Unit_OutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); void AQHREACT_Unit_OutputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
void AQHREACT_Unit_OutputDoubleData(AQHREACT_UNIT *unit, int slotIdForUnit, double data); void AQHREACT_Unit_OutputDoubleData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, double data);
void AQHREACT_Unit_OutputStringData(AQHREACT_UNIT *unit, int slotIdForUnit, const char *data); void AQHREACT_Unit_OutputStringData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const char *data);
void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
/** /**
* Process inputs and generate output. * Process inputs and generate output.

View File

@@ -25,10 +25,10 @@ struct AQHREACT_UNIT {
uint32_t flags; uint32_t flags;
uint64_t gpTimestamp; uint64_t gpTimestamp;
int nextInputSlotId; int nextInputPortId;
AQHREACT_INPUT_SLOT_LIST *inputSlotList; AQHREACT_PORT_LIST *inputPortList;
AQHREACT_OUTPUT_SLOT_LIST *outputSlotList; AQHREACT_PORT_LIST *outputPortList;
AQHREACT_PARAM_LIST *paramList; AQHREACT_PARAM_LIST *paramList;

View File

@@ -31,7 +31,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
@@ -43,8 +43,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_
AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh) AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
AQHREACT_OUTPUT_SLOT *outputSlot; AQHREACT_PORT *port;
AQHREACT_INPUT_SLOT *inputSlot;
AQHREACT_PARAM *param; AQHREACT_PARAM *param;
unit=AQHREACT_Unit_new(aqh); unit=AQHREACT_Unit_new(aqh);
@@ -52,17 +51,17 @@ AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh)
AQHREACT_Unit_SetDescription(unit, "Highpass filter for data"); AQHREACT_Unit_SetDescription(unit, "Highpass filter for data");
AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData);
outputSlot=AQHREACT_OutputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_OutputSlot_SetName(outputSlot, "output"); AQHREACT_Port_SetName(port, "output");
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_HIGHPASS_OUTSLOT_OUTPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_HIGHPASS_OUTSLOT_OUTPUT);
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddOutputSlot(unit, outputSlot); AQHREACT_Unit_AddOutputPort(unit, port);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "input"); AQHREACT_Port_SetName(port, "input");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_HIGHPASS_INSLOT_INPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_HIGHPASS_INSLOT_INPUT);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
param=AQHREACT_Param_new(); param=AQHREACT_Param_new();
AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_HIGHPASS_PARAM_LIMIT); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_HIGHPASS_PARAM_LIMIT);
@@ -79,17 +78,22 @@ AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh)
void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_HIGHPASS_INSLOT_INPUT) { if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_HIGHPASS_INSLOT_INPUT) {
double data; AQHREACT_PORT *outputPort;
double limit;
double newValue;
data=AQHREACT_DataObject_GetDoubleData(dataObject); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_HIGHPASS_OUTSLOT_OUTPUT);
limit=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HIGHPASS_PARAM_LIMIT, data); if (outputPort) {
newValue=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HIGHPASS_PARAM_NEWVALUE, data); double data;
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_HIGHPASS_OUTSLOT_OUTPUT, (data>=limit)?data:newValue); double limit;
double newValue;
data=AQHREACT_DataObject_GetDoubleData(dataObject);
limit=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HIGHPASS_PARAM_LIMIT, data);
newValue=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HIGHPASS_PARAM_NEWVALUE, data);
AQHREACT_Unit_OutputDoubleData(unit, outputPort, (data>=limit)?data:newValue);
}
} }
} }

View File

@@ -89,27 +89,26 @@ AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQHOME_REACT *aqh)
AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh) AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
AQHREACT_OUTPUT_SLOT *outputSlot; AQHREACT_PORT *port;
AQHREACT_INPUT_SLOT *inputSlot;
unit=AQHREACT_Unit_new(aqh); unit=AQHREACT_Unit_new(aqh);
AQHREACT_Unit_SetName(unit, "or"); AQHREACT_Unit_SetName(unit, "or");
AQHREACT_Unit_SetDescription(unit, "Logical OR inputs"); AQHREACT_Unit_SetDescription(unit, "Logical OR inputs");
AQHREACT_Unit_SetNextInputSlotId(unit, AQHOMEREACT_UNIT_LOGICAL_INSLOT_AUTOINPUT); /* for auto-gen multi-slots */ AQHREACT_Unit_SetNextInputPortId(unit, AQHOMEREACT_UNIT_LOGICAL_INSLOT_AUTOINPUT); /* for auto-gen multi-slots */
outputSlot=AQHREACT_OutputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_OutputSlot_SetName(outputSlot, "output"); AQHREACT_Port_SetName(port, "output");
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT);
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddOutputSlot(unit, outputSlot); AQHREACT_Unit_AddOutputPort(unit, port);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "input"); AQHREACT_Port_SetName(port, "input");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_LOGICAL_INSLOT_INPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_LOGICAL_INSLOT_INPUT);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_InputSlot_AddFlags(inputSlot, AQHREACT_UNIT_FLAGS_MULTI); AQHREACT_Port_AddFlags(port, AQHREACT_UNIT_FLAGS_MULTI);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
return unit; return unit;
} }
@@ -119,41 +118,46 @@ AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh)
int _cbProcessOr(AQHREACT_UNIT *unit) int _cbProcessOr(AQHREACT_UNIT *unit)
{ {
if (unit && AQHREACT_Unit_InputHasChanged(unit)) { if (unit && AQHREACT_Unit_InputHasChanged(unit)) {
AQHREACT_INPUT_SLOT_LIST *inputSlotList; AQHREACT_PORT *outputPort;
inputSlotList=AQHREACT_Unit_GetInputSlots(unit); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT);
if (inputSlotList) { if (outputPort) {
const AQHREACT_INPUT_SLOT *inputSlot; AQHREACT_PORT_LIST *portList;
int result=0;
portList=AQHREACT_Unit_GetInputPortList(unit);
inputSlot=AQHREACT_InputSlot_List_First(inputSlotList); if (portList) {
while(inputSlot) { const AQHREACT_PORT *port;
const char *slotName; int result=0;
const AQHREACT_DATAOBJECT *dataObject;
port=AQHREACT_Port_List_First(portList);
slotName=AQHREACT_InputSlot_GetName(inputSlot); while(port) {
dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot); const char *portName;
if (dataObject) { const AQHREACT_DATAOBJECT *dataObject;
if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
double d; portName=AQHREACT_Port_GetName(port);
dataObject=AQHREACT_Port_GetCurrentDataObject(port);
d=AQHREACT_DataObject_GetDoubleData(dataObject); if (dataObject) {
if (d>0.0) if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
result|=1; double d;
}
else { d=AQHREACT_DataObject_GetDoubleData(dataObject);
DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:"<unnamed>"); if (d>0.0)
} result|=1;
} }
else { else {
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:"<unnamed>"); DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", portName?portName:"<unnamed>");
} }
inputSlot=AQHREACT_InputSlot_List_Next(inputSlot); }
else {
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", portName?portName:"<unnamed>");
}
port=AQHREACT_Port_List_Next(port);
}
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit);
AQHREACT_Unit_OutputDoubleData(unit, outputPort, result?1.0:0.0);
return 1;
} }
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit);
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0);
return 1;
} }
} }
@@ -165,41 +169,46 @@ int _cbProcessOr(AQHREACT_UNIT *unit)
int _cbProcessAnd(AQHREACT_UNIT *unit) int _cbProcessAnd(AQHREACT_UNIT *unit)
{ {
if (unit && AQHREACT_Unit_InputHasChanged(unit)) { if (unit && AQHREACT_Unit_InputHasChanged(unit)) {
AQHREACT_INPUT_SLOT_LIST *inputSlotList; AQHREACT_PORT *outputPort;
inputSlotList=AQHREACT_Unit_GetInputSlots(unit); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT);
if (inputSlotList) { if (outputPort) {
const AQHREACT_INPUT_SLOT *inputSlot; AQHREACT_PORT_LIST *portList;
int result=1;
portList=AQHREACT_Unit_GetInputPortList(unit);
inputSlot=AQHREACT_InputSlot_List_First(inputSlotList); if (portList) {
while(inputSlot) { AQHREACT_PORT *port;
const char *slotName; int result=1;
const AQHREACT_DATAOBJECT *dataObject;
port=AQHREACT_Port_List_First(portList);
slotName=AQHREACT_InputSlot_GetName(inputSlot); while(port) {
dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot); const char *portName;
if (dataObject) { const AQHREACT_DATAOBJECT *dataObject;
if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
double d; portName=AQHREACT_Port_GetName(port);
dataObject=AQHREACT_Port_GetCurrentDataObject(port);
d=AQHREACT_DataObject_GetDoubleData(dataObject); if (dataObject) {
if (!(d>0.0)) if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
result=0; double d;
}
else { d=AQHREACT_DataObject_GetDoubleData(dataObject);
DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:"<unnamed>"); if (!(d>0.0))
} result=0;
} }
else { else {
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:"<unnamed>"); DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", portName?portName:"<unnamed>");
} }
inputSlot=AQHREACT_InputSlot_List_Next(inputSlot); }
else {
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", portName?portName:"<unnamed>");
}
port=AQHREACT_Port_List_Next(port);
}
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit);
AQHREACT_Unit_OutputDoubleData(unit, port, result?1.0:0.0);
return 1;
} }
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit);
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0);
return 1;
} }
} }
@@ -211,41 +220,46 @@ int _cbProcessAnd(AQHREACT_UNIT *unit)
int _cbProcessXor(AQHREACT_UNIT *unit) int _cbProcessXor(AQHREACT_UNIT *unit)
{ {
if (unit && AQHREACT_Unit_InputHasChanged(unit)) { if (unit && AQHREACT_Unit_InputHasChanged(unit)) {
AQHREACT_INPUT_SLOT_LIST *inputSlotList; AQHREACT_PORT *outputPort;
inputSlotList=AQHREACT_Unit_GetInputSlots(unit); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT);
if (inputSlotList) { if (outputPort) {
const AQHREACT_INPUT_SLOT *inputSlot; AQHREACT_PORT_LIST *portList;
int result=0;
portList=AQHREACT_Unit_GetInputPortList(unit);
inputSlot=AQHREACT_InputSlot_List_First(inputSlotList); if (portList) {
while(inputSlot) { AQHREACT_PORT *port;
const char *slotName; int result=0;
const AQHREACT_DATAOBJECT *dataObject;
port=AQHREACT_Port_List_First(portList);
slotName=AQHREACT_InputSlot_GetName(inputSlot); while(port) {
dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot); const char *portName;
if (dataObject) { const AQHREACT_DATAOBJECT *dataObject;
if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
double d; portName=AQHREACT_Port_GetName(port);
dataObject=AQHREACT_Port_GetCurrentDataObject(port);
d=AQHREACT_DataObject_GetDoubleData(dataObject); if (dataObject) {
if (d>0.0) if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
result^=1; /*only xor when >0.0, otherwise no change (x XOR 0 is still x) */ double d;
}
else { d=AQHREACT_DataObject_GetDoubleData(dataObject);
DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:"<unnamed>"); if (d>0.0)
} result^=1; /*only xor when >0.0, otherwise no change (x XOR 0 is still x) */
} }
else { else {
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:"<unnamed>"); DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", portName?portName:"<unnamed>");
} }
inputSlot=AQHREACT_InputSlot_List_Next(inputSlot); }
else {
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", portName?portName:"<unnamed>");
}
port=AQHREACT_Port_List_Next(port);
}
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit);
AQHREACT_Unit_OutputDoubleData(unit, port, result?1.0:0.0);
return 1;
} }
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit);
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0);
return 1;
} }
} }

View File

@@ -31,7 +31,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
@@ -43,8 +43,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_
AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh) AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
AQHREACT_OUTPUT_SLOT *outputSlot; AQHREACT_PORT *port;
AQHREACT_INPUT_SLOT *inputSlot;
AQHREACT_PARAM *param; AQHREACT_PARAM *param;
unit=AQHREACT_Unit_new(aqh); unit=AQHREACT_Unit_new(aqh);
@@ -52,17 +51,17 @@ AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh)
AQHREACT_Unit_SetDescription(unit, "Lowpass filter for data"); AQHREACT_Unit_SetDescription(unit, "Lowpass filter for data");
AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData);
outputSlot=AQHREACT_OutputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_OutputSlot_SetName(outputSlot, "output"); AQHREACT_Port_SetName(port, "output");
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_LOWPASS_OUTSLOT_OUTPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_LOWPASS_OUTSLOT_OUTPUT);
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddOutputSlot(unit, outputSlot); AQHREACT_Unit_AddOutputPort(unit, port);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "input"); AQHREACT_Port_SetName(port, "input");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_LOWPASS_INSLOT_INPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_LOWPASS_INSLOT_INPUT);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
param=AQHREACT_Param_new(); param=AQHREACT_Param_new();
AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_LOWPASS_PARAM_LIMIT); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_LOWPASS_PARAM_LIMIT);
@@ -79,17 +78,22 @@ AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh)
void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_LOWPASS_INSLOT_INPUT) { if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_LOWPASS_INSLOT_INPUT) {
double data; AQHREACT_PORT *outputPort;
double limit;
double newValue;
data=AQHREACT_DataObject_GetDoubleData(dataObject); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_LOWPASS_OUTSLOT_OUTPUT);
limit=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_LOWPASS_PARAM_LIMIT, data); if (outputPort) {
newValue=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_LOWPASS_PARAM_NEWVALUE, data); double data;
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOWPASS_OUTSLOT_OUTPUT, (data<=limit)?data:newValue); double limit;
double newValue;
data=AQHREACT_DataObject_GetDoubleData(dataObject);
limit=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_LOWPASS_PARAM_LIMIT, data);
newValue=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_LOWPASS_PARAM_NEWVALUE, data);
AQHREACT_Unit_OutputDoubleData(unit, outputPort, (data<=limit)?data:newValue);
}
} }
} }

View File

@@ -16,7 +16,7 @@
#include <gwenhywfar/xml.h> #include <gwenhywfar/xml.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
//TODO: set params //TODO: read modules
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -36,31 +36,43 @@ GWEN_LIST_FUNCTIONS(MODULE_PROXY_DESCR, ModuleProxyDescr);
*/ */
static void GWENHYWFAR_CB _freeData(void *bp, void *p); static void GWENHYWFAR_CB _freeData(void *bp, void *p);
static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
static void _cbOutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject);
static AQHREACT_PARAM *_cbGetParamByName(const AQHREACT_UNIT *unit, const char *paramName); static AQHREACT_PARAM *_cbGetParamByName(const AQHREACT_UNIT *unit, const char *paramName);
static int _cbProcess(AQHREACT_UNIT *unit); static int _cbProcess(AQHREACT_UNIT *unit);
static void _readProxyFromXml(AQHREACT_UNIT *unit, static void _readProxyFromXml(GWEN_XMLNODE *xmlNode,
GWEN_XMLNODE *xmlNode,
MODULE_PROXY_DESCR_LIST *proxyDescrList, MODULE_PROXY_DESCR_LIST *proxyDescrList,
const char *mainGroupName, const char *mainGroupName,
const char *groupName, const char *groupName,
const char *nameProperty, const char *nameProperty,
const char *targetObjectProperty, const char *targetObjectProperty,
const char *targetNameProperty); const char *targetNameProperty);
static void _readInputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); static int _readInputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode);
static void _readOutputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); static int _readOutputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode);
static int _finishInSlots(AQHREACT_UNIT *unit);
static int _finishOutSlots(AQHREACT_UNIT *unit);
static int _finishParams(AQHREACT_UNIT *unit); static int _finishParams(AQHREACT_UNIT *unit);
static void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); static void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode);
static AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *parentUnit, GWEN_XMLNODE *xmlNode); static AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode);
static int _readParamsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNodeUnit, const char *mainGroupName); static int _readParamsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNodeUnit, const char *mainGroupName);
static int _readParamFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode); static int _readParamFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode);
static int _setParamDataFromString(AQHREACT_PARAM *param, const char *value); static int _setParamDataFromString(AQHREACT_PARAM *param, const char *value);
static int _readLinksFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); static int _readLinksFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode);
static int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode); static int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode);
static int _linkFromThisModulesInput(AQHOME_REACT *aqh,
AQHREACT_UNIT *unit,
const char *emittingPortName,
const char *receivingUnitName,
const char *receivingPortName);
static int _linkToModulesOutput(AQHOME_REACT *aqh,
AQHREACT_UNIT *unit,
const char *emittingUnitName,
const char *emittingPortName,
const char *receivingPortName);
static int _linkBetweenUnits(AQHOME_REACT *aqh,
AQHREACT_UNIT *unit,
const char *emittingUnitName,
const char *emittingPortName,
const char *receivingUnitName,
const char *receivingPortName);
@@ -138,12 +150,9 @@ AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQHOME_REACT *aqh)
GWEN_INHERIT_SETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit, xunit, _freeData); GWEN_INHERIT_SETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit, xunit, _freeData);
xunit->paramProxyList=ModuleProxyDescr_List_new(); xunit->paramProxyList=ModuleProxyDescr_List_new();
xunit->inSlotProxyList=ModuleProxyDescr_List_new();
xunit->outSlotProxyList=ModuleProxyDescr_List_new();
xunit->unitList=AQHREACT_Unit_List_new(); xunit->unitList=AQHREACT_Unit_List_new();
AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData);
AQHREACT_Unit_SetOutputDataFn(unit, _cbOutputData);
AQHREACT_Unit_SetGetParamByNameFn(unit, _cbGetParamByName); AQHREACT_Unit_SetGetParamByNameFn(unit, _cbGetParamByName);
AQHREACT_Unit_SetProcessFn(unit, _cbProcess); AQHREACT_Unit_SetProcessFn(unit, _cbProcess);
@@ -152,15 +161,13 @@ AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQHOME_REACT *aqh)
void _freeData(void *bp, void *p) void _freeData(GWEN_UNUSED void *bp, void *p)
{ {
AQHREACT_UNIT_MODULE *xunit; AQHREACT_UNIT_MODULE *xunit;
xunit=(AQHREACT_UNIT_MODULE*) p; xunit=(AQHREACT_UNIT_MODULE*) p;
AQHREACT_Unit_List_free(xunit->unitList); AQHREACT_Unit_List_free(xunit->unitList);
ModuleProxyDescr_List_free(xunit->outSlotProxyList);
ModuleProxyDescr_List_free(xunit->inSlotProxyList);
ModuleProxyDescr_List_free(xunit->paramProxyList); ModuleProxyDescr_List_free(xunit->paramProxyList);
GWEN_FREE_OBJECT(xunit); GWEN_FREE_OBJECT(xunit);
@@ -171,110 +178,67 @@ void _freeData(void *bp, void *p)
AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode) AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode)
{ {
const char *t; const char *t;
const char *id;
AQHREACT_UNIT *unit;
AQHREACT_UNIT_MODULE *xunit;
int rv;
t=GWEN_XMLNode_GetProperty(xmlNode, "type", NULL); t=GWEN_XMLNode_GetProperty(xmlNode, "type", NULL);
if (t && *t) { id=GWEN_XMLNode_GetProperty(xmlNode, "id", NULL);
AQHREACT_UNIT *unit;
AQHREACT_UNIT_MODULE *xunit;
int rv;
unit=AqHomeReact_UnitModule_new(aqh); unit=AqHomeReact_UnitModule_new(aqh);
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
AQHREACT_Unit_SetName(unit, t); AQHREACT_Unit_SetName(unit, t);
AQHREACT_Unit_SetId(unit, id);
_readProxyFromXml(unit, xmlNode, xunit->paramProxyList, "paramdefs", "param", "name", "targetModule", "targetParam"); _readProxyFromXml(xmlNode, xunit->paramProxyList, "paramdefs", "param", "name", "targetModule", "targetParam");
_readInputSlotsFromXml(aqh, unit, xmlNode); rv=_readInputPortsFromXml(unit, xmlNode);
_readOutputSlotsFromXml(aqh, unit, xmlNode); if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
_readUnitsFromXml(aqh, unit, xmlNode); AQHREACT_Unit_free(unit);
rv=_finishInSlots(unit);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
rv=_finishOutSlots(unit);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
rv=_finishParams(unit);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
rv=_readParamsFromXml(unit, xmlNode, "paramDefs");
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
rv=_readLinksFromXml(aqh, unit, xmlNode);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
return unit;
}
else {
DBG_ERROR(NULL, "No \"type\" property in xml node for module");
return NULL; return NULL;
} }
rv=_readOutputPortsFromXml(unit, xmlNode);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
_readUnitsFromXml(aqh, unit, xmlNode);
rv=_finishParams(unit);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
rv=_readParamsFromXml(unit, xmlNode, "paramDefs");
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
rv=_readLinksFromXml(aqh, unit, xmlNode);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
return NULL;
}
return unit;
} }
void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void _cbInputData(GWEN_UNUSED AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
AQHREACT_UNIT_MODULE *xunit; if (port)
AQHREACT_Port_SendData(port, dataObject);
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
if (xunit) {
AQHREACT_INPUT_SLOT *slot;
slot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, slotIdForUnit);
if (slot) {
const char *slotName;
const MODULE_PROXY_DESCR *pd;
slotName=AQHREACT_InputSlot_GetName(slot);
pd=ModuleProxyDescr_List_FindByName(xunit->inSlotProxyList, slotName);
if (pd)
AQHREACT_Unit_InputData(pd->targetObjectPtr, pd->targetIdForModule, dataObject);
}
}
}
void _cbOutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject)
{
AQHREACT_UNIT_MODULE *xunit;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
if (xunit) {
AQHREACT_OUTPUT_SLOT *slot;
slot=AQHREACT_Unit_GetOutputSlotByIdForUnit(unit, slotIdForUnit);
if (slot) {
const char *slotName;
const MODULE_PROXY_DESCR *pd;
slotName=AQHREACT_OutputSlot_GetName(slot);
pd=ModuleProxyDescr_List_FindByName(xunit->outSlotProxyList, slotName);
if (pd)
AQHREACT_Unit_OutputData(pd->targetObjectPtr, pd->targetIdForModule, dataObject);
}
}
} }
@@ -322,8 +286,7 @@ int _cbProcess(AQHREACT_UNIT *unit)
void _readProxyFromXml(AQHREACT_UNIT *unit, void _readProxyFromXml(GWEN_XMLNODE *xmlNode,
GWEN_XMLNODE *xmlNode,
MODULE_PROXY_DESCR_LIST *proxyDescrList, MODULE_PROXY_DESCR_LIST *proxyDescrList,
const char *mainGroupName, const char *mainGroupName,
const char *groupName, const char *groupName,
@@ -363,136 +326,42 @@ void _readProxyFromXml(AQHREACT_UNIT *unit,
void _readInputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) int _readInputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode)
{ {
AQHREACT_UNIT_MODULE *xunit; AQHREACT_UNIT_MODULE *xunit;
GWEN_XMLNODE *nGroup; GWEN_XMLNODE *nGroup;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "inputSlots", NULL, NULL); nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "inputPorts", NULL, NULL);
if (nGroup) { if (nGroup) {
GWEN_XMLNODE *n; GWEN_XMLNODE *n;
n=GWEN_XMLNode_FindFirstTag(nGroup, "inputSlot", NULL, NULL); n=GWEN_XMLNode_FindFirstTag(nGroup, "inputPort", NULL, NULL);
while(n) { while(n) {
const char *name; const char *name;
const char *targetUnit; int dataType;
const char *targetSlot; AQHREACT_PORT *port;
int slotIdForUnit;
name=GWEN_XMLNode_GetProperty(n, "name", NULL); name=GWEN_XMLNode_GetProperty(n, "name", NULL);
targetUnit=GWEN_XMLNode_GetProperty(n, "targetUnit", NULL); dataType=AQHREACT_DataObjectType_fromString(GWEN_XMLNode_GetProperty(n, "dataType", "double"));
targetSlot=GWEN_XMLNode_GetProperty(n, "targetSlot", NULL); if (dataType==AQHREACT_DATAOBJECTTYPE_UNKNOWN) {
slotIdForUnit=GWEN_XMLNode_GetIntProperty(n, "idForUnit", 0); DBG_ERROR(NULL, "Unknown dataType: %s", GWEN_XMLNode_GetProperty(n, "dataType", "double"));
return GWEN_ERROR_BAD_DATA;
if (name && targetUnit && targetSlot) {
MODULE_PROXY_DESCR *pd;
AQHREACT_INPUT_SLOT *slot;
pd=ModuleProxyDescr_new(name, targetUnit, targetSlot); /* set pd->targetObjectPtr later */
ModuleProxyDescr_List_Add(pd, xunit->inSlotProxyList);
slot=AQHREACT_InputSlot_new();
AQHREACT_InputSlot_SetName(slot, name);
AQHREACT_InputSlot_SetIdForUnit(slot, slotIdForUnit);
AQHREACT_Unit_AddInputSlot(unit, slot);
} }
else { if (name==NULL) {
DBG_ERROR(NULL, "Incomplete input slot, ignoring"); DBG_ERROR(NULL, "Missing name in input port");
return GWEN_ERROR_BAD_DATA;
} }
n=GWEN_XMLNode_FindNextTag(n, "inputSlot", NULL, NULL);
}
}
}
/* create input port */
port=AQHREACT_Port_new();
void _readOutputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) AQHREACT_Port_SetName(port, name);
{ AQHREACT_Port_SetIdForUnit(port, ++(xunit->lastPortId));
AQHREACT_UNIT_MODULE *xunit; AQHREACT_Port_SetDataType(port, dataType);
GWEN_XMLNODE *nGroup; AQHREACT_Unit_AddInputPort(unit, port);
n=GWEN_XMLNode_FindNextTag(n, "inputPort", NULL, NULL);
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); } /* while */
nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "outputSlots", NULL, NULL);
if (nGroup) {
GWEN_XMLNODE *n;
n=GWEN_XMLNode_FindFirstTag(nGroup, "outputSlot", NULL, NULL);
while(n) {
const char *name;
const char *targetUnit;
const char *targetSlot;
int slotIdForUnit;
name=GWEN_XMLNode_GetProperty(n, "name", NULL);
targetUnit=GWEN_XMLNode_GetProperty(n, "targetUnit", NULL);
targetSlot=GWEN_XMLNode_GetProperty(n, "targetSlot", NULL);
slotIdForUnit=GWEN_XMLNode_GetIntProperty(n, "idForUnit", 0);
if (name && targetUnit && targetSlot) {
MODULE_PROXY_DESCR *pd;
AQHREACT_OUTPUT_SLOT *slot;
pd=ModuleProxyDescr_new(name, targetUnit, targetSlot); /* set pd->targetObjectPtr later */
ModuleProxyDescr_List_Add(pd, xunit->outSlotProxyList);
slot=AQHREACT_OutputSlot_new();
AQHREACT_OutputSlot_SetName(slot, name);
AQHREACT_OutputSlot_SetIdForUnit(slot, slotIdForUnit);
AQHREACT_Unit_AddOutputSlot(unit, slot);
}
else {
DBG_ERROR(NULL, "Incomplete output slot, ignoring");
}
n=GWEN_XMLNode_FindNextTag(n, "outputSlot", NULL, NULL);
}
}
}
int _finishInSlots(AQHREACT_UNIT *unit)
{
AQHREACT_UNIT_MODULE *xunit;
MODULE_PROXY_DESCR *pd;
const char *unitName;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
unitName=AQHREACT_Unit_GetName(unit);
pd=ModuleProxyDescr_List_First(xunit->inSlotProxyList);
while(pd) {
AQHREACT_UNIT *subUnit;
const AQHREACT_INPUT_SLOT *subUnitSlot;
AQHREACT_INPUT_SLOT *moduleSlot;
subUnit=AQHREACT_Unit_List_GetById(xunit->unitList, pd->targetObject);
if (subUnit==NULL) {
DBG_ERROR(NULL, "Subunit \"%s\" not found for input slot", pd->targetObject);
return GWEN_ERROR_BAD_DATA;
}
pd->targetObjectPtr=subUnit;
moduleSlot=AQHREACT_Unit_GetInputSlotByName(subUnit, pd->name);
if (moduleSlot==NULL) {
DBG_ERROR(NULL, "Unit %s: Input slot \"%s\" not defined", unitName, pd->targetName);
return GWEN_ERROR_BAD_DATA;
}
subUnitSlot=AQHREACT_Unit_GetInputSlotByName(subUnit, pd->targetName);
if (subUnitSlot==NULL) {
DBG_ERROR(NULL, "Unit %s: Input slot \"%s\" not found for subunit \"%s\"", unitName, pd->targetName, pd->targetObject);
return GWEN_ERROR_BAD_DATA;
}
AQHREACT_InputSlot_SetDescription(moduleSlot, AQHREACT_InputSlot_GetDescription(subUnitSlot));
AQHREACT_InputSlot_SetFlags(moduleSlot, AQHREACT_InputSlot_GetFlags(subUnitSlot));
AQHREACT_InputSlot_SetAcceptedDataType(moduleSlot, AQHREACT_InputSlot_GetAcceptedDataType(subUnitSlot));
pd->targetIdForModule=AQHREACT_InputSlot_GetIdForUnit(subUnitSlot);
pd=ModuleProxyDescr_List_Next(pd);
} }
return 0; return 0;
@@ -500,46 +369,42 @@ int _finishInSlots(AQHREACT_UNIT *unit)
int _finishOutSlots(AQHREACT_UNIT *unit) int _readOutputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode)
{ {
AQHREACT_UNIT_MODULE *xunit; AQHREACT_UNIT_MODULE *xunit;
MODULE_PROXY_DESCR *pd; GWEN_XMLNODE *nGroup;
const char *unitName;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
unitName=AQHREACT_Unit_GetName(unit);
pd=ModuleProxyDescr_List_First(xunit->outSlotProxyList);
while(pd) {
AQHREACT_UNIT *subUnit;
const AQHREACT_OUTPUT_SLOT *subUnitSlot;
AQHREACT_OUTPUT_SLOT *moduleSlot;
subUnit=AQHREACT_Unit_List_GetById(xunit->unitList, pd->targetObject); nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "outputPorts", NULL, NULL);
if (subUnit==NULL) { if (nGroup) {
DBG_ERROR(NULL, "Subunit \"%s\" not found for output slot", pd->targetObject); GWEN_XMLNODE *n;
return GWEN_ERROR_BAD_DATA;
n=GWEN_XMLNode_FindFirstTag(nGroup, "outputPort", NULL, NULL);
while(n) {
const char *name;
int dataType;
AQHREACT_PORT *port;
name=GWEN_XMLNode_GetProperty(n, "name", NULL);
dataType=AQHREACT_DataObjectType_fromString(GWEN_XMLNode_GetProperty(n, "dataType", "double"));
if (dataType==AQHREACT_DATAOBJECTTYPE_UNKNOWN) {
DBG_ERROR(NULL, "Unknown dataType: %s", GWEN_XMLNode_GetProperty(n, "dataType", "double"));
return GWEN_ERROR_BAD_DATA;
}
if (name==NULL) {
DBG_ERROR(NULL, "Missing name in output port");
return GWEN_ERROR_BAD_DATA;
}
/* create input port */
port=AQHREACT_Port_new();
AQHREACT_Port_SetName(port, name);
AQHREACT_Port_SetIdForUnit(port, ++(xunit->lastPortId));
AQHREACT_Port_SetDataType(port, dataType);
AQHREACT_Unit_AddOutputPort(unit, port);
n=GWEN_XMLNode_FindNextTag(n, "outputPort", NULL, NULL);
} }
pd->targetObjectPtr=subUnit;
moduleSlot=AQHREACT_Unit_GetOutputSlotByName(subUnit, pd->name);
if (moduleSlot==NULL) {
DBG_ERROR(NULL, "Unit %s: Output slot \"%s\" not defined", unitName, pd->targetName);
return GWEN_ERROR_BAD_DATA;
}
subUnitSlot=AQHREACT_Unit_GetOutputSlotByName(subUnit, pd->targetName);
if (subUnitSlot==NULL) {
DBG_ERROR(NULL, "Unit %s: Output slot \"%s\" not found for subunit \"%s\"", unitName, pd->targetName, pd->targetObject);
return GWEN_ERROR_BAD_DATA;
}
AQHREACT_OutputSlot_SetDescription(moduleSlot, AQHREACT_OutputSlot_GetDescription(subUnitSlot));
AQHREACT_OutputSlot_SetFlags(moduleSlot, AQHREACT_OutputSlot_GetFlags(subUnitSlot));
AQHREACT_OutputSlot_SetEmittedDataType(moduleSlot, AQHREACT_OutputSlot_GetEmittedDataType(subUnitSlot));
pd->targetIdForModule=AQHREACT_OutputSlot_GetIdForUnit(subUnitSlot);
pd=ModuleProxyDescr_List_Next(pd);
} }
return 0; return 0;
@@ -589,7 +454,7 @@ void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xml
while(n) { while(n) {
AQHREACT_UNIT *subUnit; AQHREACT_UNIT *subUnit;
subUnit=_readOneUnitFromXml(aqh, unit, n); subUnit=_readOneUnitFromXml(aqh, n);
if (subUnit) if (subUnit)
AQHREACT_Unit_List_Add(subUnit, xunit->unitList); AQHREACT_Unit_List_Add(subUnit, xunit->unitList);
else { else {
@@ -603,7 +468,7 @@ void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xml
AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *parentUnit, GWEN_XMLNODE *xmlNode) AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode)
{ {
const char *id; const char *id;
const char *t; const char *t;
@@ -750,63 +615,179 @@ int _readLinksFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlN
int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode) int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode)
{ {
AQHREACT_UNIT_MODULE *xunit; const char *emittingUnitName;
const char *sourceUnitName; const char *emittingPortName;
const char *sourceSlotName; const char *receivingUnitName;
const char *targetUnitName; const char *receivingPortName;
const char *targetSlotName; int rv;
AQHREACT_UNIT *sourceUnit;
AQHREACT_UNIT *targetUnit;
AQHREACT_INPUT_SLOT *inputSlot;
AQHREACT_OUTPUT_SLOT *outputSlot;
AQHREACT_LINK *link;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); emittingUnitName=GWEN_XMLNode_GetProperty(linkNode, "sourceUnit", ".");
emittingPortName=GWEN_XMLNode_GetProperty(linkNode, "sourcePort", NULL);
receivingUnitName=GWEN_XMLNode_GetProperty(linkNode, "targetUnit", ".");
receivingPortName=GWEN_XMLNode_GetProperty(linkNode, "targetPort", NULL);
sourceUnitName=GWEN_XMLNode_GetProperty(linkNode, "sourceUnit", NULL); if (!(emittingUnitName && *emittingUnitName && emittingPortName && *emittingPortName &&
sourceSlotName=GWEN_XMLNode_GetProperty(linkNode, "sourceSlot", NULL); receivingUnitName && *receivingUnitName && receivingPortName && *receivingPortName)) {
targetUnitName=GWEN_XMLNode_GetProperty(linkNode, "targetUnit", NULL);
targetSlotName=GWEN_XMLNode_GetProperty(linkNode, "targetSlot", NULL);
if (!(sourceUnitName && *sourceUnitName && sourceSlotName && *sourceSlotName &&
targetUnitName && *targetUnitName && targetSlotName && *targetSlotName)) {
DBG_ERROR(NULL, DBG_ERROR(NULL,
"Link in net \"%s\" needs properties sourceUnit, sourceSlot, targetUnit and targetSlot", "Link in net \"%s\" needs properties sourceUnit, sourcePort, targetUnit and targetPort",
AQHREACT_Unit_GetName(unit)); AQHREACT_Unit_GetName(unit));
return GWEN_ERROR_BAD_DATA; return GWEN_ERROR_BAD_DATA;
} }
sourceUnit=AQHREACT_Unit_List_GetById(xunit->unitList, sourceUnitName); if (strcasecmp(emittingUnitName, ".")==0)
if (sourceUnit==NULL) rv=_linkFromThisModulesInput(aqh, unit, emittingPortName, receivingUnitName, receivingPortName);
sourceUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, sourceUnitName); else if (strcasecmp(receivingUnitName, ".")==0)
if (sourceUnit==NULL) { rv=_linkToModulesOutput(aqh, unit, emittingUnitName, emittingPortName, receivingPortName);
DBG_ERROR(NULL, "Source unit \"%s\" not found", sourceUnitName); else
return GWEN_ERROR_NOT_FOUND; rv=_linkBetweenUnits(aqh, unit, emittingUnitName, emittingPortName, receivingUnitName, receivingPortName);
if (rv<0) {
DBG_INFO(NULL, "Error creating link: %s:%s -> %s:%s (%d)",
emittingUnitName, emittingPortName, receivingUnitName, receivingPortName, rv);
return rv;
} }
outputSlot=AQHREACT_Unit_GetOutputSlotByName(sourceUnit, sourceSlotName);
if (outputSlot==NULL) { return 0;
DBG_ERROR(NULL, "Output slot \"%s\" not found for source unit \"%s\"", sourceSlotName, sourceUnitName); }
int _linkFromThisModulesInput(AQHOME_REACT *aqh,
AQHREACT_UNIT *unit,
const char *emittingPortName,
const char *receivingUnitName,
const char *receivingPortName)
{
AQHREACT_UNIT_MODULE *xunit;
AQHREACT_UNIT *receivingUnit;
AQHREACT_PORT *receivingPort;
AQHREACT_PORT *emittingPort;
AQHREACT_LINK *link;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
receivingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, receivingUnitName);
if (receivingUnit==NULL)
receivingUnit=AqHomeReact_FindUnitByUnitId(aqh, receivingUnitName);
if (receivingUnit==NULL) {
DBG_ERROR(NULL, "Target unit \"%s\" not found", receivingUnitName);
return GWEN_ERROR_NOT_FOUND; return GWEN_ERROR_NOT_FOUND;
} }
targetUnit=AQHREACT_Unit_List_GetById(xunit->unitList, targetUnitName); emittingPort=AQHREACT_Unit_GetInputPortByName(unit, emittingPortName); /* find in modules input port list! */
if (targetUnit==NULL) if (emittingPort==NULL) {
targetUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, targetUnitName); DBG_ERROR(NULL, "Target port \"%s\" not found for source unit \"%s\"", emittingPortName, AQHREACT_Unit_GetName(unit));
if (targetUnit==NULL) {
DBG_ERROR(NULL, "Target unit \"%s\" not found", targetUnitName);
return GWEN_ERROR_NOT_FOUND; return GWEN_ERROR_NOT_FOUND;
} }
inputSlot=AQHREACT_Unit_GetOrCreateUnusedInputSlotByName(targetUnit, targetSlotName);
if (inputSlot==NULL) { receivingPort=AQHREACT_Unit_GetInputPortByName(receivingUnit, receivingPortName);
DBG_ERROR(NULL, "Input slot \"%s\" not found for target unit \"%s\"", targetSlotName, targetUnitName); if (receivingPort==NULL) {
DBG_ERROR(NULL, "Input port \"%s\" not found for target unit \"%s\"", receivingPortName, receivingUnitName);
return GWEN_ERROR_NOT_FOUND; return GWEN_ERROR_NOT_FOUND;
} }
link=AQHREACT_Link_new(); link=AQHREACT_Link_new();
AQHREACT_Link_SetTargetUnitId(link, targetUnitName); AQHREACT_Link_SetTargetUnit(link, receivingUnit);
AQHREACT_Link_SetTargetUnit(link, targetUnit); AQHREACT_Link_SetTargetPort(link, receivingPort);
AQHREACT_Link_SetTargetInputSlotIdForUnit(link, AQHREACT_InputSlot_GetIdForUnit(inputSlot)); AQHREACT_Port_AddLink(emittingPort, link);
AQHREACT_OutputSlot_AddLink(outputSlot, link); return 0;
}
int _linkToModulesOutput(AQHOME_REACT *aqh,
AQHREACT_UNIT *unit,
const char *emittingUnitName,
const char *emittingPortName,
const char *receivingPortName)
{
AQHREACT_UNIT_MODULE *xunit;
AQHREACT_UNIT *receivingUnit;
AQHREACT_PORT *receivingPort;
AQHREACT_UNIT *emittingUnit;
AQHREACT_PORT *emittingPort;
AQHREACT_LINK *link;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
emittingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, emittingUnitName);
if (emittingUnit==NULL)
emittingUnit=AqHomeReact_FindUnitByUnitId(aqh, emittingUnitName);
if (emittingUnit==NULL) {
DBG_ERROR(NULL, "Source unit \"%s\" not found", emittingUnitName);
return GWEN_ERROR_NOT_FOUND;
}
receivingUnit=unit;
emittingPort=AQHREACT_Unit_GetOutputPortByName(emittingUnit, emittingPortName);
if (emittingPort==NULL) {
DBG_ERROR(NULL, "Output port \"%s\" not found", emittingPortName);
return GWEN_ERROR_NOT_FOUND;
}
receivingPort=AQHREACT_Unit_GetOutputPortByName(unit, receivingPortName); /* find in modules output port list! */
if (receivingPort==NULL) {
DBG_ERROR(NULL, "Target port \"%s\" not found", receivingPortName);
return GWEN_ERROR_NOT_FOUND;
}
link=AQHREACT_Link_new();
AQHREACT_Link_SetTargetUnit(link, receivingUnit);
AQHREACT_Link_SetTargetPort(link, receivingPort);
AQHREACT_Port_AddLink(emittingPort, link);
return 0;
}
int _linkBetweenUnits(AQHOME_REACT *aqh,
AQHREACT_UNIT *unit,
const char *emittingUnitName,
const char *emittingPortName,
const char *receivingUnitName,
const char *receivingPortName)
{
AQHREACT_UNIT_MODULE *xunit;
AQHREACT_UNIT *receivingUnit;
AQHREACT_PORT *receivingPort;
AQHREACT_UNIT *emittingUnit;
AQHREACT_PORT *emittingPort;
AQHREACT_LINK *link;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
emittingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, emittingUnitName);
if (emittingUnit==NULL)
emittingUnit=AqHomeReact_FindUnitByUnitId(aqh, emittingUnitName);
if (emittingUnit==NULL) {
DBG_ERROR(NULL, "Source unit \"%s\" not found", emittingUnitName);
return GWEN_ERROR_NOT_FOUND;
}
receivingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, receivingUnitName);
if (receivingUnit==NULL)
receivingUnit=AqHomeReact_FindUnitByUnitId(aqh, receivingUnitName);
if (receivingUnit==NULL) {
DBG_ERROR(NULL, "Target unit \"%s\" not found", receivingUnitName);
return GWEN_ERROR_NOT_FOUND;
}
emittingPort=AQHREACT_Unit_GetOutputPortByName(emittingUnit, emittingPortName);
if (emittingPort==NULL) {
DBG_ERROR(NULL, "Output port \"%s\" not found for source unit \"%s\"", emittingPortName, emittingUnitName);
return GWEN_ERROR_NOT_FOUND;
}
receivingPort=AQHREACT_Unit_GetOrCreateUnusedInputPortByName(receivingUnit, receivingPortName);
if (receivingPort==NULL) {
DBG_ERROR(NULL, "Input port \"%s\" not found for target unit \"%s\"", receivingPortName, receivingUnitName);
return GWEN_ERROR_NOT_FOUND;
}
link=AQHREACT_Link_new();
AQHREACT_Link_SetTargetUnit(link, receivingUnit);
AQHREACT_Link_SetTargetPort(link, receivingPort);
AQHREACT_Port_AddLink(emittingPort, link);
return 0; return 0;
} }
@@ -814,4 +795,3 @@ int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkN

View File

@@ -43,10 +43,8 @@ static MODULE_PROXY_DESCR *ModuleProxyDescr_List_FindByName(const MODULE_PROXY_D
struct AQHREACT_UNIT_MODULE { struct AQHREACT_UNIT_MODULE {
MODULE_PROXY_DESCR_LIST *paramProxyList; MODULE_PROXY_DESCR_LIST *paramProxyList;
MODULE_PROXY_DESCR_LIST *inSlotProxyList;
MODULE_PROXY_DESCR_LIST *outSlotProxyList;
AQHREACT_UNIT_LIST *unitList; AQHREACT_UNIT_LIST *unitList;
int lastPortId;
}; };

View File

@@ -28,7 +28,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
@@ -40,25 +40,24 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_
AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQHOME_REACT *aqh) AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
AQHREACT_OUTPUT_SLOT *outputSlot; AQHREACT_PORT *port;
AQHREACT_INPUT_SLOT *inputSlot;
unit=AQHREACT_Unit_new(aqh); unit=AQHREACT_Unit_new(aqh);
AQHREACT_Unit_SetName(unit, "passthrough"); AQHREACT_Unit_SetName(unit, "passthrough");
AQHREACT_Unit_SetDescription(unit, "Generic passthrough unit"); AQHREACT_Unit_SetDescription(unit, "Generic passthrough unit");
AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData);
outputSlot=AQHREACT_OutputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_OutputSlot_SetName(outputSlot, "output"); AQHREACT_Port_SetName(port, "output");
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT);
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddOutputSlot(unit, outputSlot); AQHREACT_Unit_AddOutputPort(unit, port);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "input"); AQHREACT_Port_SetName(port, "input");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
return unit; return unit;
} }
@@ -66,10 +65,15 @@ AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQHOME_REACT *aqh)
void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_PASSTHROUGH_INSLOT_INPUT) if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_PASSTHROUGH_INSLOT_INPUT) {
AQHREACT_Unit_OutputData(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT, dataObject); AQHREACT_PORT *outputPort;
outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT);
if (outputPort)
AQHREACT_Unit_OutputData(unit, outputPort, dataObject);
}
} }

View File

@@ -66,8 +66,7 @@ AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT_STABILIZE *xunit; AQHREACT_UNIT_STABILIZE *xunit;
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
AQHREACT_OUTPUT_SLOT *outputSlot; AQHREACT_PORT *port;
AQHREACT_INPUT_SLOT *inputSlot;
AQHREACT_PARAM *param; AQHREACT_PARAM *param;
unit=AQHREACT_Unit_new(aqh); unit=AQHREACT_Unit_new(aqh);
@@ -78,23 +77,23 @@ AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQHOME_REACT *aqh)
AQHREACT_Unit_SetDescription(unit, "Stabilize signal changes (only propagate changes stable for some time)"); AQHREACT_Unit_SetDescription(unit, "Stabilize signal changes (only propagate changes stable for some time)");
AQHREACT_Unit_SetProcessFn(unit, _cbProcessFn); AQHREACT_Unit_SetProcessFn(unit, _cbProcessFn);
outputSlot=AQHREACT_OutputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_OutputSlot_SetName(outputSlot, "output"); AQHREACT_Port_SetName(port, "output");
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT);
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddOutputSlot(unit, outputSlot); AQHREACT_Unit_AddOutputPort(unit, port);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "input"); AQHREACT_Port_SetName(port, "input");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "timer"); AQHREACT_Port_SetName(port, "timer");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_STABILIZE_INSLOT_TIMER); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_STABILIZE_INSLOT_TIMER);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
param=AQHREACT_Param_new(); param=AQHREACT_Param_new();
AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_STABILIZE_PARAM_HOLDTIME_HIGH); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_STABILIZE_PARAM_HOLDTIME_HIGH);
@@ -111,7 +110,7 @@ AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQHOME_REACT *aqh)
void _freeData(void *bp, void *p) void _freeData(GWEN_UNUSED void *bp, void *p)
{ {
AQHREACT_UNIT_STABILIZE *xunit; AQHREACT_UNIT_STABILIZE *xunit;
@@ -127,7 +126,7 @@ int _cbProcessFn(AQHREACT_UNIT *unit)
int rv; int rv;
rv=_checkState(unit); rv=_checkState(unit);
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit); AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit);
return rv; return rv;
} }
return 0; return 0;
@@ -142,13 +141,13 @@ int _checkState(AQHREACT_UNIT *unit)
xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_STABILIZE, unit); xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_STABILIZE, unit);
if (xunit) { if (xunit) {
AQHREACT_INPUT_SLOT *dataSlot; AQHREACT_PORT *port;
dataSlot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT); port=AQHREACT_Unit_GetInputPortByIdForUnit(unit, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT);
if (dataSlot) { if (port) {
AQHREACT_DATAOBJECT *dataObject; AQHREACT_DATAOBJECT *dataObject;
dataObject=AQHREACT_InputSlot_GetCurrentDataObject(dataSlot); dataObject=AQHREACT_Port_GetCurrentDataObject(port);
if (dataObject) { if (dataObject) {
double doubleData; double doubleData;
int newState; int newState;
@@ -216,11 +215,16 @@ void _startTimer(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newSta
void _setOutput(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState) void _setOutput(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState)
{ {
/* timeout, switch output */ AQHREACT_PORT *outputPort;
DBG_INFO(NULL, "Switch output to %s", newState?"ON":"OFF");
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT, newState?1.0:0.0); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT);
xunit->currentOutState=newState; if (outputPort) {
xunit->tsHoldUntil=0; /* timeout, switch output */
DBG_INFO(NULL, "Switch output to %s", newState?"ON":"OFF");
AQHREACT_Unit_OutputDoubleData(unit, outputPort, newState?1.0:0.0);
xunit->currentOutState=newState;
xunit->tsHoldUntil=0;
}
} }

View File

@@ -32,7 +32,11 @@ AQHREACT_UNIT *AqHomeReact_UnitTimer_new(AQHOME_REACT *aqh)
void AqHomeReact_UnitTimer_GenerateTick(AQHREACT_UNIT *unit) void AqHomeReact_UnitTimer_GenerateTick(AQHREACT_UNIT *unit)
{ {
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT, 1.0); AQHREACT_PORT *outputPort;
outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT);
if (outputPort)
AQHREACT_Unit_OutputDoubleData(unit, outputPort, 1.0);
} }

View File

@@ -32,7 +32,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
@@ -44,8 +44,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_
AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh) AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
AQHREACT_OUTPUT_SLOT *outputSlot; AQHREACT_PORT *port;
AQHREACT_INPUT_SLOT *inputSlot;
AQHREACT_PARAM *param; AQHREACT_PARAM *param;
unit=AQHREACT_Unit_new(aqh); unit=AQHREACT_Unit_new(aqh);
@@ -53,17 +52,17 @@ AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh)
AQHREACT_Unit_SetDescription(unit, "Filter values received from unit VarChanges by value path"); AQHREACT_Unit_SetDescription(unit, "Filter values received from unit VarChanges by value path");
AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData);
outputSlot=AQHREACT_OutputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_OutputSlot_SetName(outputSlot, "output"); AQHREACT_Port_SetName(port, "output");
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_VALUEFILTER_OUTSLOT_RESULT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUEFILTER_OUTSLOT_RESULT);
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddOutputSlot(unit, outputSlot); AQHREACT_Unit_AddOutputPort(unit, port);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "input"); AQHREACT_Port_SetName(port, "input");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_VALUEFILTER_INSLOT_VALUE); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUEFILTER_INSLOT_VALUE);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
param=AQHREACT_Param_new(); param=AQHREACT_Param_new();
AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUEFILTER_PARAM_VALUENAME); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUEFILTER_PARAM_VALUENAME);
@@ -75,22 +74,27 @@ AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh)
void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_VALUEFILTER_INSLOT_VALUE) { if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_VALUEFILTER_INSLOT_VALUE) {
const char *sSystemValueId; AQHREACT_PORT *outputPort;
sSystemValueId=AQHREACT_DataObject_GetSystemValueId(dataObject); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_VALUEFILTER_OUTSLOT_RESULT);
if (sSystemValueId && *sSystemValueId) { if (outputPort) {
const char *sFilter; const char *sSystemValueId;
sFilter=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUEFILTER_PARAM_VALUENAME, NULL); sSystemValueId=AQHREACT_DataObject_GetSystemValueId(dataObject);
if (sFilter && *sFilter && strcasecmp(sSystemValueId, sFilter)==0) { if (sSystemValueId && *sSystemValueId) {
DBG_INFO(NULL, "Value \"%s\" matches", sSystemValueId); const char *sFilter;
AQHREACT_Unit_OutputData(unit, AQHOMEREACT_UNIT_VALUEFILTER_OUTSLOT_RESULT, dataObject);
} sFilter=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUEFILTER_PARAM_VALUENAME, NULL);
else { if (sFilter && *sFilter && strcasecmp(sSystemValueId, sFilter)==0) {
DBG_DEBUG(NULL, "Value \"%s\" does not match", sSystemValueId); DBG_INFO(NULL, "Value \"%s\" matches", sSystemValueId);
AQHREACT_Unit_OutputData(unit, outputPort, dataObject);
}
else {
DBG_DEBUG(NULL, "Value \"%s\" does not match", sSystemValueId);
}
} }
} }
} }

View File

@@ -34,9 +34,9 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
static GWEN_MSG *_mkSetDataMsgString(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); static GWEN_MSG *_mkSetDataMsgString(const char *sValueName, const AQHREACT_DATAOBJECT *dataObject);
static GWEN_MSG *_mkSetDataMsgDouble(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); static GWEN_MSG *_mkSetDataMsgDouble(const char *sValueName, const AQHREACT_DATAOBJECT *dataObject);
@@ -48,7 +48,7 @@ static GWEN_MSG *_mkSetDataMsgDouble(AQHREACT_UNIT *unit, const char *sValueName
AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh) AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
AQHREACT_INPUT_SLOT *inputSlot; AQHREACT_PORT *port;
AQHREACT_PARAM *param; AQHREACT_PARAM *param;
unit=AQHREACT_Unit_new(aqh); unit=AQHREACT_Unit_new(aqh);
@@ -56,11 +56,11 @@ AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh)
AQHREACT_Unit_SetDescription(unit, "Set value by value path"); AQHREACT_Unit_SetDescription(unit, "Set value by value path");
AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "input"); AQHREACT_Port_SetName(port, "input");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_STRING); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_STRING);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
param=AQHREACT_Param_new(); param=AQHREACT_Param_new();
AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME);
@@ -72,9 +72,9 @@ AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh)
void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE) { if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE) {
const char *sValueName; const char *sValueName;
sValueName=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME, NULL); sValueName=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME, NULL);
@@ -87,10 +87,10 @@ void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJ
switch(AQHREACT_DataObject_GetDataType(dataObject)) { switch(AQHREACT_DataObject_GetDataType(dataObject)) {
case AQHREACT_DATAOBJECTTYPE_DOUBLE: case AQHREACT_DATAOBJECTTYPE_DOUBLE:
msgOut=_mkSetDataMsgDouble(unit, sValueName, dataObject); msgOut=_mkSetDataMsgDouble(sValueName, dataObject);
break; break;
case AQHREACT_DATAOBJECTTYPE_STRING: case AQHREACT_DATAOBJECTTYPE_STRING:
msgOut=_mkSetDataMsgString(unit, sValueName, dataObject); msgOut=_mkSetDataMsgString(sValueName, dataObject);
break; break;
default: default:
DBG_INFO(NULL, "Unhandled data type (%d)", AQHREACT_DataObject_GetDataType(dataObject)); DBG_INFO(NULL, "Unhandled data type (%d)", AQHREACT_DataObject_GetDataType(dataObject));
@@ -107,7 +107,7 @@ void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJ
} }
GWEN_MSG *_mkSetDataMsgString(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) GWEN_MSG *_mkSetDataMsgString(const char *sValueName, const AQHREACT_DATAOBJECT *dataObject)
{ {
GWEN_MSG *msgOut; GWEN_MSG *msgOut;
AQH_VALUE *v; AQH_VALUE *v;
@@ -122,7 +122,7 @@ GWEN_MSG *_mkSetDataMsgString(AQHREACT_UNIT *unit, const char *sValueName, const
GWEN_MSG *_mkSetDataMsgDouble(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) GWEN_MSG *_mkSetDataMsgDouble(const char *sValueName, const AQHREACT_DATAOBJECT *dataObject)
{ {
GWEN_MSG *msgOut; GWEN_MSG *msgOut;
AQH_VALUE *v; AQH_VALUE *v;

View File

@@ -32,17 +32,22 @@ AQHREACT_UNIT *AqHomeReact_UnitVarChanges_new(AQHOME_REACT *aqh)
void AqHomeReact_UnitVarChanges_ValueUpdated(AQHREACT_UNIT *unit, const AQH_VALUE *value, uint64_t timestamp, double data) void AqHomeReact_UnitVarChanges_ValueUpdated(AQHREACT_UNIT *unit, const AQH_VALUE *value, uint64_t timestamp, double data)
{ {
AQHREACT_DATAOBJECT *dataObject; AQHREACT_PORT *outputPort;
DBG_DEBUG(NULL, "Value \"%s\" changed", AQH_Value_GetNameForSystem(value)); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT);
dataObject=AQHREACT_DataObject_new(); if (outputPort) {
AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_DATAOBJECT *dataObject;
AQHREACT_DataObject_SetTimestamp(dataObject, timestamp);
AQHREACT_DataObject_SetDoubleData(dataObject, data); DBG_DEBUG(NULL, "Value \"%s\" changed", AQH_Value_GetNameForSystem(value));
AQHREACT_DataObject_SetSystemValueId(dataObject, AQH_Value_GetNameForSystem(value)); dataObject=AQHREACT_DataObject_new();
AQHREACT_DataObject_SetValueId(dataObject, AQH_Value_GetId(value)); AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_OutputData(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT, dataObject); AQHREACT_DataObject_SetTimestamp(dataObject, timestamp);
AQHREACT_DataObject_free(dataObject); AQHREACT_DataObject_SetDoubleData(dataObject, data);
AQHREACT_DataObject_SetSystemValueId(dataObject, AQH_Value_GetNameForSystem(value));
AQHREACT_DataObject_SetValueId(dataObject, AQH_Value_GetId(value));
AQHREACT_Unit_OutputData(unit, outputPort, dataObject);
AQHREACT_DataObject_free(dataObject);
}
} }

View File

@@ -32,7 +32,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
@@ -44,8 +44,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_
AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh) AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh)
{ {
AQHREACT_UNIT *unit; AQHREACT_UNIT *unit;
AQHREACT_OUTPUT_SLOT *outputSlot; AQHREACT_PORT *port;
AQHREACT_INPUT_SLOT *inputSlot;
AQHREACT_PARAM *param; AQHREACT_PARAM *param;
unit=AQHREACT_Unit_new(aqh); unit=AQHREACT_Unit_new(aqh);
@@ -53,17 +52,17 @@ AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh)
AQHREACT_Unit_SetDescription(unit, "Translate double value into strings for zero, positive, negative values"); AQHREACT_Unit_SetDescription(unit, "Translate double value into strings for zero, positive, negative values");
AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData);
outputSlot=AQHREACT_OutputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_OutputSlot_SetName(outputSlot, "output"); AQHREACT_Port_SetName(port, "output");
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT);
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_STRING); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_STRING);
AQHREACT_Unit_AddOutputSlot(unit, outputSlot); AQHREACT_Unit_AddOutputPort(unit, port);
inputSlot=AQHREACT_InputSlot_new(); port=AQHREACT_Port_new();
AQHREACT_InputSlot_SetName(inputSlot, "input"); AQHREACT_Port_SetName(port, "input");
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_INSLOT_VALUE); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_INSLOT_VALUE);
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
AQHREACT_Unit_AddInputSlot(unit, inputSlot); AQHREACT_Unit_AddInputPort(unit, port);
param=AQHREACT_Param_new(); param=AQHREACT_Param_new();
AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG);
@@ -85,23 +84,28 @@ AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh)
void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) void _cbInputData(AQHREACT_UNIT *unit, GWEN_UNUSED AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject)
{ {
if (unit && dataObject) { if (unit && dataObject) {
const char *result=NULL; AQHREACT_PORT *outputPort;
double data;
data=AQHREACT_DataObject_GetDoubleData(dataObject); outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT);
if (data>0.0) if (outputPort) {
result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_POS, NULL); const char *result=NULL;
else if (data<0.0) double data;
result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG, NULL);
else
result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_ZERO, NULL);
if (result && *result) { data=AQHREACT_DataObject_GetDoubleData(dataObject);
DBG_DEBUG(NULL, "Sending \"%s\" to output", result); if (data>0.0)
AQHREACT_Unit_OutputStringData(unit, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT, result); result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_POS, NULL);
else if (data<0.0)
result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG, NULL);
else
result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_ZERO, NULL);
if (result && *result) {
DBG_DEBUG(NULL, "Sending \"%s\" to output", result);
AQHREACT_Unit_OutputStringData(unit, outputPort, result);
}
} }
} }
} }