Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que
mon Thread qui gère le réseau reçoit des données, il envoi
alors un un Evenement au thread concerné par ces données pour
lui dire qu'il a quelquechose a traiter.
En gros:
<Code éxécuté dans chaque Thread>:
{
while( true )
{
Event = EventManager.somethingHappened();
switch(Event.type())
{
case DATA_AVALAIBLE:
// Traitement des paramètres de l'év ènement etc
case ...:
...
case ...:
...
}
}
}
<Code éxécuté dans le thread des connections>:
{
...
// Données réçue sur un socket
Event e(DATA_AVALAIBLE, params...)
EventManager.postEvent(e);
...
}
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire,
je pensais utiliser une variable de condition (avec
pthread_cond_wait()), mais tous les Threads ne peuvent pas
utiliser la même puisque un Evenement n'est pas forcément
adressé à tous les threads...
De plus, la gestion des paramètres est compliqué, un évènement
peut avoir un nombre de paramètres et un type de paramètres
variable selon l'événement donné...
Si vous avez des idées ! Je précise je débute et mon
implémentation est peut-être une mauvaise idée, j'attends vos
suggestions dans ce cas, merci.
Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que
mon Thread qui gère le réseau reçoit des données, il envoi
alors un un Evenement au thread concerné par ces données pour
lui dire qu'il a quelquechose a traiter.
En gros:
<Code éxécuté dans chaque Thread>:
{
while( true )
{
Event = EventManager.somethingHappened();
switch(Event.type())
{
case DATA_AVALAIBLE:
// Traitement des paramètres de l'év ènement etc
case ...:
...
case ...:
...
}
}
}
<Code éxécuté dans le thread des connections>:
{
...
// Données réçue sur un socket
Event e(DATA_AVALAIBLE, params...)
EventManager.postEvent(e);
...
}
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire,
je pensais utiliser une variable de condition (avec
pthread_cond_wait()), mais tous les Threads ne peuvent pas
utiliser la même puisque un Evenement n'est pas forcément
adressé à tous les threads...
De plus, la gestion des paramètres est compliqué, un évènement
peut avoir un nombre de paramètres et un type de paramètres
variable selon l'événement donné...
Si vous avez des idées ! Je précise je débute et mon
implémentation est peut-être une mauvaise idée, j'attends vos
suggestions dans ce cas, merci.
Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que
mon Thread qui gère le réseau reçoit des données, il envoi
alors un un Evenement au thread concerné par ces données pour
lui dire qu'il a quelquechose a traiter.
En gros:
<Code éxécuté dans chaque Thread>:
{
while( true )
{
Event = EventManager.somethingHappened();
switch(Event.type())
{
case DATA_AVALAIBLE:
// Traitement des paramètres de l'év ènement etc
case ...:
...
case ...:
...
}
}
}
<Code éxécuté dans le thread des connections>:
{
...
// Données réçue sur un socket
Event e(DATA_AVALAIBLE, params...)
EventManager.postEvent(e);
...
}
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire,
je pensais utiliser une variable de condition (avec
pthread_cond_wait()), mais tous les Threads ne peuvent pas
utiliser la même puisque un Evenement n'est pas forcément
adressé à tous les threads...
De plus, la gestion des paramètres est compliqué, un évènement
peut avoir un nombre de paramètres et un type de paramètres
variable selon l'événement donné...
Si vous avez des idées ! Je précise je débute et mon
implémentation est peut-être une mauvaise idée, j'attends vos
suggestions dans ce cas, merci.
Bonjour à tous,
Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que mon Thread
qui gère le réseau reçoit des données, il envoi alors un un Evenement
au thread concerné par ces données pour lui dire qu'il a quelquechose
a traiter.
[...]
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
pensais utiliser une variable de condition (avec pthread_cond_wait()),
mais tous les Threads ne peuvent pas utiliser la même puisque un
Evenement n'est pas forcément adressé à tous les threads...
De plus, la gestion des paramètres est compliqué, un évènement peut
avoir un nombre de paramètres et un type de paramètres variable selon
l'événement donné...
Bonjour à tous,
Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que mon Thread
qui gère le réseau reçoit des données, il envoi alors un un Evenement
au thread concerné par ces données pour lui dire qu'il a quelquechose
a traiter.
[...]
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
pensais utiliser une variable de condition (avec pthread_cond_wait()),
mais tous les Threads ne peuvent pas utiliser la même puisque un
Evenement n'est pas forcément adressé à tous les threads...
De plus, la gestion des paramètres est compliqué, un évènement peut
avoir un nombre de paramètres et un type de paramètres variable selon
l'événement donné...
Bonjour à tous,
Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que mon Thread
qui gère le réseau reçoit des données, il envoi alors un un Evenement
au thread concerné par ces données pour lui dire qu'il a quelquechose
a traiter.
[...]
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
pensais utiliser une variable de condition (avec pthread_cond_wait()),
mais tous les Threads ne peuvent pas utiliser la même puisque un
Evenement n'est pas forcément adressé à tous les threads...
De plus, la gestion des paramètres est compliqué, un évènement peut
avoir un nombre de paramètres et un type de paramètres variable selon
l'événement donné...
Merwin writes:Bonjour à tous,
Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que mon Thread
qui gère le réseau reçoit des données, il envoi alors un un Evenement
au thread concerné par ces données pour lui dire qu'il a quelquechose
a traiter.
[...]
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
pensais utiliser une variable de condition (avec pthread_cond_wait()),
mais tous les Threads ne peuvent pas utiliser la même puisque un
Evenement n'est pas forcément adressé à tous les threads...
Il faut choisir entre deux:
- avoir une seule queue d'évènement ; dans ce cas, mettre un évènement
dans la queue est simple, le fil réseau n'a pas besoin de connaitre
la correspondance entre les évènements qu'il envoit et le fil qui
doit le traiter. Mais la collecte des évènements est plus
compliquée car chaque fil devra sélectionner les évènements dont il
a besoin (il faudrait ajouter un paramètre à getNextEvent
(somethingHappened)).
- avoir une queue par fil ; dans ce cas, envoyer un évènement est un
peu plus compliqué car il faut pouvoir déterminer la correspondance
entre l'évènement et le fil qui va le traiter (mais ça s'apparente
à l'envoi d'un message à un objet). Mais la collecte est simple,
car chaque fil a sa propre queue.
Si la correspondance entre les évènements et les fils est simple,
cette dernière solution aurait ma préférence. Un avantage d'avoir une
queue par fil est qu'il y a plusieurs queues, et donc moins de
contention.
Pour ce qui est des conditions et des mutex, ils ne dépendent pas des
fils, mais des conditions et des zone à exclusion mutuelle. En gros,
chaque queue doit être gérée indépendament.De plus, la gestion des paramètres est compliqué, un évènement peut
avoir un nombre de paramètres et un type de paramètres variable selon
l'événement donné...
Les évènements sont typiquement classifiables avec une belle
hierarchie: fais des sous-classes à volonté!
(en C, on aurait utilisé une union).
Merwin <merwin.irc@gmail.com> writes:
Bonjour à tous,
Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que mon Thread
qui gère le réseau reçoit des données, il envoi alors un un Evenement
au thread concerné par ces données pour lui dire qu'il a quelquechose
a traiter.
[...]
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
pensais utiliser une variable de condition (avec pthread_cond_wait()),
mais tous les Threads ne peuvent pas utiliser la même puisque un
Evenement n'est pas forcément adressé à tous les threads...
Il faut choisir entre deux:
- avoir une seule queue d'évènement ; dans ce cas, mettre un évènement
dans la queue est simple, le fil réseau n'a pas besoin de connaitre
la correspondance entre les évènements qu'il envoit et le fil qui
doit le traiter. Mais la collecte des évènements est plus
compliquée car chaque fil devra sélectionner les évènements dont il
a besoin (il faudrait ajouter un paramètre à getNextEvent
(somethingHappened)).
- avoir une queue par fil ; dans ce cas, envoyer un évènement est un
peu plus compliqué car il faut pouvoir déterminer la correspondance
entre l'évènement et le fil qui va le traiter (mais ça s'apparente
à l'envoi d'un message à un objet). Mais la collecte est simple,
car chaque fil a sa propre queue.
Si la correspondance entre les évènements et les fils est simple,
cette dernière solution aurait ma préférence. Un avantage d'avoir une
queue par fil est qu'il y a plusieurs queues, et donc moins de
contention.
Pour ce qui est des conditions et des mutex, ils ne dépendent pas des
fils, mais des conditions et des zone à exclusion mutuelle. En gros,
chaque queue doit être gérée indépendament.
De plus, la gestion des paramètres est compliqué, un évènement peut
avoir un nombre de paramètres et un type de paramètres variable selon
l'événement donné...
Les évènements sont typiquement classifiables avec une belle
hierarchie: fais des sous-classes à volonté!
(en C, on aurait utilisé une union).
Merwin writes:Bonjour à tous,
Bon je vous explique un peu ce que j'essaye de faire:
1. J'ai un programme qui contient plusieurs Threads (avec pthread)
2. Il y a un Thread qui gère la réception de données réseaux via des
sockets Tcp et select().
3. Il a X autres Threads qui traite chacun les données réseaux leur
appartenant, ainsi que des évènements envoyés par d'autres Threads.
Je cherche donc à créer un 'EventManager', l'idée c'est que mon Thread
qui gère le réseau reçoit des données, il envoi alors un un Evenement
au thread concerné par ces données pour lui dire qu'il a quelquechose
a traiter.
[...]
J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
pensais utiliser une variable de condition (avec pthread_cond_wait()),
mais tous les Threads ne peuvent pas utiliser la même puisque un
Evenement n'est pas forcément adressé à tous les threads...
Il faut choisir entre deux:
- avoir une seule queue d'évènement ; dans ce cas, mettre un évènement
dans la queue est simple, le fil réseau n'a pas besoin de connaitre
la correspondance entre les évènements qu'il envoit et le fil qui
doit le traiter. Mais la collecte des évènements est plus
compliquée car chaque fil devra sélectionner les évènements dont il
a besoin (il faudrait ajouter un paramètre à getNextEvent
(somethingHappened)).
- avoir une queue par fil ; dans ce cas, envoyer un évènement est un
peu plus compliqué car il faut pouvoir déterminer la correspondance
entre l'évènement et le fil qui va le traiter (mais ça s'apparente
à l'envoi d'un message à un objet). Mais la collecte est simple,
car chaque fil a sa propre queue.
Si la correspondance entre les évènements et les fils est simple,
cette dernière solution aurait ma préférence. Un avantage d'avoir une
queue par fil est qu'il y a plusieurs queues, et donc moins de
contention.
Pour ce qui est des conditions et des mutex, ils ne dépendent pas des
fils, mais des conditions et des zone à exclusion mutuelle. En gros,
chaque queue doit être gérée indépendament.De plus, la gestion des paramètres est compliqué, un évènement peut
avoir un nombre de paramètres et un type de paramètres variable selon
l'événement donné...
Les évènements sont typiquement classifiables avec une belle
hierarchie: fais des sous-classes à volonté!
(en C, on aurait utilisé une union).
Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Merwin writes:Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
Merwin <merwin.irc@gmail.com> writes:
Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
Merwin writes:Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
Pascal J. Bourguignon a écrit :Merwin writes:Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
En lisant la doc de la STL, je suis tombé sur typeinfo:
http://www.cplusplus.com/reference/std/typeinfo/type_info/
Est-ce que ça ne serait pas mieux ?
Pascal J. Bourguignon a écrit :
Merwin <merwin.irc@gmail.com> writes:
Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
En lisant la doc de la STL, je suis tombé sur typeinfo:
http://www.cplusplus.com/reference/std/typeinfo/type_info/
Est-ce que ça ne serait pas mieux ?
Pascal J. Bourguignon a écrit :Merwin writes:Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
En lisant la doc de la STL, je suis tombé sur typeinfo:
http://www.cplusplus.com/reference/std/typeinfo/type_info/
Est-ce que ça ne serait pas mieux ?
Merwin writes:Pascal J. Bourguignon a écrit :Merwin writes:Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
En lisant la doc de la STL, je suis tombé sur typeinfo:
http://www.cplusplus.com/reference/std/typeinfo/type_info/
Est-ce que ça ne serait pas mieux ?
C'est le mécanisme sous-jacent à dynamic_cast.
Le mieux, c'est la méthode virtuelle, avec retour sur l'objet
appelant.
Merwin <merwin.irc@gmail.com> writes:
Pascal J. Bourguignon a écrit :
Merwin <merwin.irc@gmail.com> writes:
Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
En lisant la doc de la STL, je suis tombé sur typeinfo:
http://www.cplusplus.com/reference/std/typeinfo/type_info/
Est-ce que ça ne serait pas mieux ?
C'est le mécanisme sous-jacent à dynamic_cast.
Le mieux, c'est la méthode virtuelle, avec retour sur l'objet
appelant.
Merwin writes:Pascal J. Bourguignon a écrit :Merwin writes:Merci, je pense que je vais en effet partir sur le principe une
queue/objet. Pour les évènements en sous classe je veux bien, mais
comment je peux déterminer le type de l'évènement quand je le
récupère?
Une première solution c'est de mettre les methodes de traitement de
l'évènement dans l'évènement lui-même (comme méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se réduire à
faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une table
pour accéler la sélection de la méthode à envoyer, mais il faudra
quand même utiliser un dynamic_cast pour revenir à la classe exacte de
l'évènement afin d'accéder à ses champs spécifiques.
En lisant la doc de la STL, je suis tombé sur typeinfo:
http://www.cplusplus.com/reference/std/typeinfo/type_info/
Est-ce que ça ne serait pas mieux ?
C'est le mécanisme sous-jacent à dynamic_cast.
Le mieux, c'est la méthode virtuelle, avec retour sur l'objet
appelant.
Merwin writes:
> Bon je vous explique un peu ce que j'essaye de faire:
> 1. J'ai un programme qui contient plusieurs Threads (avec pthread)
> 2. Il y a un Thread qui gère la réception de données réseaux vi a des
> sockets Tcp et select().
> 3. Il a X autres Threads qui traite chacun les données réseaux leur
> appartenant, ainsi que des évènements envoyés par d'autres Thread s.
> Je cherche donc à créer un 'EventManager', l'idée c'est que mon T hread
> qui gère le réseau reçoit des données, il envoi alors un un Eve nement
> au thread concerné par ces données pour lui dire qu'il a quelquecho se
> a traiter.
> [...]
> J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
> pensais utiliser une variable de condition (avec pthread_cond_wait()),
> mais tous les Threads ne peuvent pas utiliser la même puisque un
> Evenement n'est pas forcément adressé à tous les threads...
Il faut choisir entre deux:
- avoir une seule queue d'évènement ; dans ce cas, mettre un évèn ement
dans la queue est simple, le fil réseau n'a pas besoin de connaitre
la correspondance entre les évènements qu'il envoit et le fil qui
doit le traiter. Mais la collecte des évènements est plus
compliquée car chaque fil devra sélectionner les évènements don t il
a besoin (il faudrait ajouter un paramètre à getNextEvent
(somethingHappened)).
- avoir une queue par fil ; dans ce cas, envoyer un évènement est un
peu plus compliqué car il faut pouvoir déterminer la correspondance
entre l'évènement et le fil qui va le traiter (mais ça s'apparen te
à l'envoi d'un message à un objet). Mais la collecte est simple,
car chaque fil a sa propre queue.
Les évènements sont typiquement classifiables avec une belle
hierarchie: fais des sous-classes à volonté!
(en C, on aurait utilisé une union).
Merwin <merwin....@gmail.com> writes:
> Bon je vous explique un peu ce que j'essaye de faire:
> 1. J'ai un programme qui contient plusieurs Threads (avec pthread)
> 2. Il y a un Thread qui gère la réception de données réseaux vi a des
> sockets Tcp et select().
> 3. Il a X autres Threads qui traite chacun les données réseaux leur
> appartenant, ainsi que des évènements envoyés par d'autres Thread s.
> Je cherche donc à créer un 'EventManager', l'idée c'est que mon T hread
> qui gère le réseau reçoit des données, il envoi alors un un Eve nement
> au thread concerné par ces données pour lui dire qu'il a quelquecho se
> a traiter.
> [...]
> J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
> pensais utiliser une variable de condition (avec pthread_cond_wait()),
> mais tous les Threads ne peuvent pas utiliser la même puisque un
> Evenement n'est pas forcément adressé à tous les threads...
Il faut choisir entre deux:
- avoir une seule queue d'évènement ; dans ce cas, mettre un évèn ement
dans la queue est simple, le fil réseau n'a pas besoin de connaitre
la correspondance entre les évènements qu'il envoit et le fil qui
doit le traiter. Mais la collecte des évènements est plus
compliquée car chaque fil devra sélectionner les évènements don t il
a besoin (il faudrait ajouter un paramètre à getNextEvent
(somethingHappened)).
- avoir une queue par fil ; dans ce cas, envoyer un évènement est un
peu plus compliqué car il faut pouvoir déterminer la correspondance
entre l'évènement et le fil qui va le traiter (mais ça s'apparen te
à l'envoi d'un message à un objet). Mais la collecte est simple,
car chaque fil a sa propre queue.
Les évènements sont typiquement classifiables avec une belle
hierarchie: fais des sous-classes à volonté!
(en C, on aurait utilisé une union).
Merwin writes:
> Bon je vous explique un peu ce que j'essaye de faire:
> 1. J'ai un programme qui contient plusieurs Threads (avec pthread)
> 2. Il y a un Thread qui gère la réception de données réseaux vi a des
> sockets Tcp et select().
> 3. Il a X autres Threads qui traite chacun les données réseaux leur
> appartenant, ainsi que des évènements envoyés par d'autres Thread s.
> Je cherche donc à créer un 'EventManager', l'idée c'est que mon T hread
> qui gère le réseau reçoit des données, il envoi alors un un Eve nement
> au thread concerné par ces données pour lui dire qu'il a quelquecho se
> a traiter.
> [...]
> J'ai vraiment du mal à gérer ça, je ne vois pas comment faire, je
> pensais utiliser une variable de condition (avec pthread_cond_wait()),
> mais tous les Threads ne peuvent pas utiliser la même puisque un
> Evenement n'est pas forcément adressé à tous les threads...
Il faut choisir entre deux:
- avoir une seule queue d'évènement ; dans ce cas, mettre un évèn ement
dans la queue est simple, le fil réseau n'a pas besoin de connaitre
la correspondance entre les évènements qu'il envoit et le fil qui
doit le traiter. Mais la collecte des évènements est plus
compliquée car chaque fil devra sélectionner les évènements don t il
a besoin (il faudrait ajouter un paramètre à getNextEvent
(somethingHappened)).
- avoir une queue par fil ; dans ce cas, envoyer un évènement est un
peu plus compliqué car il faut pouvoir déterminer la correspondance
entre l'évènement et le fil qui va le traiter (mais ça s'apparen te
à l'envoi d'un message à un objet). Mais la collecte est simple,
car chaque fil a sa propre queue.
Les évènements sont typiquement classifiables avec une belle
hierarchie: fais des sous-classes à volonté!
(en C, on aurait utilisé une union).
Merwin writes:
> Merci, je pense que je vais en effet partir sur le principe
> une queue/objet. Pour les évènements en sous classe je veux
> bien, mais comment je peux déterminer le type de l'évènement
> quand je le récupère?
Une première solution c'est de mettre les methodes de
traitement de l'évènement dans l'évènement lui-même (comme
méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se
réduire à faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une
table pour accéler la sélection de la méthode à envoyer, mais
il faudra quand même utiliser un dynamic_cast pour revenir à
la classe exacte de l'évènement afin d'accéder à ses champs
spécifiques.
Merwin <merwin....@gmail.com> writes:
> Merci, je pense que je vais en effet partir sur le principe
> une queue/objet. Pour les évènements en sous classe je veux
> bien, mais comment je peux déterminer le type de l'évènement
> quand je le récupère?
Une première solution c'est de mettre les methodes de
traitement de l'évènement dans l'évènement lui-même (comme
méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se
réduire à faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une
table pour accéler la sélection de la méthode à envoyer, mais
il faudra quand même utiliser un dynamic_cast pour revenir à
la classe exacte de l'évènement afin d'accéder à ses champs
spécifiques.
Merwin writes:
> Merci, je pense que je vais en effet partir sur le principe
> une queue/objet. Pour les évènements en sous classe je veux
> bien, mais comment je peux déterminer le type de l'évènement
> quand je le récupère?
Une première solution c'est de mettre les methodes de
traitement de l'évènement dans l'évènement lui-même (comme
méthode virtuelle).
Event* e=GetNextEvent();
e->process(this);
(et la méthode process de chaque sous-classe d'Event peut se
réduire à faire suivre un message à son argument:
OpenEvent::process(Recipient* r){ r->processOpenEvent(this); }
CloseEvent::process(Recipient* r){ r->processCloseEvent(this); }
SendEvent::process(Recipient* r){ r->processSendEvent(this); }
Sinon, on peut utiliser dynamic_cast, mais c'est moins beau:
Event* e=GetNextEvent();
OpenEvent* oe=dynamic_cast<OpenEvent*>e;
if(oe){ processOpen(oe); }else{
CloseEvent* ce=dynamic_cast<OpenEvent*>e;
if(ce){ processClose(ce); }else{
SendEvent* se=dynamic_cast<OpenEvent*>e;
if(se){ processSend(se); }else{
throw std::exception("Unexpected event class");}}}
On pourrait utiliser un enum et un switch, ou un index et une
table pour accéler la sélection de la méthode à envoyer, mais
il faudra quand même utiliser un dynamic_cast pour revenir à
la classe exacte de l'évènement afin d'accéder à ses champs
spécifiques.