- Reworked the connection object and the IO system

- Reworked the support for TRICS
- Added a second generation motor
This commit is contained in:
koennecke
2009-02-03 08:05:39 +00:00
parent f6d595665e
commit 361ee9ebea
119 changed files with 16455 additions and 3674 deletions

View File

@ -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);