aqhome-react: added more logical units (or, and, xor). started "module" unit.
module units now are units created from previous networks of units thus introducing nested units.
This commit is contained in:
@@ -37,7 +37,7 @@
|
|||||||
</setVar>
|
</setVar>
|
||||||
|
|
||||||
<headers dist="true" >
|
<headers dist="true" >
|
||||||
u_or.h
|
u_logical.c
|
||||||
u_passthrough.h
|
u_passthrough.h
|
||||||
u_varchanges.h
|
u_varchanges.h
|
||||||
u_valuefilter.h
|
u_valuefilter.h
|
||||||
@@ -47,11 +47,13 @@
|
|||||||
u_stabilize.h
|
u_stabilize.h
|
||||||
u_valueset.h
|
u_valueset.h
|
||||||
u_zeroposnegstring.h
|
u_zeroposnegstring.h
|
||||||
|
u_module.h
|
||||||
|
u_module_p.h
|
||||||
</headers>
|
</headers>
|
||||||
|
|
||||||
<sources>
|
<sources>
|
||||||
$(local/typefiles)
|
$(local/typefiles)
|
||||||
u_or.c
|
u_logical.c
|
||||||
u_passthrough.c
|
u_passthrough.c
|
||||||
u_varchanges.c
|
u_varchanges.c
|
||||||
u_valuefilter.c
|
u_valuefilter.c
|
||||||
@@ -61,6 +63,7 @@
|
|||||||
u_stabilize.c
|
u_stabilize.c
|
||||||
u_valueset.c
|
u_valueset.c
|
||||||
u_zeroposnegstring.c
|
u_zeroposnegstring.c
|
||||||
|
u_module.c
|
||||||
</sources>
|
</sources>
|
||||||
|
|
||||||
<useTargets>
|
<useTargets>
|
||||||
|
|||||||
256
apps/aqhome-react/units/u_logical.c
Normal file
256
apps/aqhome-react/units/u_logical.c
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 "./u_logical.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* defines
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AQHOMEREACT_UNIT_LOGICAL_INSLOT_INPUT 0
|
||||||
|
#define AQHOMEREACT_UNIT_LOGICAL_INSLOT_AUTOINPUT 100
|
||||||
|
|
||||||
|
#define AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh);
|
||||||
|
static int _cbProcessOr(AQHREACT_UNIT *unit);
|
||||||
|
static int _cbProcessAnd(AQHREACT_UNIT *unit);
|
||||||
|
static int _cbProcessXor(AQHREACT_UNIT *unit);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* implementations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQHOME_REACT *aqh)
|
||||||
|
{
|
||||||
|
AQHREACT_UNIT *unit;
|
||||||
|
|
||||||
|
unit=_unitLogical_new(aqh);
|
||||||
|
AQHREACT_Unit_SetName(unit, "or");
|
||||||
|
AQHREACT_Unit_SetDescription(unit, "Logical OR inputs");
|
||||||
|
AQHREACT_Unit_SetProcessFn(unit, _cbProcessOr);
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitAnd_new(AQHOME_REACT *aqh)
|
||||||
|
{
|
||||||
|
AQHREACT_UNIT *unit;
|
||||||
|
|
||||||
|
unit=_unitLogical_new(aqh);
|
||||||
|
AQHREACT_Unit_SetName(unit, "and");
|
||||||
|
AQHREACT_Unit_SetDescription(unit, "Logical AND inputs");
|
||||||
|
AQHREACT_Unit_SetProcessFn(unit, _cbProcessAnd);
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQHOME_REACT *aqh)
|
||||||
|
{
|
||||||
|
AQHREACT_UNIT *unit;
|
||||||
|
|
||||||
|
unit=_unitLogical_new(aqh);
|
||||||
|
AQHREACT_Unit_SetName(unit, "xor");
|
||||||
|
AQHREACT_Unit_SetDescription(unit, "Logical XOR inputs");
|
||||||
|
AQHREACT_Unit_SetProcessFn(unit, _cbProcessXor);
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh)
|
||||||
|
{
|
||||||
|
AQHREACT_UNIT *unit;
|
||||||
|
AQHREACT_OUTPUT_SLOT *outputSlot;
|
||||||
|
AQHREACT_INPUT_SLOT *inputSlot;
|
||||||
|
|
||||||
|
unit=AQHREACT_Unit_new(aqh);
|
||||||
|
AQHREACT_Unit_SetName(unit, "or");
|
||||||
|
AQHREACT_Unit_SetDescription(unit, "Logical OR inputs");
|
||||||
|
|
||||||
|
AQHREACT_Unit_SetNextInputSlotId(unit, AQHOMEREACT_UNIT_LOGICAL_INSLOT_AUTOINPUT); /* for auto-gen multi-slots */
|
||||||
|
|
||||||
|
outputSlot=AQHREACT_OutputSlot_new();
|
||||||
|
AQHREACT_OutputSlot_SetName(outputSlot, "output");
|
||||||
|
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT);
|
||||||
|
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE);
|
||||||
|
AQHREACT_Unit_AddOutputSlot(unit, outputSlot);
|
||||||
|
|
||||||
|
inputSlot=AQHREACT_InputSlot_new();
|
||||||
|
AQHREACT_InputSlot_SetName(inputSlot, "input");
|
||||||
|
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_LOGICAL_INSLOT_INPUT);
|
||||||
|
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE);
|
||||||
|
AQHREACT_InputSlot_AddFlags(inputSlot, AQHREACT_UNIT_FLAGS_MULTI);
|
||||||
|
AQHREACT_Unit_AddInputSlot(unit, inputSlot);
|
||||||
|
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _cbProcessOr(AQHREACT_UNIT *unit)
|
||||||
|
{
|
||||||
|
if (unit && AQHREACT_Unit_InputHasChanged(unit)) {
|
||||||
|
AQHREACT_INPUT_SLOT_LIST *inputSlotList;
|
||||||
|
|
||||||
|
inputSlotList=AQHREACT_Unit_GetInputSlots(unit);
|
||||||
|
if (inputSlotList) {
|
||||||
|
const AQHREACT_INPUT_SLOT *inputSlot;
|
||||||
|
int result=0;
|
||||||
|
|
||||||
|
inputSlot=AQHREACT_InputSlot_List_First(inputSlotList);
|
||||||
|
while(inputSlot) {
|
||||||
|
const char *slotName;
|
||||||
|
const AQHREACT_DATAOBJECT *dataObject;
|
||||||
|
|
||||||
|
slotName=AQHREACT_InputSlot_GetName(inputSlot);
|
||||||
|
dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot);
|
||||||
|
if (dataObject) {
|
||||||
|
if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
|
||||||
|
double d;
|
||||||
|
|
||||||
|
d=AQHREACT_DataObject_GetDoubleData(dataObject);
|
||||||
|
if (d>0.0)
|
||||||
|
result|=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:"<unnamed>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:"<unnamed>");
|
||||||
|
}
|
||||||
|
inputSlot=AQHREACT_InputSlot_List_Next(inputSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit);
|
||||||
|
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _cbProcessAnd(AQHREACT_UNIT *unit)
|
||||||
|
{
|
||||||
|
if (unit && AQHREACT_Unit_InputHasChanged(unit)) {
|
||||||
|
AQHREACT_INPUT_SLOT_LIST *inputSlotList;
|
||||||
|
|
||||||
|
inputSlotList=AQHREACT_Unit_GetInputSlots(unit);
|
||||||
|
if (inputSlotList) {
|
||||||
|
const AQHREACT_INPUT_SLOT *inputSlot;
|
||||||
|
int result=1;
|
||||||
|
|
||||||
|
inputSlot=AQHREACT_InputSlot_List_First(inputSlotList);
|
||||||
|
while(inputSlot) {
|
||||||
|
const char *slotName;
|
||||||
|
const AQHREACT_DATAOBJECT *dataObject;
|
||||||
|
|
||||||
|
slotName=AQHREACT_InputSlot_GetName(inputSlot);
|
||||||
|
dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot);
|
||||||
|
if (dataObject) {
|
||||||
|
if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
|
||||||
|
double d;
|
||||||
|
|
||||||
|
d=AQHREACT_DataObject_GetDoubleData(dataObject);
|
||||||
|
if (!(d>0.0))
|
||||||
|
result=0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:"<unnamed>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:"<unnamed>");
|
||||||
|
}
|
||||||
|
inputSlot=AQHREACT_InputSlot_List_Next(inputSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit);
|
||||||
|
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _cbProcessXor(AQHREACT_UNIT *unit)
|
||||||
|
{
|
||||||
|
if (unit && AQHREACT_Unit_InputHasChanged(unit)) {
|
||||||
|
AQHREACT_INPUT_SLOT_LIST *inputSlotList;
|
||||||
|
|
||||||
|
inputSlotList=AQHREACT_Unit_GetInputSlots(unit);
|
||||||
|
if (inputSlotList) {
|
||||||
|
const AQHREACT_INPUT_SLOT *inputSlot;
|
||||||
|
int result=0;
|
||||||
|
|
||||||
|
inputSlot=AQHREACT_InputSlot_List_First(inputSlotList);
|
||||||
|
while(inputSlot) {
|
||||||
|
const char *slotName;
|
||||||
|
const AQHREACT_DATAOBJECT *dataObject;
|
||||||
|
|
||||||
|
slotName=AQHREACT_InputSlot_GetName(inputSlot);
|
||||||
|
dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot);
|
||||||
|
if (dataObject) {
|
||||||
|
if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
|
||||||
|
double d;
|
||||||
|
|
||||||
|
d=AQHREACT_DataObject_GetDoubleData(dataObject);
|
||||||
|
if (d>0.0)
|
||||||
|
result^=1; /*only xor when >0.0, otherwise no change (x XOR 0 is still x) */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:"<unnamed>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:"<unnamed>");
|
||||||
|
}
|
||||||
|
inputSlot=AQHREACT_InputSlot_List_Next(inputSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit);
|
||||||
|
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
* should have received along with this file.
|
* should have received along with this file.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef AQHOMEREACT_U_OR_H
|
#ifndef AQHOMEREACT_U_LOGICAL_H
|
||||||
#define AQHOMEREACT_U_OR_H
|
#define AQHOMEREACT_U_LOGICAL_H
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome-react/aqhome_react.h"
|
#include "aqhome-react/aqhome_react.h"
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
|
|
||||||
AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQHOME_REACT *aqh);
|
AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQHOME_REACT *aqh);
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitAnd_new(AQHOME_REACT *aqh);
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQHOME_REACT *aqh);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
817
apps/aqhome-react/units/u_module.c
Normal file
817
apps/aqhome-react/units/u_module.c
Normal file
@@ -0,0 +1,817 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 "./u_module_p.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/xml.h>
|
||||||
|
#include <gwenhywfar/text.h>
|
||||||
|
|
||||||
|
//TODO: set params
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* defines
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
GWEN_INHERIT(AQHREACT_UNIT, AQHREACT_UNIT_MODULE);
|
||||||
|
|
||||||
|
GWEN_LIST_FUNCTIONS(MODULE_PROXY_DESCR, ModuleProxyDescr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 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,
|
||||||
|
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 _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 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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* implementations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* ModuleProxyDescr
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
MODULE_PROXY_DESCR *ModuleProxyDescr_new(const char *name, const char *targetObject, const char *targetName)
|
||||||
|
{
|
||||||
|
MODULE_PROXY_DESCR *pd;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(MODULE_PROXY_DESCR, pd);
|
||||||
|
GWEN_LIST_INIT(MODULE_PROXY_DESCR, pd);
|
||||||
|
pd->name=name?strdup(name):NULL;
|
||||||
|
pd->targetObject=targetObject?strdup(targetObject):NULL;
|
||||||
|
pd->targetName=targetName?strdup(targetName):NULL;
|
||||||
|
|
||||||
|
return pd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ModuleProxyDescr_free(MODULE_PROXY_DESCR *pd)
|
||||||
|
{
|
||||||
|
if (pd) {
|
||||||
|
GWEN_LIST_FINI(MODULE_PROXY_DESCR, pd);
|
||||||
|
free(pd->targetName);
|
||||||
|
free(pd->targetObject);
|
||||||
|
free(pd->name);
|
||||||
|
GWEN_FREE_OBJECT(pd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MODULE_PROXY_DESCR *ModuleProxyDescr_List_FindByName(const MODULE_PROXY_DESCR_LIST *pdList, const char *s)
|
||||||
|
{
|
||||||
|
if (pdList && s && *s) {
|
||||||
|
MODULE_PROXY_DESCR *pd;
|
||||||
|
|
||||||
|
pd=ModuleProxyDescr_List_First(pdList);
|
||||||
|
while(pd) {
|
||||||
|
if (pd->name && strcasecmp(pd->name, s)==0)
|
||||||
|
return pd;
|
||||||
|
pd=ModuleProxyDescr_List_Next(pd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* AqHomeReact_UnitModule
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQHOME_REACT *aqh)
|
||||||
|
{
|
||||||
|
AQHREACT_UNIT *unit;
|
||||||
|
AQHREACT_UNIT_MODULE *xunit;
|
||||||
|
|
||||||
|
unit=AQHREACT_Unit_new(aqh);
|
||||||
|
GWEN_NEW_OBJECT(AQHREACT_UNIT_MODULE, xunit);
|
||||||
|
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);
|
||||||
|
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _freeData(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode)
|
||||||
|
{
|
||||||
|
const char *t;
|
||||||
|
|
||||||
|
t=GWEN_XMLNode_GetProperty(xmlNode, "type", NULL);
|
||||||
|
if (t && *t) {
|
||||||
|
AQHREACT_UNIT *unit;
|
||||||
|
AQHREACT_UNIT_MODULE *xunit;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
unit=AqHomeReact_UnitModule_new(aqh);
|
||||||
|
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
|
||||||
|
AQHREACT_Unit_SetName(unit, t);
|
||||||
|
|
||||||
|
_readProxyFromXml(unit, 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");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _cbInputData(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_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHREACT_PARAM *_cbGetParamByName(const AQHREACT_UNIT *unit, const char *paramName)
|
||||||
|
{
|
||||||
|
AQHREACT_UNIT_MODULE *xunit;
|
||||||
|
|
||||||
|
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
|
||||||
|
if (xunit) {
|
||||||
|
const MODULE_PROXY_DESCR *pd;
|
||||||
|
|
||||||
|
pd=ModuleProxyDescr_List_FindByName(xunit->paramProxyList, paramName);
|
||||||
|
if (pd)
|
||||||
|
AQHREACT_Unit_GetParamByName(pd->targetObjectPtr, pd->targetName);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _cbProcess(AQHREACT_UNIT *unit)
|
||||||
|
{
|
||||||
|
AQHREACT_UNIT_MODULE *xunit;
|
||||||
|
int result=0;
|
||||||
|
|
||||||
|
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
|
||||||
|
if (xunit) {
|
||||||
|
AQHREACT_UNIT *subUnit;
|
||||||
|
|
||||||
|
subUnit=AQHREACT_Unit_List_First(xunit->unitList);
|
||||||
|
while(subUnit) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=AQHREACT_Unit_Process(subUnit);
|
||||||
|
if (rv<0)
|
||||||
|
result=rv;
|
||||||
|
else if (result>=0)
|
||||||
|
result=rv;
|
||||||
|
subUnit=AQHREACT_Unit_List_Next(subUnit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _readProxyFromXml(AQHREACT_UNIT *unit,
|
||||||
|
GWEN_XMLNODE *xmlNode,
|
||||||
|
MODULE_PROXY_DESCR_LIST *proxyDescrList,
|
||||||
|
const char *mainGroupName,
|
||||||
|
const char *groupName,
|
||||||
|
const char *nameProperty,
|
||||||
|
const char *targetObjectProperty,
|
||||||
|
const char *targetNameProperty)
|
||||||
|
{
|
||||||
|
GWEN_XMLNODE *nGroup;
|
||||||
|
|
||||||
|
nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, mainGroupName, NULL, NULL);
|
||||||
|
if (nGroup) {
|
||||||
|
GWEN_XMLNODE *n;
|
||||||
|
|
||||||
|
n=GWEN_XMLNode_FindFirstTag(nGroup, groupName, NULL, NULL);
|
||||||
|
while(n) {
|
||||||
|
const char *name;
|
||||||
|
const char *targetObject;
|
||||||
|
const char *targetName;
|
||||||
|
|
||||||
|
name=GWEN_XMLNode_GetProperty(n, nameProperty, NULL);
|
||||||
|
targetObject=GWEN_XMLNode_GetProperty(n, targetObjectProperty, NULL);
|
||||||
|
targetName=GWEN_XMLNode_GetProperty(n, targetNameProperty, NULL);
|
||||||
|
|
||||||
|
if (name && targetObject && targetName) {
|
||||||
|
MODULE_PROXY_DESCR *pd;
|
||||||
|
|
||||||
|
pd=ModuleProxyDescr_new(name, targetObject, targetName);
|
||||||
|
ModuleProxyDescr_List_Add(pd, proxyDescrList);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Incomplete entry in list \"%s\", ignoring", mainGroupName);
|
||||||
|
}
|
||||||
|
n=GWEN_XMLNode_FindNextTag(n, groupName, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _readInputSlotsFromXml(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, "inputSlots", NULL, NULL);
|
||||||
|
if (nGroup) {
|
||||||
|
GWEN_XMLNODE *n;
|
||||||
|
|
||||||
|
n=GWEN_XMLNode_FindFirstTag(nGroup, "inputSlot", 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_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 {
|
||||||
|
DBG_ERROR(NULL, "Incomplete input slot, ignoring");
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _finishOutSlots(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->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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _finishParams(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->paramProxyList);
|
||||||
|
while(pd) {
|
||||||
|
AQHREACT_UNIT *subUnit;
|
||||||
|
|
||||||
|
subUnit=AQHREACT_Unit_List_GetById(xunit->unitList, pd->targetObject);
|
||||||
|
if (subUnit==NULL) {
|
||||||
|
DBG_ERROR(NULL, "Unit %s: Subunit \"%s\" not found for param \"%s\"", unitName, pd->targetObject, pd->name);
|
||||||
|
return GWEN_ERROR_BAD_DATA;
|
||||||
|
}
|
||||||
|
pd->targetObjectPtr=subUnit;
|
||||||
|
|
||||||
|
pd=ModuleProxyDescr_List_Next(pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode)
|
||||||
|
{
|
||||||
|
GWEN_XMLNODE *nGroup;
|
||||||
|
AQHREACT_UNIT_MODULE *xunit;
|
||||||
|
|
||||||
|
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
|
||||||
|
|
||||||
|
nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "units", NULL, NULL);
|
||||||
|
if (nGroup) {
|
||||||
|
GWEN_XMLNODE *n;
|
||||||
|
|
||||||
|
n=GWEN_XMLNode_FindFirstTag(nGroup, "unit", NULL, NULL);
|
||||||
|
while(n) {
|
||||||
|
AQHREACT_UNIT *subUnit;
|
||||||
|
|
||||||
|
subUnit=_readOneUnitFromXml(aqh, unit, n);
|
||||||
|
if (subUnit)
|
||||||
|
AQHREACT_Unit_List_Add(subUnit, xunit->unitList);
|
||||||
|
else {
|
||||||
|
DBG_INFO(NULL, "Error reading unit from XML node");
|
||||||
|
}
|
||||||
|
|
||||||
|
n=GWEN_XMLNode_FindNextTag(n, "unit", NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *parentUnit, GWEN_XMLNODE *xmlNode)
|
||||||
|
{
|
||||||
|
const char *id;
|
||||||
|
const char *t;
|
||||||
|
|
||||||
|
id=GWEN_XMLNode_GetProperty(xmlNode, "id", NULL);
|
||||||
|
t=GWEN_XMLNode_GetProperty(xmlNode, "type", NULL);
|
||||||
|
|
||||||
|
if (id && t) {
|
||||||
|
AQHREACT_UNIT *subUnit;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
subUnit=AqHomeReact_CreateUnitByName(aqh, t);
|
||||||
|
AQHREACT_Unit_SetId(subUnit, id);
|
||||||
|
rv=_readParamsFromXml(subUnit, xmlNode, "params");
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
|
AQHREACT_Unit_free(subUnit);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return subUnit;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Incomplete unit, ignoring");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readParamsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNodeUnit, const char *mainGroupName)
|
||||||
|
{
|
||||||
|
GWEN_XMLNODE *nGroup;
|
||||||
|
|
||||||
|
nGroup=GWEN_XMLNode_FindFirstTag(xmlNodeUnit, mainGroupName, NULL, NULL);
|
||||||
|
if (nGroup) {
|
||||||
|
GWEN_XMLNODE *n;
|
||||||
|
|
||||||
|
n=GWEN_XMLNode_FindFirstTag(nGroup, "param", NULL, NULL);
|
||||||
|
while(n) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=_readParamFromXml(unit, n);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
n=GWEN_XMLNode_FindNextTag(n, "param", NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readParamFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode)
|
||||||
|
{
|
||||||
|
const char *paramName;
|
||||||
|
|
||||||
|
paramName=GWEN_XMLNode_GetProperty(paramNode, "name", NULL);
|
||||||
|
if (paramName && *paramName) {
|
||||||
|
AQHREACT_PARAM *param;
|
||||||
|
|
||||||
|
param=AQHREACT_Unit_GetParamByName(unit, paramName);
|
||||||
|
if (param) {
|
||||||
|
const char *value;
|
||||||
|
|
||||||
|
value=GWEN_XMLNode_GetCharValue(paramNode, NULL, NULL);
|
||||||
|
if (value && *value) {
|
||||||
|
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 unit", 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readLinksFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode)
|
||||||
|
{
|
||||||
|
GWEN_XMLNODE *nGroup;
|
||||||
|
|
||||||
|
nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "links", NULL, NULL);
|
||||||
|
if (nGroup) {
|
||||||
|
GWEN_XMLNODE *n;
|
||||||
|
|
||||||
|
n=GWEN_XMLNode_FindFirstTag(nGroup, "link", NULL, NULL);
|
||||||
|
while(n) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=_readLinkFromXml(aqh, unit, n);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "Error reading link in net \"%s\" (%d)", AQHREACT_Unit_GetName(unit), rv);
|
||||||
|
return GWEN_ERROR_BAD_DATA;
|
||||||
|
}
|
||||||
|
n=GWEN_XMLNode_FindNextTag(n, "link", NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit);
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
DBG_ERROR(NULL,
|
||||||
|
"Link in net \"%s\" needs properties sourceUnit, sourceSlot, targetUnit and targetSlot",
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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_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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
29
apps/aqhome-react/units/u_module.h
Normal file
29
apps/aqhome-react/units/u_module.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 AQHOMEREACT_U_MODULE_H
|
||||||
|
#define AQHOMEREACT_U_MODULE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome-react/aqhome_react.h"
|
||||||
|
#include "aqhome-react/types/unit.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/xml.h>
|
||||||
|
|
||||||
|
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQHOME_REACT *aqh);
|
||||||
|
|
||||||
|
AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
58
apps/aqhome-react/units/u_module_p.h
Normal file
58
apps/aqhome-react/units/u_module_p.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 AQHOMEREACT_U_MODULE_P_H
|
||||||
|
#define AQHOMEREACT_U_MODULE_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "./u_module.h"
|
||||||
|
|
||||||
|
#include "aqhome-react/aqhome_react.h"
|
||||||
|
#include "aqhome-react/types/unit.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct MODULE_PROXY_DESCR MODULE_PROXY_DESCR;
|
||||||
|
typedef struct AQHREACT_UNIT_MODULE AQHREACT_UNIT_MODULE;
|
||||||
|
|
||||||
|
GWEN_LIST_FUNCTION_DEFS(MODULE_PROXY_DESCR, ModuleProxyDescr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct MODULE_PROXY_DESCR {
|
||||||
|
GWEN_LIST_ELEMENT(MODULE_PROXY_DESCR);
|
||||||
|
char *name;
|
||||||
|
char *targetObject;
|
||||||
|
char *targetName;
|
||||||
|
int targetIdForModule;
|
||||||
|
AQHREACT_UNIT *targetObjectPtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static MODULE_PROXY_DESCR *ModuleProxyDescr_new(const char *name, const char *targetObject, const char *targetName);
|
||||||
|
static void ModuleProxyDescr_free(MODULE_PROXY_DESCR *pd);
|
||||||
|
static MODULE_PROXY_DESCR *ModuleProxyDescr_List_FindByName(const MODULE_PROXY_DESCR_LIST *pdList, const char *s);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct AQHREACT_UNIT_MODULE {
|
||||||
|
MODULE_PROXY_DESCR_LIST *paramProxyList;
|
||||||
|
MODULE_PROXY_DESCR_LIST *inSlotProxyList;
|
||||||
|
MODULE_PROXY_DESCR_LIST *outSlotProxyList;
|
||||||
|
|
||||||
|
AQHREACT_UNIT_LIST *unitList;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 "./u_or.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* defines
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AQHOMEREACT_UNIT_OR_INSLOT_INPUT 0
|
|
||||||
#define AQHOMEREACT_UNIT_OR_INSLOT_AUTOINPUT 100
|
|
||||||
|
|
||||||
#define AQHOMEREACT_UNIT_OR_OUTSLOT_RESULT 0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int _cbProcessFn(AQHREACT_UNIT *unit);
|
|
||||||
static int _sampleInputSlots(const AQHREACT_INPUT_SLOT_LIST *inputSlotList);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* implementations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQHOME_REACT *aqh)
|
|
||||||
{
|
|
||||||
AQHREACT_UNIT *unit;
|
|
||||||
AQHREACT_OUTPUT_SLOT *outputSlot;
|
|
||||||
AQHREACT_INPUT_SLOT *inputSlot;
|
|
||||||
|
|
||||||
unit=AQHREACT_Unit_new(aqh);
|
|
||||||
AQHREACT_Unit_SetName(unit, "or");
|
|
||||||
AQHREACT_Unit_SetDescription(unit, "Logical OR inputs");
|
|
||||||
AQHREACT_Unit_SetProcessFn(unit, _cbProcessFn);
|
|
||||||
|
|
||||||
AQHREACT_Unit_SetNextInputSlotId(unit, AQHOMEREACT_UNIT_OR_INSLOT_AUTOINPUT); /* for auto-gen multi-slots */
|
|
||||||
|
|
||||||
outputSlot=AQHREACT_OutputSlot_new();
|
|
||||||
AQHREACT_OutputSlot_SetName(outputSlot, "output");
|
|
||||||
AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_OR_OUTSLOT_RESULT);
|
|
||||||
AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE);
|
|
||||||
AQHREACT_Unit_AddOutputSlot(unit, outputSlot);
|
|
||||||
|
|
||||||
inputSlot=AQHREACT_InputSlot_new();
|
|
||||||
AQHREACT_InputSlot_SetName(inputSlot, "input");
|
|
||||||
AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_OR_INSLOT_INPUT);
|
|
||||||
AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE);
|
|
||||||
AQHREACT_InputSlot_AddFlags(inputSlot, AQHREACT_UNIT_FLAGS_MULTI);
|
|
||||||
AQHREACT_Unit_AddInputSlot(unit, inputSlot);
|
|
||||||
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _cbProcessFn(AQHREACT_UNIT *unit)
|
|
||||||
{
|
|
||||||
if (unit && AQHREACT_Unit_InputHasChanged(unit)) {
|
|
||||||
AQHREACT_INPUT_SLOT_LIST *inputSlotList;
|
|
||||||
|
|
||||||
inputSlotList=AQHREACT_Unit_GetInputSlots(unit);
|
|
||||||
if (inputSlotList) {
|
|
||||||
int result;
|
|
||||||
|
|
||||||
result=_sampleInputSlots(inputSlotList);
|
|
||||||
AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit);
|
|
||||||
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_OR_OUTSLOT_RESULT, result?1.0:0.0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _sampleInputSlots(const AQHREACT_INPUT_SLOT_LIST *inputSlotList)
|
|
||||||
{
|
|
||||||
const AQHREACT_INPUT_SLOT *inputSlot;
|
|
||||||
int result=0;
|
|
||||||
|
|
||||||
inputSlot=AQHREACT_InputSlot_List_First(inputSlotList);
|
|
||||||
while(inputSlot) {
|
|
||||||
const char *slotName;
|
|
||||||
const AQHREACT_DATAOBJECT *dataObject;
|
|
||||||
|
|
||||||
slotName=AQHREACT_InputSlot_GetName(inputSlot);
|
|
||||||
dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot);
|
|
||||||
if (dataObject) {
|
|
||||||
if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) {
|
|
||||||
double d;
|
|
||||||
|
|
||||||
d=AQHREACT_DataObject_GetDoubleData(dataObject);
|
|
||||||
if (d>0.0)
|
|
||||||
result|=1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:"<unnamed>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:"<unnamed>");
|
|
||||||
}
|
|
||||||
|
|
||||||
inputSlot=AQHREACT_InputSlot_List_Next(inputSlot);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user