- Reworked the connection object and the IO system
- Reworked the support for TRICS - Added a second generation motor
This commit is contained in:
255
callback.c
255
callback.c
@ -50,22 +50,24 @@
|
||||
#include "splitter.h"
|
||||
|
||||
#define CALLBACK 17777
|
||||
static int debug = 0;
|
||||
|
||||
/*--------------------- The interface datastructure ---------------------*/
|
||||
typedef struct __ICallBack {
|
||||
int iID;
|
||||
int iList;
|
||||
} ICallBack;
|
||||
|
||||
/*-------------- The data stored for a single callback ------------------*/
|
||||
typedef struct {
|
||||
typedef struct __CBItem{
|
||||
long iID;
|
||||
SICSCallBack pFunc;
|
||||
void *pUserData;
|
||||
KillFuncIT pKill;
|
||||
int iEvent;
|
||||
commandContext comCon;
|
||||
int killFlag;
|
||||
struct __CBItem *next;
|
||||
} CallBackItem, *pCallBackItem;
|
||||
/*--------------------- The interface datastructure ---------------------*/
|
||||
typedef struct __ICallBack {
|
||||
int iID;
|
||||
pCallBackItem head;
|
||||
} ICallBack;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int CheckPointer(pICallBack self)
|
||||
{
|
||||
@ -89,19 +91,14 @@
|
||||
}
|
||||
|
||||
pNew->iID = CALLBACK;
|
||||
pNew->iList = LLDcreate(sizeof(CallBackItem));
|
||||
if(pNew->iList < 0)
|
||||
{
|
||||
free(pNew);
|
||||
return NULL;
|
||||
}
|
||||
pNew->head = NULL;
|
||||
return pNew;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void DeleteCallBackInterface(pICallBack self)
|
||||
{
|
||||
int iRet;
|
||||
CallBackItem sItem;
|
||||
pCallBackItem pItem, pTmp;
|
||||
|
||||
if(!CheckPointer(self))
|
||||
{
|
||||
@ -109,73 +106,160 @@
|
||||
}
|
||||
|
||||
/* kill all userdata associated with callbacks */
|
||||
iRet = LLDnodePtr2First(self->iList);
|
||||
while(iRet != 0)
|
||||
pItem = self->head;
|
||||
while(pItem != NULL)
|
||||
{
|
||||
LLDnodeDataTo(self->iList,&sItem);
|
||||
if(sItem.pKill != NULL)
|
||||
{
|
||||
sItem.pKill(sItem.pUserData);
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
pTmp = pItem->next;
|
||||
if(pItem->pKill != NULL)
|
||||
{
|
||||
pItem->pKill(pItem->pUserData);
|
||||
}
|
||||
free(pItem);
|
||||
pItem = pTmp;
|
||||
}
|
||||
|
||||
LLDdelete(self->iList);
|
||||
free(self);
|
||||
free(self);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void markUserdata4Kill(pICallBack self, void *pData)
|
||||
{
|
||||
pCallBackItem pItem = NULL;
|
||||
|
||||
pItem = self->head;
|
||||
while(pItem != NULL){
|
||||
if(pData != NULL && pItem->pUserData == pData)
|
||||
{
|
||||
pItem->killFlag = 1;
|
||||
}
|
||||
pItem = pItem->next;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void cleanCallbackList(pICallBack self)
|
||||
{
|
||||
pCallBackItem toKill, current;
|
||||
|
||||
/*
|
||||
* killing at the head
|
||||
*/
|
||||
while(self->head != NULL && self->head->killFlag == 0){
|
||||
toKill = self->head;
|
||||
self->head = toKill->next;
|
||||
if(toKill->pKill != NULL){
|
||||
toKill->pKill(toKill->pUserData);
|
||||
}
|
||||
free(toKill);
|
||||
}
|
||||
|
||||
if(self->head == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* killing in the middle and the end
|
||||
*/
|
||||
current = self->head;
|
||||
while(current->next != NULL){
|
||||
if(current->next->killFlag == 1){
|
||||
toKill = current->next;
|
||||
current->next = toKill->next;
|
||||
if(toKill->pKill != NULL){
|
||||
toKill->pKill(toKill->pUserData);
|
||||
}
|
||||
free(toKill);
|
||||
} else {
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int InvokeCallBack(pICallBack self, int iEvent, void *pEventData)
|
||||
{
|
||||
CallBackItem sItem;
|
||||
pCallBackItem pItem;
|
||||
int iCurrent, iRet;
|
||||
int iResult = 1;
|
||||
int iResult = 1, iKill = 0;;
|
||||
|
||||
if(!CheckPointer(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
iCurrent = LLDnodePtr2First(self->iList);
|
||||
while(iCurrent != 0)
|
||||
pItem = self->head;
|
||||
while(pItem != NULL)
|
||||
{
|
||||
LLDnodeDataTo(self->iList,&sItem);
|
||||
if(sItem.iEvent == iEvent)
|
||||
if(pItem->iEvent == iEvent && pItem->killFlag == 0)
|
||||
{
|
||||
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData,sItem.comCon);
|
||||
if(!iRet)
|
||||
iRet = pItem->pFunc(iEvent, pEventData,pItem->pUserData);
|
||||
if(iRet < 0)
|
||||
{
|
||||
pItem->killFlag = 1;
|
||||
if(pItem->pUserData != NULL)
|
||||
{
|
||||
markUserdata4Kill(self, pItem->pUserData);
|
||||
iKill = 1;
|
||||
}
|
||||
}
|
||||
else if(iRet != 1)
|
||||
{
|
||||
iResult = 0;
|
||||
}
|
||||
}
|
||||
iCurrent = LLDnodePtr2Next(self->iList);
|
||||
pItem = pItem->next;
|
||||
}
|
||||
|
||||
/* kill run */
|
||||
if(iKill == 1){
|
||||
cleanCallbackList(self);
|
||||
}
|
||||
|
||||
return iResult;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static long lCount = 1L;
|
||||
|
||||
long RegisterCallback(pICallBack self, commandContext comCon, int iEvent,
|
||||
long RegisterCallback(pICallBack self, int iEvent,
|
||||
SICSCallBack pFunc,
|
||||
void *pUserData, KillFunc pKFunc)
|
||||
{
|
||||
CallBackItem sItem;
|
||||
pCallBackItem pItem = NULL;
|
||||
|
||||
if(!CheckPointer(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sItem.iID = lCount++;
|
||||
pItem = calloc(1,sizeof(CallBackItem));
|
||||
if(pItem == NULL){
|
||||
return -1;
|
||||
}
|
||||
pItem->iID = lCount++;
|
||||
assert(pFunc);
|
||||
sItem.pFunc = pFunc;
|
||||
sItem.iEvent = iEvent;
|
||||
sItem.pUserData = pUserData;
|
||||
sItem.pKill = pKFunc;
|
||||
sItem.comCon = comCon;
|
||||
|
||||
LLDnodeAppendFrom(self->iList,&sItem);
|
||||
return sItem.iID;
|
||||
pItem->pFunc = pFunc;
|
||||
pItem->iEvent = iEvent;
|
||||
pItem->pUserData = pUserData;
|
||||
pItem->pKill = pKFunc;
|
||||
pItem->killFlag = 0;
|
||||
pItem->next = self->head;
|
||||
self->head = pItem;
|
||||
if(debug){
|
||||
printf("Registered callback at %p\n",self);
|
||||
}
|
||||
return pItem->iID;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void markById(pICallBack self, int lID)
|
||||
{
|
||||
pCallBackItem pItem = NULL;
|
||||
|
||||
pItem = self->head;
|
||||
while(pItem != NULL)
|
||||
{
|
||||
if(pItem->iID == lID)
|
||||
{
|
||||
pItem->killFlag = 1;
|
||||
}
|
||||
pItem = pItem->next;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int RemoveCallback(pICallBack self, long lID)
|
||||
{
|
||||
@ -186,22 +270,8 @@
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
iCurrent = LLDnodePtr2First(self->iList);
|
||||
while(iCurrent != 0)
|
||||
{
|
||||
LLDnodeDataTo(self->iList,&sItem);
|
||||
if(sItem.iID == lID)
|
||||
{
|
||||
if(sItem.pKill != NULL)
|
||||
{
|
||||
sItem.pKill(sItem.pUserData);
|
||||
}
|
||||
LLDnodeDelete(self->iList);
|
||||
return 1;
|
||||
}
|
||||
iCurrent = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
markById(self,lID);
|
||||
cleanCallbackList(self);
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -214,23 +284,37 @@
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
iCurrent = LLDnodePtr2First(self->iList);
|
||||
while(iCurrent != 0)
|
||||
{
|
||||
LLDnodeDataTo(self->iList,&sItem);
|
||||
if(sItem.pUserData == pUserData)
|
||||
{
|
||||
if(sItem.pKill != NULL)
|
||||
{
|
||||
sItem.pKill(sItem.pUserData);
|
||||
}
|
||||
LLDnodeDelete(self->iList);
|
||||
}
|
||||
iCurrent = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
markUserdata4Kill(self,pUserData);
|
||||
cleanCallbackList(self);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int RemoveCallbackCon(pICallBack self, SConnection *con)
|
||||
{
|
||||
pCallBackItem pItem;
|
||||
SConnection *tst = NULL;
|
||||
|
||||
if(!CheckPointer(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pItem = self->head;
|
||||
while(pItem != NULL)
|
||||
{
|
||||
tst = (SConnection *)pItem->pUserData;
|
||||
if(VerifyConnection(tst) && tst->ident == con->ident)
|
||||
{
|
||||
if(debug){
|
||||
printf("Killing callback on connection.ident = %ld\n", con->ident);
|
||||
}
|
||||
pItem->killFlag = 1;
|
||||
}
|
||||
pItem = pItem->next;
|
||||
}
|
||||
cleanCallbackList(self);
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------
|
||||
a write function for the connection which writes to stdout
|
||||
-------------------------------------------------------------------*/
|
||||
@ -246,8 +330,7 @@ static int CallbackWrite(SConnection *pCon,char *message, int outCode)
|
||||
/*-----------------------------------------------------------------------
|
||||
the actual callback function invoking the script
|
||||
------------------------------------------------------------------------*/
|
||||
static int ScriptCallback(int iEvent, void *pEventData, void *pUserData,
|
||||
commandContext cc)
|
||||
static int ScriptCallback(int iEvent, void *pEventData, void *pUserData)
|
||||
{
|
||||
SConnection *pCon = NULL;
|
||||
Tcl_Interp *pTcl;
|
||||
@ -264,18 +347,6 @@ static int ScriptCallback(int iEvent, void *pEventData, void *pUserData,
|
||||
fprintf(stdout,"ERROR: ScriptCallback: no script to execute\n");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
SCSetWriteFunc(pCon,CallbackWrite);
|
||||
MacroPush(pCon);
|
||||
pTcl = InterpGetTcl(pServ->pSics);
|
||||
status = Tcl_Eval(pTcl,(char *)pUserData);
|
||||
if(status != TCL_OK)
|
||||
{
|
||||
fprintf(stdout,"ERROR: in CallbackScript: %s\n",(char *)pUserData);
|
||||
fprintf(stdout,"Tcl-error: %s\n",pTcl->result);
|
||||
}
|
||||
MacroPop();
|
||||
*/
|
||||
SCSetRights(pCon,usInternal);
|
||||
status = InterpExecute(pServ->pSics,pCon,(char *)pUserData);
|
||||
|
||||
@ -335,7 +406,7 @@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
Arg2Text(argc-4,&argv[4],pBuffer,131);
|
||||
lID = RegisterCallback(pCall,SCGetContext(pCon),
|
||||
lID = RegisterCallback(pCall,
|
||||
iEvent,ScriptCallback,
|
||||
strdup(pBuffer),free);
|
||||
sprintf(pBuffer,"callback = %ld", lID);
|
||||
|
Reference in New Issue
Block a user