- allow scriptcontext objects to be dynamic

- enhancements in scriptcontext (error messages stored as properties)
This commit is contained in:
zolliker
2009-02-19 13:30:32 +00:00
parent 981534624f
commit 35f2b6b810
33 changed files with 753 additions and 310 deletions

View File

@ -3,6 +3,19 @@
* scriptcontext to control the actual driving operation. This can also
* serve as a drivable adapter to nodes in other objects.
*
* Some cooperation from the node is required: It has to provide
* certain properties the value of which define scripts which
* have to be called at various stages. These are:
*
* checklimits, for limits checking
* checkstatus, for evaluating progress
* halt , for halting things
*
* If no checklimits script is given, nothing is checked.
* If no checkstatus scripts is given, the value of the status property is
* returned. In that case the status value should be updated by some poll script.
* If no halt script is given, the status is set to idle. M.Z. Sept. 08
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, June-July 2008
@ -22,18 +35,19 @@ typedef struct {
/*--------------------------------------------------------------*/
static void KillDrivePriv(void *data)
{
pDrivObjPriv priv = (pDrivObjPriv)data;
if(priv == NULL){
pDrivObjPriv priv = (pDrivObjPriv) data;
if (priv == NULL) {
return;
}
if(priv->pDriv != NULL){
if (priv->pDriv != NULL) {
free(priv->pDriv);
}
if(priv->pCon != NULL){
if (priv->pCon != NULL) {
SCDeleteConnection(priv->pCon);
}
free(priv);
}
/*---------------------------------------------------------------*/
static void *SCTDRIVGetInterface(void *data, int iD)
{
@ -65,8 +79,8 @@ static int SCTDRIVHalt(void *data)
self = (pSICSOBJ) data;
pPriv = (pDrivObjPriv) self->pPrivate;
if (GetHdbProperty(self->objectNode, "halt", dummy, sizeof dummy)) {
SctQueueNode(pPriv->c, self->objectNode, HaltPRIO, "halt",
pPriv->pCon);
SctQueueNode(pPriv->c, self->objectNode, HaltPRIO, "halt",
pPriv->pCon);
} else
if (GetHdbProperty(self->objectNode, "status", dummy, sizeof dummy))
{
@ -128,11 +142,13 @@ static long SCTDRIVSetValue(void *data, SConnection * pCon, float val)
self = (pSICSOBJ) data;
pPriv = (pDrivObjPriv) self->pPrivate;
if(pPriv->pCon != NULL){
if (pPriv->pCon != NULL) {
SCDeleteConnection(pPriv->pCon);
}
pPriv->pCon = SCCopyConnection(pCon);
StopByData(pServ->pExecutor, data);
v.dataType = HIPFLOAT;
v.v.doubleValue = (double) val;
SetHdbProperty(self->objectNode, "writestatus", "start");
@ -258,24 +274,17 @@ static void KillDriveOBJ(void *data)
}
pPriv = (pDrivObjPriv) self->pPrivate;
if (pPriv->doNotKillNode && self->pDes != NULL) {
if (self->pDes->name)
free(self->pDes->name);
if (self->pDes->pKeys)
IFDeleteOptions(self->pDes->pKeys);
free(self->pDes);
} else {
DeleteDescriptor(self->pDes); /* kill descriptor including node */
if (pPriv->doNotKillNode && GetDescriptorKey(self->pDes, "creationCommand") == NULL /* it's not a dynamic object */
&& self->pDes != NULL) {
self->objectNode = NULL; /* do not call RemoveHdbNodeFromParent in KillSICSOBJ */
self->pDes->parNode = NULL; /* do not kill the node in KillSICSOBJ/DeleteDescriptor */
}
if (self->KillPrivate != NULL && self->pPrivate != NULL) {
self->KillPrivate(self->pPrivate);
}
RemoveHdbNodeFromParent(self->objectNode, pServ->dummyCon);
free(self);
KillSICSOBJ(self);
}
/*-----------------------------------------------------------------------------*/
pSICSOBJ MakeSctDriveObj(pHdb node, char *class, SctController * c)
pSICSOBJ MakeSctDriveObj(pHdb node, char *class, SctController * c,
int doNotKillNode)
{
pSICSOBJ pNew = NULL;
pDrivObjPriv pPriv = NULL;
@ -299,6 +308,7 @@ pSICSOBJ MakeSctDriveObj(pHdb node, char *class, SctController * c)
pNew->objectNode = node;
AssignSctDrive(pPriv->pDriv);
pPriv->c = c;
pPriv->doNotKillNode = doNotKillNode;
pNew->pDes->parNode = pNew->objectNode;
pNew->pDes->GetInterface = SCTDRIVGetInterface;
pNew->pPrivate = pPriv;
@ -309,7 +319,7 @@ pSICSOBJ MakeSctDriveObj(pHdb node, char *class, SctController * c)
/*--------------------------------------------------------------------------
* This actually has two syntaxes:
* makesctdrive name path-to-existing-node class SctController
* makesctdrive name type priv class SctController
* makesctdrive name float priv class SctController
*--------------------------------------------------------------------------*/
int SctMakeDriveObject(SConnection * pCon, SicsInterp * pSics,
void *object, int argc, char *argv[])
@ -319,54 +329,58 @@ int SctMakeDriveObject(SConnection * pCon, SicsInterp * pSics,
pSICSOBJ pNew = NULL;
pSICSOBJ pSct = NULL;
SctController *c = NULL;
int priv, type, status;
int priv, type, status, doNotKillNode;
hdbValue val;
char *sctName;
char *class;
if (argc < 5) {
SCWrite(pCon, "ERROR: not enough arguments to SctMakeDriveObject",
eError);
return 0;
}
if (argc < 5)
goto Usage;
node = FindHdbNode(NULL, argv[2], pCon);
if (node != NULL) {
pSct = FindCommandData(pSics, argv[4], "SctController");
if (pSct == NULL) {
SCPrintf(pCon, eError, "ERROR: SctController %s not found", argv[4]);
return 0;
if (argc == 5) {
node = FindHdbNode(NULL, argv[2], pCon);
if (node == NULL) {
SCPrintf(pCon, eError, "ERROR: node %s not found", argv[2]);
goto Usage;
}
c = (SctController *) pSct->pPrivate;
pNew = MakeSctDriveObj(node, argv[3], c);
pPriv = (pDrivObjPriv) pNew->pPrivate;
pPriv->doNotKillNode = 1; /* the node is owned by someone else */
sctName = argv[4];
class = argv[3];
doNotKillNode = 1; /* the node is owned by someone else */
} else {
/* convert datatype */
type = convertHdbType(argv[2]);
/* convert privilege */
priv = decodeSICSPriv(argv[3]);
/* convert datatype */
strtolower(argv[4]);
type = convertHdbType(argv[2]);
if (type == HIPNONE) {
node = MakeHipadabaNode(argv[1], HIPNONE, 1);
} else {
val = makeHdbValue(type, 0);
node = MakeSICSHdbPar(argv[1], priv, val);
ReleaseHdbValue(&val);
}
if (priv < 0 || type != HIPFLOAT)
goto Usage;
node = MakeSICSHdbPar(argv[1], priv, MakeHdbFloat(0.0));
if (node == NULL) {
SCWrite(pCon, "ERROR: node creation failed", eError);
return 0;
}
c = FindCommandData(pSics, argv[5], "SctController");
if (c == NULL) {
SCPrintf(pCon, eError, "ERROR: SctController %s not found", argv[4]);
return 0;
}
pNew = MakeSctDriveObj(node, argv[3], c);
sctName = argv[5];
class = argv[4];
doNotKillNode = 0; /* kill the node with the command */
}
pSct = FindCommandData(pSics, sctName, "SctController");
if (pSct == NULL) {
SCPrintf(pCon, eError, "ERROR: SctController %s not found", sctName);
goto Usage;
}
c = (SctController *) pSct->pPrivate;
pNew = MakeSctDriveObj(node, class, c, doNotKillNode);
SetHdbProperty(node, "objectName", argv[1]);
if (pNew == NULL) {
SCWrite(pCon, "ERROR: failed to create drive object", eError);
return 0;
}
if (strcasecmp(argv[0], "dynsctdriveobj") == 0) {
/* make object dynamic by defining a creation command */
SetDescriptorKey(pNew->pDes, "creationCommand", "0");
RegisterSICSOBJKillCmd(pNew, argv[1]);
}
status = AddCommand(pSics,
argv[1], InterInvokeSICSOBJ, KillDriveOBJ, pNew);
if (status != 1) {
@ -376,4 +390,18 @@ int SctMakeDriveObject(SConnection * pCon, SicsInterp * pSics,
return 0;
}
return 1;
Usage:
SCPrintf(pCon, eError,
"ERROR: should be %s <object name> <existing node> <class> <controller>",
argv[0]);
SCPrintf(pCon, eError,
"ERROR: or %s <object name> <type> <priv> <class> <controller>",
argv[0]);
return 0;
}
/*---------------------------------------------------------------*/
void SctDriveObjInit(void)
{
AddCmd("makesctdriveobj", SctMakeDriveObject);
AddCmd("dynsctdriveobj", SctMakeDriveObject);
}