diff options
Diffstat (limited to 'src/ivycpy.docfile')
-rw-r--r-- | src/ivycpy.docfile | 1594 |
1 files changed, 1594 insertions, 0 deletions
diff --git a/src/ivycpy.docfile b/src/ivycpy.docfile new file mode 100644 index 0000000..eb56154 --- /dev/null +++ b/src/ivycpy.docfile @@ -0,0 +1,1594 @@ +/** + * SWIG Module for making a python wrapper to C ivy library + * -#- c-mode -#- + * + * warning avoid any phrase starting with "pyIvy + * or ending with MsgAsS" + * or ending with ErrorAsS" + * cause these patterns are patched afterwards in order to neat + * Ivycpy library naming + * this wrapper works only with ivy-c version 3.8.1.1 and higher version + */ + +%module ivycpy + +/* on place ici entre %{%} les inclusions, pre-declarations importantes, + fonctions locales qui vont etre associées au wrapper ce code sera conservé + intact par SWIG */ + +%{ +#include <stdio.h> +#include <string.h> +#include <ivy.h> +#include <timer.h> +#include <ivychannel.h> +#include <signal.h> +#include <tcl.h> +#include <sys/types.h> +#include "list.h" + +%} + + +/********************************************************************** + ****************************** PART 1 ******************************** + ******************* définition des types de données ****************** + **********************************************************************/ + +/* part 1 on place ici les types de donnees faisant partie des elements + à wrapper */ + +/** + * définition de la structure pointeur sur IvyClient + * cette structure permet de chainer des clients et de parcourir cette chaine + * par acces au client suivant + */ +typedef struct +{ + /** + * next: pointeur vers le client suivant + */ + IvyClientPtr next; + + /** + * client: reference au client ivy-c + */ + Client client; + + /** + * msg_send: pointeur vers le message envoye + */ + MsgSndPtr msg_send; + + /** + * app_name: nom de l'application + */ + char *app_name; + + /** + * app_port: port tcp pour connexion a l'application + */ + unsigned short app_port; + +}*IvyClientPtr; + + + +/** + * définition des types d'évenement pouvant être envoyer par les applications + * IvyApplicationConnected : evenement de connexion d'une application + * IvyApplicationDisconnected : evenement de deconnexion d'une application + */ +typedef enum {IvyApplicationConnected, IvyApplicationDisconnected} IvyApplicationEvent; + + +/** + * définition des évenement lors des abonnments et désabonnement de message + * IvyAddBind : evenement d'ajout d'un binding par une application + * ivyRemoveBind : evenement de suppression d'un binding par une application + */ +typedef enum {IvyAddBind, IvyRemoveBind} IvyBindEvent; + + +/** + * définition de la structure pointeur sur timer + */ +typedef struct _timer *TimerId; + + /** + * structure définissant les canaux de communication + * cette structure permet de créer une liste chainee de canaux + */ + struct _channel + { + /** + * pointeur vers le canal suivant + */ + Channel next; + + /** + * int representant le numero de socket + */ + HANDLE fd; + + /** + * donnee recuperer sur la socket + */ + void *data; + + /** + * flag de suppression du canal + */ + int tobedeleted; + + /** + * callback declenche par la gestion de boucle sur evenement exception sur le canal + */ + ChannelHandleDelete handle_delete; + + /** + * callback declenche par la gestion de boucle sur donnees pretes sur le canal + */ + ChannelHandleRead handle_read; + }; + + + + /** + * channels_list: pointeur vers le premier element de la liste chaine des canaux + */ + static Channel channels_list = NULL; + + /** + * channel_initialized : flag d'initialisation d'un canal, vaut 1 si canal initialise, 0 sinon + */ + static int channel_initialized = 0; + + /** + * open_fds : file descriptor for socket + */ + static fd_set open_fds; + + /** + * MainLoop : flag pour la mainloop ivy, si MainLoop vaut 1, les evenements sont ecoutes + * sinon, il ne le sont pas + */ + static int MainLoop = 1; + + /** + * definition du type MsgRcvArray + * MsgRcvArray : tableau contenant les structures de donnees + * creer lors d'un abonnement a un message + */ + typedef MsgRcvPtr *MsgRcvArray ; + + /** + * definition du type TimerIdArray + * TimerIdArray : tableau contenant les identifiants des timers + */ + typedef TimerId *TimerIdArray ; + + /** + * definition du type Message + * Message : chaine de caracteres utilise pour les messages + */ + typedef char *Message; + + /** + * definition du type MessagesArray + * MessagesArray: tableau de Message + */ + typedef Message *MessagesArray ; + + + /** + * donnees et fonctions de gestion des infos MsgRcvPtr retournés par IvyBindMsg + * msgrcvarray : tableau utilise pour rangee les structures de donnees pour les abonnements + */ + static MsgRcvArray msgrcvarray ; + + /** + * bindingid_number : entier informant du nombre d'abonnement enregistre + */ + static int bindingid_number = 0 ; + + /** + * donnees et fonctions de gestion des timer retournés par TimerRepeatAfter + * timerarray : tableau contenant les identifiant des timers + */ + static TimerIdArray timerarray ; + + /** + * timerid_number : entier represenetant le nombre de timers + */ + static int timerid_number = 0 ; + + + /********************************************************** + **************** définition des fonctions **************** + **************** permettant la gestion des *************** + **************** bases de messages et timers ************* + **********************************************************/ + + /** + * fonction addRcvMsg() + * cette fonction permet d'ajouter un abonnement dans le tableau + * @param rcvptr, pointeur vers le message + * @return int représentant l'identifiant du message dans la base + **/ + static int addRcvMsg(MsgRcvPtr rcvptr) + { + int i, bindingid ; + /* loop on the msgarray to find free slots */ + for(i=0;i<bindingid_number;++i) + { + if (msgrcvarray[i] == NULL) + { /* a slot is free + saving message in the database */ + msgrcvarray[i] = rcvptr ; + return(i); + } + } + /* no free slot was found */ + /* adding one entry in the database */ + bindingid = bindingid_number ; + bindingid_number ++ ; + + /* resizing the table */ + msgrcvarray = (MsgRcvPtr *) realloc((void *) msgrcvarray , + sizeof(MsgRcvArray)*(bindingid_number)); + /* testing realloc */ + if (!msgrcvarray) + { + fprintf(stderr,"realloc msgrcvarray return NULL\n"); + exit(1); + }; + msgrcvarray[bindingid] = rcvptr ; + return bindingid ; + } + + + /** + * fonction getRcvMsg() + * cette fonction permet de recuperer un abonnement en utilisant son identifiant + * @param binding_id : identifiant de l'abonnement dans la base + * @return : un pointeur vers l'abonnement + */ + static MsgRcvPtr getRcvMsg(int binding_id) + { + if (binding_id >=0 && binding_id < bindingid_number) + return msgrcvarray[binding_id] ; + else + return NULL ; + } + + + /** + * fonction delRcvMsg() + * cette fonction permet de supprimer un abonnement de la base + * @param binding_id : identifiant de l'abonnement dans la base + */ + static void delRcvMsg(int binding_id) + { + if (binding_id >=0 && binding_id < bindingid_number) + msgrcvarray[binding_id] = NULL ; + } + + + /** + * fonction printmsgrcvarray() + * cette fonction affiche sur la sortie standard le contenu du tableau de message + */ + static void printmsgrcvarray() + { + int i; + for(i=0;i<bindingid_number;++i) + { + printf("rcvarray %i : %x \n", i, (int) msgrcvarray[i]); + } + } + + + /** + * fonction addIvyTimer() + * cette fonction permet d'ajouter un timer Ivy au tableau de timers + * @param timer : pointeur vers le timer a ajouter + * @return : l'identifiant du timer dasn la base + */ + static int addIvyTimer(TimerId timer) + { + int i, timerid ; + for(i=0;i<timerid_number;++i) + { + if (timerarray[i] == NULL) + { /* a slot is free */ + timerarray[i] = timer ; + return(i); + } + } + /* no free slot was found */ + timerid = timerid_number ; + timerid_number ++ ; + + timerarray = (TimerId *) realloc((void *) timerarray, + sizeof(TimerIdArray)*(timerid_number)); + /* testing realloc */ + if (!timerarray) + { + fprintf(stderr,"realloc timerarray return NULL\n"); + exit(1); + }; + timerarray[timerid] = timer ; + return timerid ; + } + + + + /** + * fonction getIvyTimer() + * cette fonction permet de recuperer un timer dans la base par son identifiant + * @param timerid : identifiant du timer + * @return : pointeur vers un timer + */ + static TimerId getIvyTimer(int timerid) + { + if (timerid >=0 && timerid < timerid_number) + return timerarray[timerid] ; + else + return NULL ; + } + + + /** + * fonction delIvyTimer() + * cette fonction permet de supprimer un timer de la base par son identifiant + * @param timerid : identifiant du timer + */ + static void delIvyTimer(int timerid) + { + if (timerid >=0 && timerid < timerid_number) + timerarray[timerid] = NULL ; + } + + + /** + * fonction printtimerarray() + * cette fonction permet d'afficher sur la sortie standard le contenu de la base de timers + */ + static void printtimerarray() + { + int i; + for(i=0;i<timerid_number;++i) + { + printf("timerarray %i : %x \n", i, (int) timerarray[i]); + } + } + + + /************************************************************* + * This functions matche the prototype of a normal C callback* + * function for our widget. However, the clientdata pointer * + * actually refers to a Python callable object. * + *************************************************************/ + + /** + * fonction pyIvyApplicationCallback() + * cette fonction est le callback appele lors d'une connexion ou d'une deconnexion d'application au bus Ivy + * @param app : pointeur vers le client se connectant/deconnectant + * @param user_data : pointeur vers la fonction a appelee lors d'une connexion / deconnexion d'application + * @param event : evenement indiquant s'il s'agit d'une connexion ou d'une deconnexion + */ + static void pyIvyApplicationCallback(IvyClientPtr app, + void *user_data, + IvyApplicationEvent event) + { + PyObject *func, *arglist; + PyObject *result, *eventobj; + PyObject *resultobj; + static void *descr = 0; + +#ifdef __DEBUG__ + printf("-pyIvyApplicationCallback\n"); +#endif + func = (PyObject *) user_data; + /* cette verif est inutile ; elle a deja ete faite lors de + l'enregistrement du callback */ + if (!PyCallable_Check(func)) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return ; + }; + /* user_data->func ; */ + /* la signature python doit etre proc(n) elle ne retourne rien */ + descr = SWIG_TypeQuery("IvyClientPtr"); + resultobj = SWIG_NewPointerObj((void *) app, descr, 0); + eventobj = Py_BuildValue("i", (int) event); + arglist = PyTuple_New(2); + PyTuple_SetItem(arglist,0,resultobj); + PyTuple_SetItem(arglist,1,eventobj); + + result = PyEval_CallObject(func,arglist); + if (!result) + { + PyErr_Print(); + }; + Py_DECREF(arglist); + } + + + /** + * fonction pyIvyBindCallback() + * cette fonction est le callback appele sur chaque abonnement ou desabonnement à un message + * @param app : pointeur sur le client s'abonnant ou se desabonnant + * @param user_data : pointeur vers la fonction appelee lors de cet abonnement/desabonnement + * @param id : identifiant de l'abonnement + * @param regexp : expression reguliere auquel le client s'abonne ou se desabonne + * @param event : evenement d'abonnement/desabonnement + */ + static void pyIvyBindCallback(IvyClientPtr app, + void *user_data, + int id, + char* regexp, + IvyBindEvent event) + { + PyObject *func, *arglist; + PyObject *result, *eventobj, *idobj, *regexpobj; + PyObject *resultobj; + static void *descr = 0; +#ifdef __DEBUG__ + printf("-pyIvyBindCallback\n"); +#endif + func = (PyObject *) user_data; + /* cette verif est inutile ; elle a deja ete faite lors de + l'enregistrement du callback */ + if (!PyCallable_Check(func)) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return ; + }; + /* user_data->func ; */ + /* la signature python doit etre proc(n) elle ne retourne rien */ + descr = SWIG_TypeQuery("IvyClientPtr"); + resultobj = SWIG_NewPointerObj((void *) app, descr, 0); + + idobj = Py_BuildValue("i", (int) id); + regexpobj=PyString_FromString(regexp); + eventobj = Py_BuildValue("i", (int) event); + arglist = PyTuple_New(4); + + PyTuple_SetItem(arglist,0,resultobj); + PyTuple_SetItem(arglist,1,idobj); + PyTuple_SetItem(arglist,2,regexpobj); + PyTuple_SetItem(arglist,3,eventobj); + + result = PyEval_CallObject(func,arglist); + if (!result) + { + PyErr_Print(); + }; + Py_DECREF(arglist); + } + + + /** + * fonction pyIvyDieCallback() + * cette fonction est le callback appele lors d'un message die + * @param app : le client envoyant le message + * @param user_data : fonction appelee lors d'une reception de message + * @param id : identifiant non utilise + */ + static void pyIvyDieCallback(IvyClientPtr app, + void *user_data, + int id) + { + PyObject *func, *arglist; + PyObject *result, *idobj; + PyObject *resultobj; + static void *descr = 0; +#ifdef __DEBUG__ + printf("-pyIvyDieCallback\n"); +#endif + func = (PyObject *) user_data; + /* cette verif est inutile ; elle a deja ete faite lors de + l'enregistrement du callback */ + if (!PyCallable_Check(func)) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return ; + }; + /* user_data->func ; */ + /* la signature python doit etre proc(n) elle ne retourne rien */ + /* + arglist = Py_BuildValue("(i)", id); + result = PyEval_CallObject(func,arglist); + Py_DECREF(arglist); + */ + descr = SWIG_TypeQuery("IvyClientPtr"); + resultobj = SWIG_NewPointerObj((void *) app, descr, 0); + idobj = Py_BuildValue("i", (int) id); + + arglist = PyTuple_New(2); + PyTuple_SetItem(arglist,0,resultobj); + PyTuple_SetItem(arglist,1,idobj); + + result = PyEval_CallObject(func,arglist); + if (!result) + { + PyErr_Print(); + }; + Py_DECREF(arglist); + } + + + /** + * fonction pyMsgCallback() + * cette fonction est le callback appele lors d'une reception de message + * @param app : le client appelant + * @param user_data : la fonction a appele lors de la reception de message + * @param argc : nombre de parametres envoyes dans le message + * @param argv : tableau de chaine de caractere contenant les elements du message + */ + static void pyMsgCallback( IvyClientPtr app, void *user_data, int argc, char **argv ) + { + PyObject *pyargv ; + int i ; + PyObject *func; + PyObject *result; + PyObject *resultobj; + PyObject *chaine; + static void *descr = 0; +#ifdef __DEBUG__ + printf("-pyMsgCallback\n"); +#endif + + func = (PyObject *) user_data; + + /* cette verif est inutile ; elle a deja ete faite lors de + l'enregistrement du callback */ + if (!PyCallable_Check(func)) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return ; + }; + /* user_data->func ; */ + /* la signature python doit etre proc(*arg)) + elle ne retourne rien */ + descr = SWIG_TypeQuery("IvyClientPtr"); + resultobj = SWIG_NewPointerObj((void *) app, descr, 0); + pyargv = PyTuple_New(argc+1); + PyTuple_SetItem(pyargv,0,resultobj); + for (i = 1; i < argc+1; i++) + { + if (argv[i-1]) + { + chaine=PyString_FromString(argv[i-1]); + } + else + { + chaine=PyString_FromString(""); + } + + if(PyString_Check(chaine)) + { + PyTuple_SetItem(pyargv,i,chaine); + } + else + { + printf("-pytkMsgCallback Error %i\n",i); + } + } + + /* this codes is useless; the tuple (pyargv) is directly passed + to the Python call back + */ + result = PyEval_CallObject(func, pyargv) ; + if (!result) + { + PyErr_Print(); + }; + Py_DECREF(pyargv); + /*Py_DECREF(resultobj);*/ + } + + + /** + * fonction pyMsgDirectCallback() + * cette fonction est le callback appele lors d'une reception d'un message direct + * @param app : le clieant appelant + * @param user_data : la fonction a appelee sur cette reception + * @param id : identifiant utilise pour message en plusieurs partie, sinon inutile + * @param msg : chaine de caractere representant le message + */ + static void pyMsgDirectCallback(IvyClientPtr app, + void *user_data, + int id, + char *msg ) + { + PyObject *func, *arglist; + PyObject *result, *idobj; + // modification olivier : ajout d'un parametre + //PyObject *result; + PyObject *resultobj; + static void *descr = 0; + +#ifdef __DEBUG__ + printf("-pyMsgDirectCallback\n"); +#endif + func = (PyObject *) user_data; + + /* cette verif est inutile ; elle a deja ete faite lors de + l'enregistrement du callback */ + if (!PyCallable_Check(func)) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return ; + }; + /* user_data->func ; */ + /* la signature python doit etre proc(arg)) + elle ne retourne rien */ + descr = SWIG_TypeQuery("IvyClientPtr"); + resultobj= SWIG_NewPointerObj((void *) app, descr, 0); + idobj = Py_BuildValue("i", (int) id); + // modification olivier : ajout d'un element au tuple + arglist = PyTuple_New(3); + //arglist = PyTuple_New(2); + PyTuple_SetItem(arglist,0,resultobj); + PyTuple_SetItem(arglist,1,idobj); + // modification olivier : ajout de l'identifiant dans le tuple + //PyTuple_SetItem(arglist,1,PyString_FromString(msg)); + PyTuple_SetItem(arglist,2,PyString_FromString(msg)); + + result = PyEval_CallObject(func,arglist); + if (!result) + { + PyErr_Print(); + }; + Py_DECREF(arglist); + Py_DECREF(resultobj); + } + + + + /** + * fonction pyTimerCallback() + * cette fonction est la callback appelee lors d'un repeat after sur un timer + * @param id : identifiant du timer sur lequel l'operation a eu lieu + * @param user_data : pointeur sur la fonction à appeler sur l'application + * @param delta : entier representant le resultat du timer + */ + static void pyTimerCallback(TimerId id, + void *user_data, + unsigned long delta) + { + PyObject *func ; + PyObject *result; + +#ifdef __DEBUG__ + printf("-pyTimerCallback\n"); +#endif + func = (PyObject *) user_data; + + /* cette verif est inutile ; elle a deja ete faite lors de + l'enregistrement du callback */ + if (!PyCallable_Check(func)) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return ; + }; + /* la signature de la fonction python a appellé doit etre + proc() */ + result = PyEval_CallObject(func,NULL); + } + + + /************************************************************ + ************* End functions matching C callbacks *********** + ************************************************************/ + + + /************************************************************* + **************** FUNCTIONS FOR IVY CHANNELS ***************** + *************************************************************/ + + /** + * fonction pyIvyChannelHandleRead() + * cette fonction est en charge de la gestion de la lecture sur la socket + * @param current : le file descriptor courant + */ + static void pyIvyChannelHandleRead (fd_set *current) + { + Channel channel, next; + + IVY_LIST_EACH_SAFE (channels_list, channel, next) + { + if (FD_ISSET (channel->fd, current)) + { + (*channel->handle_read)(channel,channel->fd,channel->data); + } + } + } + + /** + * fonction pyIvyChannelHandleExcpt() + * fonction gérant les exceptions lors de la lecture/ecriture sur la socket + * @param current : le file descriptor courant + */ + static void pyIvyChannelHandleExcpt (fd_set *current) + { + Channel channel,next; + IVY_LIST_EACH_SAFE (channels_list, channel, next) + { + if (FD_ISSET (channel->fd, current)) + { + if (channel->handle_delete) + (*channel->handle_delete)(channel->data); + } + } + } + + + /** + * fonction pyIvyChannelDelete() + * fonction permettant la suppression d'un canal de communication + * @param channel : le canal à supprimer + */ + static void pyIvyChannelDelete (Channel channel) + { + if (channel->handle_delete) + (*channel->handle_delete) (channel->data); + + FD_CLR (channel->fd, &open_fds); + IVY_LIST_REMOVE (channels_list, channel); + } + + + /** + * fonction pyChannelDefferedDelete() + * fonction permettant la suppression de l'ensemble des canaux + * marquer à supprimer + */ + static void pyChannelDefferedDelete () + { + Channel channel, next; + IVY_LIST_EACH_SAFE (channels_list, channel,next) + { + if (channel->tobedeleted ) + { + pyIvyChannelDelete (channel); + } + } + } + + + /** + * fonction IvyChannelInit() + * cette fonction est appele pour la création d'un canal de communication + * c'est la librairie ivy-c qui appelle cette fonction + * function called by the library ivy-c + * defined as extern in ivychannel.h + * initialisation d'un canal + */ + void IvyChannelInit(void) + { + +#ifdef __DEBUG__ + printf("-IvyChannelInit\n"); +#endif +#ifdef WIN32 + int error; +#else + /* pour eviter les plantages quand les autres applis font core-dump */ + signal (SIGPIPE, SIG_IGN); +#endif + if (channel_initialized) return; + + /* loopmode test removed */ + FD_ZERO (&open_fds); + +#ifdef WIN32 + error = WSAStartup (0x0101, &WsaData); + if (error == SOCKET_ERROR) + { + printf ("WSAStartup failed.\n"); + } +#endif + channel_initialized = 1; + } + + + + /** + * fonction IvyChannelStop() + * fonction appelee par la librairie ivy-c + * arret de la mainloop ivy + */ + void IvyChannelStop() + { + MainLoop = 0; + } + + + /** + * fonction IvyChannelAdd() + * fonction ajoutant un nouveau canal de communication à la liste + * @param fd : identifiant du file descriptor + * @param data : buffer de donnee à remplir + * @param handle_delete : fonction à appeler lors d'une suppression du canal + * @param handle_read : fonction à appeler lors de la lecture sur le canal + * @return une structure de donnee de type channel + */ + /* ajout d'un canal */ + Channel IvyChannelAdd(HANDLE fd, + void *data, + ChannelHandleDelete handle_delete, + ChannelHandleRead handle_read) + { + Channel channel; + /* loopmode test removed */ + IVY_LIST_ADD (channels_list, channel); + if (!channel) + { + fprintf(stderr,"NOK Memory Alloc Error\n"); + exit(0); + } + channel->fd = fd; + channel->tobedeleted = 0; + channel->handle_delete = handle_delete; + channel->handle_read = handle_read; + channel->data = data; + + FD_SET (channel->fd, &open_fds); + + return channel; + } + + + + /** + * fonction IvyChannelRemove() + * fonction appelee par la librairie ivy-c + * elle permet de supprimer un canal en plçant le flag tobedeleted à 1 + * @param channel : pointeur vers la structure de donnes du canal + */ + /* suppression d'un canal */ + void IvyChannelRemove(Channel channel) + { +#ifdef __DEBUG__ + printf("-IvyChannelRemove\n"); +#endif + /* loopmode test removed */ + channel->tobedeleted = 1; + } + + + + /************************************************************* + ******************** END IVY CHANNELS *********************** + *************************************************************/ + + + /**************************************************** + ************* FACADE FOR IVY METHODS *************** + ****************************************************/ + + /** + * fonction pyIvyInit() + + * cette fonction permet d'initialiser une connexion au bus Ivy + * cette fonction est une facade pour la fonction IvyInit() de la + * librairie ivy-c + * @param AppName : chaine de caractere representant + * le nom de l'application a connecter + * @param ready : chaine de caractere representant le message + * envoyer lors d'une connexion + * @param loopmode : entier permettant de fonctionner sur le thread + * de la boucle tk ou sur un thread à part ce parametre doit être + * mis à zero, car le mode fonctionnant avec le thread tk n'existe + * plus + * @param pyFuncOnCx : pointeur sur la fonction appelee lors d'une + * connexion d'une application au bus ivy + * @param PyFuncOnDie : pointeur sur la fonction a appele lors d'un + * DIE message + */ + + static void pyIvyInit(const char *AppName, /* nom de l'application */ + const char *ready, /* ready Message peut etre NULL */ + int loopmode, /* 1 = mode Tk (obsolete) , 0 = mode Ivyloop */ + PyObject *PyFuncOnCx, /* callback appele sur connection deconnection d'une appli */ + PyObject *PyFuncOnDie) /* last change callback before die */ + { + +#ifdef __DEBUG__ + printf("-pyIvyInit\n"); +#endif + IvyInit(AppName,ready, + pyIvyApplicationCallback, (void *) PyFuncOnCx, + pyIvyDieCallback, (void *) PyFuncOnDie); + + Py_INCREF(PyFuncOnCx); + Py_INCREF(PyFuncOnDie); + } + + + + /** + * fonction pyIvySetBindCallBack() + * cette fonction permet de donner la callback a appele lors d'un bind + * cette fonction est la facade de la fonction IvySetBindCallback() + * @param PyFunc: pointeur sur la callback appelee lors d'un bind + */ + static void pyIvySetBindCallback(PyObject *PyFunc) + { + IvySetBindCallback(pyIvyBindCallback, (void *) PyFunc); + Py_INCREF(PyFunc); + } + + + /** + * fonction pyIvyDelBindCallback() + * cette fonction permet de reseter la callback appelee lors d'un bind + * cette fonction est une facade de la fonction IvySetBindCallback() + * @TODO cette fonction ne marche peut être pas, il faudrait la tester et la corriger le cas échéant + */ + static void pyIvyDelBindCallback() + { + IvySetBindCallback(NULL, NULL); + } + + + /** + * fonction pyIvyStart() + * cette fonction permet de demarrer une application ivy + * cette fonction est une facade de la fonction IvyStart() + * @param appname : chaine de caractere representant le nom de l'application a demarrer + */ + static void pyIvyStart (const char* appname) + { + IvyStart(appname); + MainLoop = 1; + } + + /** + * fonction pyIvystop() + * cette fonction permet d'arreter une application + * cette fonction est une facade pour la fonction IvyStop() de la librairie ivt-c + */ + static void pyIvyStop (void) + { + IvyStop(); + } + + + /** + * fonction pyIvyGetApplicationName() + * cette fonction permet de recuperer le nom d'une application cliente + * cette fonction est uen facade de la fonction IvyGetApplicationName() de la librairie ivy-c + * @param app : pointeur vers le client dont on veur recuperer le nom + * @return une chane de caracteres representant le nom de l'application + */ + static char* pyIvyGetApplicationName(IvyClientPtr app) + { + return IvyGetApplicationName(app); + } + + + /** + * fonction pyIvyGetApplicationHost() + * cette fonction permet de recuperer la machine hote du client ivy passe en parametre + * cette fonction est une facade de la fonction IvyGetApplicationHost() de la librairie ivy-c + * @param app : pointeur vers le client ivy + * @return une chaine de caracteres representant le nom de la machine hote du client + */ + static char* pyIvyGetApplicationHost(IvyClientPtr app) + { + return IvyGetApplicationHost(app); + } + + + /** + * fonction pyIvyGetApplication() + * cette fonction permet de recuperer un une reference a un client ivy à partir de son nom + * cette fonction est uen facade de la fonction IvyGetApplication() de la librairie ivy-c + * @param name : chaine de caracteres represenatnt le nom de l'application + * @return une reference au client ivy + */ + static IvyClientPtr pyIvyGetApplication(char *name) + { + return IvyGetApplication(name); + } + + + /** + * fonction pyIvyGetApplicationList() + * cette fonction permet de recuperer la liste des clients connectes au bus ivy + * cette fonction est uen facade de la fonction IvygetApplicationList() de la librairie ivy-c + * @param sep : chaine de caractere representant le separateur a mettre entre les noms d'application + * @return chaine de caracteres representant la liste des clients connectes separes par le separateur + */ + static char* pyIvyGetApplicationList(const char* sep) + { + return IvyGetApplicationList(sep); + } + + + /** + * fonction pyIvyGetApplicationMessages() + * cette fonction permet de recuperer la liste des abonnements d'un client + * cette fonction est une facade de la fonction IvyGetApplicationMessages() de la libraire ivy-c + * @param app : refreence au client dnt on desire recuperer les abonnements + * @return un tableau de chaines de caracteres represenatnt les differents abonnements + */ + static char** pyIvyGetApplicationMessages(IvyClientPtr app) + { + return IvyGetApplicationMessages(app); + } + + + /** + * fonction pyIvyBindMsg() + * cette fonction permet de s'abonner à un type de message afin de declencher une action sur la reception + * cette fonction est une facade de IvyBindMsg() evitat le problème de vararg + * @param PyFunc : pointeur vers la callback à declencher sur recption d'un message + * @param msg : chaine de caracteres representant le message auquel on s'abonne (ce message est generalement une expression reguliere) + * @return une entier representant le numero de l'abonnement + */ + static int pyIvyBindMsg (PyObject *PyFunc, + const char *msg) + { + MsgRcvPtr result ; + int binding_id = -1 ; + + result = IvyBindMsg(pyMsgCallback, (void *) PyFunc , msg); + + /* on conserve une trace de result sous la forme d'une table + indexé i -> (result) ; cet indice sera incrémenté et retourné + comme valeur de retour */ +#ifdef __DEBUG__ + printf("-IvyBindMsg retourne %x \n", (int) result); +#endif + binding_id = addRcvMsg(result) ; +#ifdef __DEBUG__ + printmsgrcvarray(); +#endif + Py_INCREF(PyFunc); + Py_INCREF(Py_None) ; + return binding_id ; + } + + + /** + * fonction pyIvyUnbindMsg() + * cette fonction permet de se desabonner a un type de message + * cette fonction est une facade de IvyUnbindMsg() de la libraire ivy-c + * @param binding_id : entier representant le numero de l'abonnement que l'on veut arreter + */ + static void pyIvyUnBindMsg (int binding_id) + { + /* on passe à pyIvyUnBindMsg l'indexe du MsgRcvPtr retourné par + pyIvyBindMsg */ + MsgRcvPtr rcvid ; + rcvid = getRcvMsg(binding_id) ; + if (rcvid != NULL) + { + IvyUnbindMsg(rcvid); + delRcvMsg(binding_id); + }; +#ifdef __DEBUG__ + printmsgrcvarray() ; +#endif + } + + + /** + * fonction pyIvySendError() + * cette fonction permet d'envoyer un message d'erreur à un client donner + * cette fonction est une facade de IvySendError() de la librairie ivy-c + * @param app : refrence du client auquel on envoie le message + * @param id : identifiant lié au message + * @param message : chaine de caracteres representant le message d'erreur + */ + void pyIvySendError(IvyClientPtr app, + int id, + const char *message) + { + IvySendError(app,id,message); + } + + + /** + * fonction IvySendDieMsg() + * cette fonction permet de tuer un client via le bus ivy par un envoi d'un message DIE + * cette fonction est une facade de la fonction IvySendDieMsg() de la librairie ivy-c + * @param app : refrence au client à tuer + */ + static void pyIvySendDieMsg(IvyClientPtr app) + { + IvySendDieMsg(app); + } + + + /** + * fonction pyIvySendMsg() + * cette fonction permet d'envoyer un message sue le bus ivy + * cette fonction est une facade de IvySendMsg() évitant le problème de vararg + * @param message : chaine de cracteres representant le message à envoyer + * @return une entier indiquent si l'envoi c'est bien passer + */ + int pyIvySendMsg(const char *message) + { + return(IvySendMsg(message)); + } + + + /** + * fonction pyIvyBindDirectMsg() + * cette fonction permet de s'abonner au message directe entre application + * cette fonction est une facade de IvyBindDirectMsg() évitant le problème de vararg + * @param PyFunc : pointeur sur la callback à appeler lors d'un message direct + */ + static void pyIvyBindDirectMsg (PyObject *PyFunc) + { + /* le user_data est le pointeur PyFunc */ + IvyBindDirectMsg(pyMsgDirectCallback, (void *) PyFunc); + /* on conserve une trace de result sous la forme d'une table + indexé i -> (result) ; cet indice sera incrémenté et retourné + comme valeur de retour */ +#ifdef __DEBUG__ + printmsgrcvarray(); +#endif + Py_INCREF(PyFunc); + Py_INCREF(Py_None) ; + } + + + /** + * fonction pyIvySendDirectMsg() + * cette foction permet d'envoyer un message directement à une autre application connectée au bus ivy + * cette fontion est une facade de IvySendDirectMsg() de la librairie ivy-c + * @param app : refrence du client auquel on veut envoyer les message + * @param id : identifiant lié au message + * @param msg : chaine de caracteres representant le message à envoyer à l'application + */ + static void pyIvySendDirectMsg(IvyClientPtr app, int id, char *msg) + { + IvySendDirectMsg(app, id, msg); + } + + + /** + * il n'existe pas de fonction jouant le role de facade pour la fonction IvySetFilter() + */ + + + /***************************************************************** + ******************* END FACADE FOR IVY ************************** + *****************************************************************/ + + + /***************************************************************** + *********************** FACADE FOR IVY TIMER ******************** + *****************************************************************/ + + + /** + * fonction pyIvyTimerRepeatAfter() + * cette fonction permet de creer un timer et de le declencher + * cette fonction est une facade de TimerRepeatAfter() de la librairie ivy-c + * @param count : duree de comptage + * @param time : temps de depart + * @param PyFunc : ppointeur vers la callback à appeler à la fin du timer + * @return l'identifiant du timer creer pour l'operation + */ + static int pyIvyTimerRepeatAfter(int count, + int time, + PyObject *PyFunc) + { + TimerId timer ; + int timerid ; +#ifdef __DEBUG__ + printf("-pyIvyTimerRepeatAfter\n"); +#endif + timer = TimerRepeatAfter(count, time, + pyTimerCallback, + (void *) PyFunc); + timerid = addIvyTimer(timer); +#ifdef __DEBUG__ + printtimerarray(); +#endif + Py_INCREF(PyFunc); + Py_INCREF(Py_None) ; + return timerid ; + } + + + /** + * fonction pyIvyTimerModify() + * cette fonction permet de modifier les parametres d'un timer donne + * cette fonction est une facade de la fonction de TimerModify() de la librairie ivy-c + * @param timerid : entier representant l'identifiant du timer à modifier + * @param time : le nouveau temps à attribuer au timer + */ + static void pyIvyTimerModify(int timerid, + int time ) + { + TimerId timer ; + timer = getIvyTimer(timerid); + if (timer != NULL) + { + TimerModify(timer, (long) time); + } + } + + + /** + * fonction pyIvyTimerRemove() + * cette fonction permet de supprimer un timer + * cette fonction est une facade de Timerremove() de la lirairie ivy-c + * @param timerid : entier represenatnt l'identifiant du timer à supprimer + */ + static void pyIvyTimerRemove( int timerid) + { + TimerId timer ; + timer = getIvyTimer(timerid); + if (timer != NULL) + { + TimerRemove(timer); + delIvyTimer(timerid); + } + } + + + /************************************************************ + *******************END FACADE FOR IVY TIMER **************** + ************************************************************/ + + /***************************************************************** + ******************** MAINLOOP IVY ******************************* + *****************************************************************/ + + /** + * fonction pyIvyMainLoop() + * cette fonction est la fonctions ecoutant les différents canaux de communication + * et lisant sur les sockets + * c'est donc ce qu'on appelle la mainloop ivy + */ + static void pyIvyMainLoop() + { + fd_set rdset; + fd_set exset; + int ready; + + while (MainLoop) + { + pyChannelDefferedDelete(); + rdset = open_fds; + exset = open_fds; + Py_BEGIN_ALLOW_THREADS + ready = select(64, &rdset, 0, &exset, TimerGetSmallestTimeout()); + Py_END_ALLOW_THREADS + if (ready < 0 && (errno != EINTR)) + { + fprintf (stderr, "select error %d\n",errno); + perror("select"); + return; + } + TimerScan(); + if (ready > 0) + { + pyIvyChannelHandleExcpt(&exset); + pyIvyChannelHandleRead(&rdset); + continue; + } + } + Py_INCREF(Py_None) ; + } + + /**************************************************************** + ***************** FIN MAINLOOP IVY ***************************** + ****************************************************************/ + + + + +/************************************************************** + ************************* PART 2 ***************************** + *on place ici les declarations complementaires : typemap, etc* + *------------------------------------------------------------* + * SWIG typemap allowing us to grab a Python callable object ** + *-----------------------------------------------------------** + **************************************************************/ + +// nouvelle syntaxe SWIG 1.3.x : $target -> $1 et $source -> $input +%typemap(python,in) PyObject *PyFunc { + if (!PyCallable_Check($input)) { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return NULL; + } + $1 = $input; +} + +%typemap(python,in) PyObject *PyFuncOnCx { + if (!PyCallable_Check($input)) { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return NULL; + } + $1 = $input; +} + +%typemap(python,in) PyObject *PyFuncOnDie { + if (!PyCallable_Check($input)) { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return NULL; + } + $1 = $input; +} + +%typemap(python,out) char** { + int size=0, i; + char **msgList; + msgList=$1; + while (*msgList ) + { + /*printf("Message to '%s'\n",*msgList++);*/ + *msgList++; + size++; + } + resultobj=PyTuple_New(size); + msgList=$1; + for (i = 0; i < size; i++) { + PyTuple_SetItem(resultobj,i,PyString_FromString(*msgList++)); + } + $result=resultobj; +} + + + + +/****************************************************************** + *************************** PART 3 ******************************* + ******************** fonctions du wrapper ************************ + ******************************************************************/ + + +/** + * fonction pyIvyInit() + * cette fonction permet d'initialiser une connexion au bus Ivy + * cette fonction est une facade pour la fonction IvyInit() de la librairie ivy-c + * @param AppName : chaine de caractere representant le nom de l'application a connecter + * @param ready : chaine de caractere representant le message envoyer lors d'une connexion + * @param loopmode : entier permettant de fonctionner sur le thread de la boucle tk ou sur un thread à part + * ce parametre doit être mis à zero, car le mode fonctionnant avec le thread tk n'existe plus + * @param pyFuncOnCx : pointeur sur la fonction appelee lors d'une connexion d'une application au bus ivy + * @param PyFuncOnDie : pointeur sur la fonction a appele lors d'un DIE message + */ +void pyIvyInit(const char *AppName, /* nom de l'application */ + const char *ready, /* ready Message peut etre NULL */ + int loopmode, + PyObject *PyFuncOnCx,/* callback appele sur connection deconnection d'une appli */ + PyObject *PyFuncOnDie); /* last change callback before die */ + + + +/** + * fonction pyIvyStart() + * cette fonction permet de demarrer une application ivy + * cette fonction est une facade de la fonction IvyStart() + * @param appname : chaine de caractere representant le nom de l'application a demarrer + */ +/* fonction permettant l'initialisation d'une application */ +void pyIvyStart (const char*); + + +/** + * fonction pyIvyMainLoop() + * cette fonction est la fonctions ecoutant les différents canaux de communication + * et lisant sur les sockets + * c'est donc ce qu'on appelle la mainloop ivy + */ +/* lancement de la mainloop ivy */ +void pyIvyMainLoop(); + + +/** + * fonction pyIvystop() + * cette fonction permet d'arreter une application + * cette fonction est une facade pour la fonction IvyStop() de la librairie ivt-c + */ +/* fonction arretant un application ivy */ +void pyIvyStop (); + + +/** + * fonction pyIvyBindMsg() + * cette fonction permet de s'abonner à un type de message afin de declencher une action sur la reception + * cette fonction est une facade de IvyBindMsg() evitat le problème de vararg + * @param PyFunc : pointeur vers la callback à declencher sur recption d'un message + * @param msg : chaine de caracteres representant le message auquel on s'abonne (ce message est generalement une expression reguliere) + * @return une entier representant le numero de l'abonnement + */ +/* fonction permettant l'abonnement des messages */ +int pyIvyBindMsg (PyObject *PyFunc, const char *msg); + + +/** + * fonction pyIvyUnbindMsg() + * cette fonction permet de se desabonner a un type de message + * cette fonction est une facade de IvyUnbindMsg() de la libraire ivy-c + * @param binding_id : entier representant le numero de l'abonnement que l'on veut arreter + */ +/* fonction permettant le desabonnement des messages */ +void pyIvyUnBindMsg (int binding_id); + + +/** + * fonction pyIvySendMsg() + * cette fonction permet d'envoyer un message sue le bus ivy + * cette fonction est une facade de IvySendMsg() évitant le problème de vararg + * @param message : chaine de cracteres representant le message à envoyer + * @return une entier indiquent si l'envoi c'est bien passer + */ +/* fonction permettant l'envoi du message */ +int pyIvySendMsg(const char *message); + + +/** + * fonction pyIvySendDieMsg() + * cette fonction permet de tuer un client via le bus ivy par un envoi d'un message DIE + * cette fonction est une facade de la fonction IvySendDieMsg() de la librairie ivy-c + * @param app : refrence au client à tuer + */ +/* emission d'un message die pour terminer l'application */ +void pyIvySendDieMsg(IvyClientPtr app); + + +/** + * fonction pyIvySendDirectMsg() + * cette foction permet d'envoyer un message directement à une autre application connectée au bus ivy + * cette fontion est une facade de IvySendDirectMsg() de la librairie ivy-c + * @param app : refrence du client auquel on veut envoyer les message + * @param id : identifiant lié au message + * @param msg : chaine de caracteres representant le message à envoyer à l'application + */ +/* send direct message to an application */ +void pyIvySendDirectMsg(IvyClientPtr app, int id, char *msg); + + +/** + * fonction pyIvyBindDirectMsg() + * cette fonction permet de s'abonner au message directe entre application + * cette fonction est une facade de IvyBindDirectMsg() évitant le problème de vararg + * @param PyFunc : pointeur sur la callback à appeler lors d'un message direct + */ +/* bind direct a venir non implémente en ivy-python*/ +void pyIvyBindDirectMsg(PyObject *PyFunc); + + +/** + * fonction pyIvySendError() + * cette fonction permet d'envoyer un message d'erreur à un client donner + * cette fonction est une facade de IvySendError() de la librairie ivy-c + * @param app : refrence du client auquel on envoie le message + * @param id : identifiant lié au message + * @param message : chaine de caracteres representant le message d'erreur + */ +/* emission d'un message d'erreur non implemente en ivy-python*/ +void pyIvySendError(IvyClientPtr app, + int id, + const char *message); + +/* fonctions de bind et unbind callback non implemente en ivy-python*/ + +/** + * fonction pyIvySetBindCallBack() + * cette fonction permet de donner la callback a appele lors d'un bind + * cette fonction est la facade de la fonction IvySetBindCallback() + * @param PyFunc: pointeur sur la callback appelee lors d'un bind + */ +void pyIvySetBindCallback(PyObject *PyFunc); + + +/** + * fonction pyIvyDelBindCallback() + * cette fonction permet de reseter la callback appelee lors d'un bind + * cette fonction est une facade de la fonction IvySetBindCallback() + * @TODO cette fonction ne marche peut être pas, il faudrait la tester et la corriger le cas échéant + */ +void pyIvyDelBindCallback(); + + +/** + * fonction pyIvyGetApplicationList() + * cette fonction permet de recuperer la liste des clients connectes au bus ivy + * cette fonction est uen facade de la fonction IvygetApplicationList() de la librairie ivy-c + * @param sep : chaine de caractere representant le separateur a mettre entre les noms d'application + * @return chaine de caracteres representant la liste des clients connectes separes par le separateur + */ +/* fonction permettant de recuperer la liste des applications */ +char* pyIvyGetApplicationList(const char* sep); + + +/** + * fonction pyIvyGetApplication() + * cette fonction permet de recuperer un une reference a un client ivy à partir de son nom + * cette fonction est uen facade de la fonction IvyGetApplication() de la librairie ivy-c + * @param name : chaine de caracteres represenatnt le nom de l'application + * @return une reference au client ivy + */ +/* fonction permettant de recuperer un client */ +IvyClientPtr pyIvyGetApplication(char *name); + + +/** + * fonction pyIvyGetApplicationName() + * cette fonction permet de recuperer le nom d'une application cliente + * cette fonction est uen facade de la fonction IvyGetApplicationName() de la librairie ivy-c + * @param app : pointeur vers le client dont on veur recuperer le nom + * @return une chane de caracteres representant le nom de l'application + */ +/* fonction permettant la recuperation du nom d'un client */ +char* pyIvyGetApplicationName(IvyClientPtr app); + + +/** + * fonction pyIvyGetApplicationHost() + * cette fonction permet de recuperer la machine hote du client ivy passe en parametre + * cette fonction est une facade de la fonction IvyGetApplicationHost() de la librairie ivy-c + * @param app : pointeur vers le client ivy + * @return une chaine de caracteres representant le nom de la machine hote du client + */ +/* fonction peremettant la recuperation de l'hote du client */ +char* pyIvyGetApplicationHost(IvyClientPtr app); + + +/** + * fonction pyIvyGetApplicationMessages() + * cette fonction permet de recuperer la liste des abonnements d'un client + * cette fonction est une facade de la fonction IvyGetApplicationMessages() de la libraire ivy-c + * @param app : refreence au client dnt on desire recuperer les abonnements + * @return un tableau de chaines de caracteres represenatnt les differents abonnements + */ +/* methode permettant la recuperation de la liste des abonnement d'un client non implemente en ivy-python*/ +char** pyIvyGetApplicationMessages(IvyClientPtr app); + + +/** + * fonction pyIvyTimerRepeatAfter() + * cette fonction permet de creer un timer et de le declencher + * cette fonction est une facade de TimerRepeatAfter() de la librairie ivy-c + * @param count : duree de comptage + * @param time : temps de depart + * @param PyFunc : ppointeur vers la callback à appeler à la fin du timer + * @return l'identifiant du timer creer pour l'operation + */ +/* fonctions a wrapper concernant les timer */ +int pyIvyTimerRepeatAfter(int count, + int time, + PyObject *PyFunc); + + +/** + * fonction pyIvyTimerModify() + * cette fonction permet de modifier les parametres d'un timer donne + * cette fonction est une facade de la fonction de TimerModify() de la librairie ivy-c + * @param timerid : entier representant l'identifiant du timer à modifier + * @param time : le nouveau temps à attribuer au timer + */ +void pyIvyTimerModify(int timerid, + int time); + + +/** + * fonction pyIvyTimerRemove() + * cette fonction permet de supprimer un timer + * cette fonction est une facade de Timerremove() de la lirairie ivy-c + * @param timerid : entier represenatnt l'identifiant du timer à supprimer + */ +void pyIvyTimerRemove(int timerid); + + +// for emacs +// Local Variables: +// mode: C +// indent-tabs-mode: t +// tab-width: 4 +// End: |