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

@@ -16,7 +16,7 @@
#include <gwenhywfar/xml.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 _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject);
static void _cbOutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject);
static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
static AQHREACT_PARAM *_cbGetParamByName(const AQHREACT_UNIT *unit, const char *paramName);
static int _cbProcess(AQHREACT_UNIT *unit);
static void _readProxyFromXml(AQHREACT_UNIT *unit,
GWEN_XMLNODE *xmlNode,
static void _readProxyFromXml(GWEN_XMLNODE *xmlNode,
MODULE_PROXY_DESCR_LIST *proxyDescrList,
const char *mainGroupName,
const char *groupName,
const char *nameProperty,
const char *targetObjectProperty,
const char *targetNameProperty);
static void _readInputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode);
static void _readOutputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode);
static int _finishInSlots(AQHREACT_UNIT *unit);
static int _finishOutSlots(AQHREACT_UNIT *unit);
static int _readInputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode);
static int _readOutputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode);
static int _finishParams(AQHREACT_UNIT *unit);
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 _readParamFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode);
static int _setParamDataFromString(AQHREACT_PARAM *param, const char *value);
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 _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);
xunit->paramProxyList=ModuleProxyDescr_List_new();
xunit->inSlotProxyList=ModuleProxyDescr_List_new();
xunit->outSlotProxyList=ModuleProxyDescr_List_new();
xunit->unitList=AQHREACT_Unit_List_new();
AQHREACT_Unit_SetInputDataFn(unit, _cbInputData);
AQHREACT_Unit_SetOutputDataFn(unit, _cbOutputData);
AQHREACT_Unit_SetGetParamByNameFn(unit, _cbGetParamByName);
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;
xunit=(AQHREACT_UNIT_MODULE*) p;
AQHREACT_Unit_List_free(xunit->unitList);
ModuleProxyDescr_List_free(xunit->outSlotProxyList);
ModuleProxyDescr_List_free(xunit->inSlotProxyList);
ModuleProxyDescr_List_free(xunit->paramProxyList);
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)
{
const char *t;
const char *id;
AQHREACT_UNIT *unit;
AQHREACT_UNIT_MODULE *xunit;
int rv;
t=GWEN_XMLNode_GetProperty(xmlNode, "type", NULL);
if (t && *t) {
AQHREACT_UNIT *unit;
AQHREACT_UNIT_MODULE *xunit;
int rv;
id=GWEN_XMLNode_GetProperty(xmlNode, "id", NULL);
unit=AqHomeReact_UnitModule_new(aqh);
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
AQHREACT_Unit_SetName(unit, t);
unit=AqHomeReact_UnitModule_new(aqh);
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
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);
_readOutputSlotsFromXml(aqh, unit, xmlNode);
_readUnitsFromXml(aqh, unit, xmlNode);
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");
rv=_readInputPortsFromXml(unit, xmlNode);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHREACT_Unit_free(unit);
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;
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);
}
}
if (port)
AQHREACT_Port_SendData(port, dataObject);
}
@@ -322,8 +286,7 @@ int _cbProcess(AQHREACT_UNIT *unit)
void _readProxyFromXml(AQHREACT_UNIT *unit,
GWEN_XMLNODE *xmlNode,
void _readProxyFromXml(GWEN_XMLNODE *xmlNode,
MODULE_PROXY_DESCR_LIST *proxyDescrList,
const char *mainGroupName,
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;
GWEN_XMLNODE *nGroup;
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) {
GWEN_XMLNODE *n;
n=GWEN_XMLNode_FindFirstTag(nGroup, "inputSlot", NULL, NULL);
n=GWEN_XMLNode_FindFirstTag(nGroup, "inputPort", NULL, NULL);
while(n) {
const char *name;
const char *targetUnit;
const char *targetSlot;
int slotIdForUnit;
int dataType;
AQHREACT_PORT *port;
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_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);
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;
}
else {
DBG_ERROR(NULL, "Incomplete input slot, ignoring");
if (name==NULL) {
DBG_ERROR(NULL, "Missing name in input port");
return GWEN_ERROR_BAD_DATA;
}
n=GWEN_XMLNode_FindNextTag(n, "inputSlot", NULL, NULL);
}
}
}
void _readOutputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode)
{
AQHREACT_UNIT_MODULE *xunit;
GWEN_XMLNODE *nGroup;
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
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);
/* 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_AddInputPort(unit, port);
n=GWEN_XMLNode_FindNextTag(n, "inputPort", NULL, NULL);
} /* while */
}
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;
MODULE_PROXY_DESCR *pd;
const char *unitName;
GWEN_XMLNODE *nGroup;
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);
if (subUnit==NULL) {
DBG_ERROR(NULL, "Subunit \"%s\" not found for output slot", pd->targetObject);
return GWEN_ERROR_BAD_DATA;
nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "outputPorts", NULL, NULL);
if (nGroup) {
GWEN_XMLNODE *n;
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;
@@ -589,7 +454,7 @@ void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xml
while(n) {
AQHREACT_UNIT *subUnit;
subUnit=_readOneUnitFromXml(aqh, unit, n);
subUnit=_readOneUnitFromXml(aqh, n);
if (subUnit)
AQHREACT_Unit_List_Add(subUnit, xunit->unitList);
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 *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)
{
AQHREACT_UNIT_MODULE *xunit;
const char *sourceUnitName;
const char *sourceSlotName;
const char *targetUnitName;
const char *targetSlotName;
AQHREACT_UNIT *sourceUnit;
AQHREACT_UNIT *targetUnit;
AQHREACT_INPUT_SLOT *inputSlot;
AQHREACT_OUTPUT_SLOT *outputSlot;
AQHREACT_LINK *link;
const char *emittingUnitName;
const char *emittingPortName;
const char *receivingUnitName;
const char *receivingPortName;
int rv;
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);
sourceSlotName=GWEN_XMLNode_GetProperty(linkNode, "sourceSlot", NULL);
targetUnitName=GWEN_XMLNode_GetProperty(linkNode, "targetUnit", NULL);
targetSlotName=GWEN_XMLNode_GetProperty(linkNode, "targetSlot", NULL);
if (!(sourceUnitName && *sourceUnitName && sourceSlotName && *sourceSlotName &&
targetUnitName && *targetUnitName && targetSlotName && *targetSlotName)) {
if (!(emittingUnitName && *emittingUnitName && emittingPortName && *emittingPortName &&
receivingUnitName && *receivingUnitName && receivingPortName && *receivingPortName)) {
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));
return GWEN_ERROR_BAD_DATA;
}
sourceUnit=AQHREACT_Unit_List_GetById(xunit->unitList, 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;
if (strcasecmp(emittingUnitName, ".")==0)
rv=_linkFromThisModulesInput(aqh, unit, emittingPortName, receivingUnitName, receivingPortName);
else if (strcasecmp(receivingUnitName, ".")==0)
rv=_linkToModulesOutput(aqh, unit, emittingUnitName, emittingPortName, receivingPortName);
else
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) {
DBG_ERROR(NULL, "Output slot \"%s\" not found for source unit \"%s\"", sourceSlotName, sourceUnitName);
return 0;
}
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;
}
targetUnit=AQHREACT_Unit_List_GetById(xunit->unitList, targetUnitName);
if (targetUnit==NULL)
targetUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, targetUnitName);
if (targetUnit==NULL) {
DBG_ERROR(NULL, "Target unit \"%s\" not found", targetUnitName);
emittingPort=AQHREACT_Unit_GetInputPortByName(unit, emittingPortName); /* find in modules input port list! */
if (emittingPort==NULL) {
DBG_ERROR(NULL, "Target port \"%s\" not found for source unit \"%s\"", emittingPortName, AQHREACT_Unit_GetName(unit));
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);
receivingPort=AQHREACT_Unit_GetInputPortByName(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_SetTargetUnitId(link, targetUnitName);
AQHREACT_Link_SetTargetUnit(link, targetUnit);
AQHREACT_Link_SetTargetInputSlotIdForUnit(link, AQHREACT_InputSlot_GetIdForUnit(inputSlot));
AQHREACT_OutputSlot_AddLink(outputSlot, link);
AQHREACT_Link_SetTargetUnit(link, receivingUnit);
AQHREACT_Link_SetTargetPort(link, receivingPort);
AQHREACT_Port_AddLink(emittingPort, 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;
}
@@ -814,4 +795,3 @@ int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkN