Facile
On utilise la notion de "callbacks", ou de fonctions enregistrées (exactement simlaires aux callbacks d'un widget dans une IHM)
Un petit exemple en C : (je simplifie un peu : je ne mets pas toutes les fonctions, et plusieurs options sont possibles)
Soit un include de définitions d'actions diverses :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 #define ENVOYER 1 #define TIMBRER 2 #define PESER 3 ....
et un include de définition d'une structure de fonction callback commune :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 .. typedef int HandlerFunction ( void *Clientdata );
On a un module de gestion des events :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 typedef struct pEventHandler { int EventType ; int ObjectType ; HandlerFunction *Function } EventHandler ; static EventHandler *TableEvents=NULL ; static int NEventHandlers=0 ; int RegisterEventHandler ( int EventType, int ObjectType, int *Function ) { EventHandler *tmp ; tmp = realloc ( TableEvents, (NEventHandlers+1)*sizeof(EventHandler) ); if ( tmp != NULL ) { TableEvents = tmp ; Tablevents[NEventHandlers].EventType = EventType ; Tablevents[NEventHandlers].ObjectType = ObjectType ; Tablevents[NEventHandlers].Function = Function ; NEventHandlers = NEventHandlers + 1 ; return SUCCESS ; } else return ERROR ; } int CallRegisteredFunction ( int EventType, int ObjectType, void *ClientData ) { int i, s = SUCCESS ; for ( i = 0 ; i < NEventHandlers ; i++ ) { if ( (TableEvents[i].EventType == EventType) && (TableEvents[i].ObjectType == ObjectType) ) { s = TableEvents[i].Function ( ClientData ) ; break ; } } return s ; }
On a un code de création des "classes" et de leurs méthodes :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #define CENTRE_TRI 0 #define MESSAGER 1 ... /* Crée centre de tri */ ... RegisterEventHandler ( ENVOYER, CENTRE_TRI, &EnvoyerParCentreDeTri ); .. /* Crée messager */ .. RegisterEventHandler ( ENVOYER, MESSAGER, &EnvoyerParMessager ); .. .. int EnvoyerMessageParCentreDeTri ( void *Data ) { .... }
et on a un code d'utilisation :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 ... /* La variable TypeEnvoi est définie par l'appli, par l'usager via l'IHM.. */ statut = CallRegisteredFunction ( ENVOYER, TypeEnvoi, &MyData );
Tu vois, c'est pas bien long
Pour étendre les moyens d'envois, il suffit de créer la classe correspondante dane le module de création, et d'ajouter le choix dans l'IHM par exemple.. (on ne touche même pas les modules applicatifs)
Il y a d'autres moyens de faire, mais là je te donne un exemple... Utilisé absolument couramment en procédural un peu évolué (on peut même rajouter des structures dépendantes des actions (ce qui se fait dans les callbacks de widgets))
D'autre part, comme le code de gestion des handlers est général, le même module (oui oui, juste ces 45 petites lignes) peut s'appliquer pour enregistrer des fonctions d'édition, d'IHM, d'accès à des BD, de traitement d'image, ce qu'on veut..
Partager