Bonjour !
Je vais essayer d'exprimer ce que je voudrais, ca va etre dur x)
Alors, il me faut:
- une classe template mère, dedans sera défini une fonction 'handle'; et une unordered_map<short, pointeur vers fonction membre de la classe fille>
- pour tester, on utiliser une seule classe fille, qui va devoir hériter de la class template mere.
- une classe abstraite(???) qui permettra d'avoir un type de variable commun pour pouvoir utiliser chaque classe fille, mais sur une variable de meme type.
Voici ce que j'ai,
La classe mère, et celle abstraite:
Voici maintenant, une classe fille:
Code : 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 #ifndef HANDLER_H #define HANDLER_H #include <unordered_map> using namespace std; #include "Packet.h" class PacketHandler { public: virtual void handle(PacketReader& packet) {}; static void loadPackets() {}; }; template <class T> class Handler : public PacketHandler { public: typedef void(T::*handlerf)(PacketReader& packet); // le pointeur vers fonction membre de la classe fille void handle(PacketReader& packet){ // la fonction handle if(handlers.find(packet.GetHeader())== handlers.end()){ if(handlers.find(-1)!= handlers.end()) ((T*)this->*handlers[-1])(packet); } else{ handlerf func = handlers[packet.GetHeader()]; ((T*)this->*func)(packet); } } static void loadPackets(){}; // pour charger les valeurs dans 'handlers' protected: static unordered_map<short, handlerf> handlers; // et la map }; template <class T> void Handler<T>::handle(PacketReader& packet); #endif
Au début de la classe fille j'ai:
Code : 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 #ifndef UNKNOWNPACKETHANDLER_H #define UNKNOWNPACKETHANDLER_H #include "../Tools/Handler.h" using namespace std; typedef unsigned short ushort; class Selector; class Session; class UnknownPacketHandler; class UnknownPacketHandler: public Handler<UnknownPacketHandler> { private: // liste des short a ajouter dans handlers; static const ushort IDENTIFY = 0x01; Session* target; Selector* server; public: /** Default constructor */ UnknownPacketHandler(Session* t, Selector* st) { target = t; server = st; }; /** Default destructor */ ~UnknownPacketHandler() { delete target; delete server; }; static void loadPackets(); // liste des fonctions a ajotuer dans handlers void identify(PacketReader& packet); }; #endif // UNKNOWNPACKETHANDLER_H
Et finalement, un test:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2unordered_map<short, UnknownPacketHandler::handlerf> Handler<UnknownPacketHandler>::handlers;
Code : 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #ifndef SESSION_H #define SESSION_H #if defined __MINGW32__ #include <winsock2.h> #elif defined __GNUC__ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #endif #include <ctime> #include <string> #include "Packet.h" //#include "Handler.h" #include "../PacketHandler/UnknownPacketHandler.h" //#include "../PacketHandler/ServerPacketHandler.h" using namespace std; typedef string IPaddress; typedef int TCPsocket; class Selector; class PacketHandler; class Session { public: /** Default constructor */ Session() {} Session(const IPaddress& ip, const TCPsocket& sock, Selector* slt) { SessionInfo.ip = ip; SessionInfo.sock = sock; SessionInfo.lastping = clock(); selector = slt; handler = new UnknownPacketHandler(this, selector); // et hop, on construit ! } /** Default destructor */ virtual ~Session() { delete reader; delete selector; delete handler; } void handleRequest(const char* Buffer) { reader = new PacketReader(Buffer); handler->handle(*reader); } private: PacketReader* reader; PacketHandler* handler; // ici nous avons le type commun Selector* selector; }; #endif // SESSION_H
note: Vous voyez, dans le dernier fichier, j'ai commenté include ServerPacketHandler.
En effet, le but de ce que j'essaye de faire, et de pouvoir séparer le handler qui s'occupera de la reception de mes packets, car sur mon serveur, je vais avoir des clients, d'autres serveurs, et des robots, et aussi des 'unknown' !
De plus, elle evite de nombreux if() partout dans le code, car le handler pointra où il faut!
Voilou !
Maintenant, retour à la réalité:
C'est donc sur la declaration dans le cpp:D:\C++\projects\Servers\Master\PacketHandler\UnknownPacketHandler.cpp|3|error: too few template-parameter-lists|
Merci d'avance!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2unordered_map<short, UnknownPacketHandler::handlerf> Handler<UnknownPacketHandler>::handlers;
nico
Partager