Muy buenas.
Pues la idea es hacer algo parecido a los delegados de C# pero con el C de toda la vida.
Sobre una lista dinámica de diferentes funciones con la misma firma se puede hacer las siguientes operaciones:
· Añadir funciones al final de la lista
· Quitar la primera aparición de una función dada
· Vaciar la lista de una tacada
· Ejecutar todas las funciones de la lista de forma secuencial y con unos parámetros comunes dados en la llamada a la ejecución.
En este programa se trabaja sobre una función que acepta un char* y no devuelve nada, pero se puede modificar fácilmente para trabajar con otras funciones.
#include <stdio.h>
#include <stdlib.h>
typedef struct tdelegate {
void (*func)(char*);
struct tdelegate *next;
} DELEGATE;
int delegate_add(DELEGATE **pdelegate, void (*funcpointer)(char*)) {
DELEGATE
*newdelegate
= malloc(sizeof(DELEGATE
)); DELEGATE *aux = NULL;
if(newdelegate == NULL)
return 0;
newdelegate->func = funcpointer;
newdelegate->next = NULL;
if(*pdelegate == NULL)
*pdelegate = newdelegate;
else {
aux = *pdelegate;
while(aux->next != NULL)
aux = aux->next;
aux->next = newdelegate;
}
return 1;
}
void delegate_exec(DELEGATE **pdelegate, char *str) {
DELEGATE *actualdelegate = *pdelegate;
while(actualdelegate != NULL) {
actualdelegate->func(str);
actualdelegate = actualdelegate->next;
}
}
void delegate_del(DELEGATE **pdelegate, void (*funcpointer)(char*)) {
DELEGATE *actualdelegate = *pdelegate;
DELEGATE *aux = NULL;
int found = 0;
if(funcpointer == NULL || actualdelegate == NULL)
return;
if(actualdelegate->func == funcpointer)
{
aux = actualdelegate->next;
actualdelegate = aux;
}
else {
while(actualdelegate->next != NULL && !found) {
if(actualdelegate->next->func == funcpointer) {
found = 1;
aux = actualdelegate->next->next;
free(actualdelegate
->next
); actualdelegate->next = aux;
}
else actualdelegate = actualdelegate->next;
}
}
}
void delegate_free(DELEGATE **pdelegate) {
DELEGATE *aux = NULL;
if(*pdelegate == NULL) return;
while(*pdelegate != NULL) {
aux = (*pdelegate)->next;
*pdelegate = aux;
}
}
/* FUNCIONES DE PRUEBA */
void a(char *str) {
}
void b(char *str) {
}
void c(char *str) {
}
/* PROGRAMA DE PRUEBA */
int main() {
DELEGATE *midelegado = NULL;
delegate_add(&midelegado, &a);
delegate_add(&midelegado, &b);
delegate_add(&midelegado, &c);
delegate_exec(&midelegado, "hola");
delegate_del(&midelegado, &b);
delegate_exec(&midelegado, "adios");
delegate_free(&midelegado);
midelegado = NULL;
return 0;
}
muy bueno tenia en mente hacer algo parecido. Le echaré un ojo. ;-)