From: <Ven...@us...> - 2008-11-22 17:21:27
|
Revision: 2470 http://planeshift.svn.sourceforge.net/planeshift/?rev=2470&view=rev Author: Vengeance2001 Date: 2008-11-22 17:21:24 +0000 (Sat, 22 Nov 2008) Log Message: ----------- Added functor templates for net message callback support. This is how ALL net msgtype subscriptions should be done in the future. I will work on backporting the existing ones over the next day or so. See authentserver for an example of how the subscriptions are done now. Modified Paths: -------------- trunk/src/common/net/msghandler.cpp trunk/src/common/net/msghandler.h trunk/src/server/authentserver.cpp trunk/src/server/authentserver.h Modified: trunk/src/common/net/msghandler.cpp =================================================================== --- trunk/src/common/net/msghandler.cpp 2008-11-22 16:10:24 UTC (rev 2469) +++ trunk/src/common/net/msghandler.cpp 2008-11-22 17:21:24 UTC (rev 2470) @@ -67,7 +67,12 @@ Client *client; me->Reset(); if (subscribers[mtype][x]->subscriber->Verify(me,subscribers[mtype][x]->flags,client)) - subscribers[mtype][x]->subscriber->HandleMessage(me,client); + { + if (subscribers[mtype][x]->callback) + subscribers[mtype][x]->callback->Call(me,client); + else + subscribers[mtype][x]->subscriber->HandleMessage(me,client); + } handled = true; } @@ -83,6 +88,7 @@ Subscription* p = new Subscription; p->subscriber = subscriber; + p->callback = NULL; p->type = type; p->flags = flags; @@ -95,6 +101,28 @@ return true; } +bool MsgHandler::Subscribe(iNetSubscriber *subscriber, MsgtypeCallback *callback, msgtype type,uint32_t flags) +{ + Subscription* p = new Subscription; + + p->subscriber = subscriber; + p->callback = callback; + p->type = type; + p->flags = flags; + + CS::Threading::RecursiveMutexScopedLock lock(mutex); + if ( IsSubscribed(p) ) + { + if (p->callback) + delete p->callback; + delete p; + } + else + subscribers[type].Push(p); + + return true; +} + bool MsgHandler::Unsubscribe(iNetSubscriber *subscriber, msgtype type) { CS::Threading::RecursiveMutexScopedLock lock(mutex); Modified: trunk/src/common/net/msghandler.h =================================================================== --- trunk/src/common/net/msghandler.h 2008-11-22 16:10:24 UTC (rev 2469) +++ trunk/src/common/net/msghandler.h 2008-11-22 17:21:24 UTC (rev 2470) @@ -29,10 +29,51 @@ // forward decls struct iNetSubscriber; class NetBase; +class Client; #define MAX_MESSAGE_TYPES 255 // MSGTYPE enumeration in messages.h has less types than this -// This little struct tracks who is interested in what. +/// Functor base class for direct callbacks on Subscriptions +class MsgtypeCallback +{ +public: + virtual void operator()(MsgEntry *message, Client *client) = 0; // call using operator + virtual void Call(MsgEntry *message, Client *client) = 0; // call using function +}; + +template <class Manager> +class NetMessageCallback : public MsgtypeCallback +{ + private: + void (Manager::*funcptr)(MsgEntry *message, Client *client); // pointer to member function + Manager *thisPtr; // pointer to object + + public: + + // constructor - takes pointer to an object and pointer to a member and stores + // them in two private variables + NetMessageCallback(Manager *myObject, void(Manager::*fpt)(MsgEntry *message, Client *client)) + { + thisPtr = myObject; + funcptr = fpt; + } + + // override operator "()" + virtual void operator()(MsgEntry *message, Client *client) + { + (*thisPtr.*funcptr)(message,client); + } + + // override function "Call" + virtual void Call(MsgEntry *message, Client *client) + { + (*thisPtr.*funcptr)(message,client); + } +}; + + + +/// This little struct tracks who is interested in what. struct Subscription { /// type of the messages this listener listens to @@ -43,11 +84,13 @@ /// pointer to the subscriber iNetSubscriber *subscriber; + + /// pointer to functor class callback as alternative to iNetSubscriber + MsgtypeCallback *callback; }; -/** - * This class handles the incoming network packets - */ + +/// This class handles the incoming network packets class MsgHandler : public csRefCount { public: @@ -61,6 +104,7 @@ * with this function */ virtual bool Subscribe(iNetSubscriber *subscriber, msgtype type, uint32_t flags=0); + virtual bool Subscribe(iNetSubscriber *subscriber, MsgtypeCallback *callback, msgtype type, uint32_t flags=0); /// Remove subscriber from list virtual bool Unsubscribe(iNetSubscriber *subscriber, msgtype type); Modified: trunk/src/server/authentserver.cpp =================================================================== --- trunk/src/server/authentserver.cpp 2008-11-22 16:10:24 UTC (rev 2469) +++ trunk/src/server/authentserver.cpp 2008-11-22 17:21:24 UTC (rev 2470) @@ -82,13 +82,11 @@ guildmanager = gm; msgstringsmessage = NULL; - psserver->GetEventManager()->Subscribe(this,MSGTYPE_PREAUTHENTICATE,REQUIRE_ANY_CLIENT); - psserver->GetEventManager()->Subscribe(this,MSGTYPE_AUTHENTICATE,REQUIRE_ANY_CLIENT); - psserver->GetEventManager()->Subscribe(this,MSGTYPE_DISCONNECT,REQUIRE_ANY_CLIENT); - psserver->GetEventManager()->Subscribe(this,MSGTYPE_AUTHCHARACTER,REQUIRE_ANY_CLIENT); - psserver->GetEventManager()->Subscribe(this,MSGTYPE_SYSTEM,REQUIRE_ANY_CLIENT); // Handle the heartbeat from the client - psserver->GetEventManager()->Subscribe(this,MSGTYPE_CLIENTSTATUS,REQUIRE_ANY_CLIENT); // Handle the heartbeat from the client - psserver->GetEventManager()->Subscribe(this,MSGTYPE_HEART_BEAT,REQUIRE_ANY_CLIENT); // Handle the heartbeat from the client + psserver->GetEventManager()->Subscribe(this,new NetMessageCallback<psAuthenticationServer>(this,&psAuthenticationServer::HandlePreAuthent),MSGTYPE_PREAUTHENTICATE,REQUIRE_ANY_CLIENT); + psserver->GetEventManager()->Subscribe(this,new NetMessageCallback<psAuthenticationServer>(this,&psAuthenticationServer::HandleAuthent),MSGTYPE_AUTHENTICATE,REQUIRE_ANY_CLIENT); + psserver->GetEventManager()->Subscribe(this,new NetMessageCallback<psAuthenticationServer>(this,&psAuthenticationServer::HandleDisconnect),MSGTYPE_DISCONNECT,REQUIRE_ANY_CLIENT); + psserver->GetEventManager()->Subscribe(this,new NetMessageCallback<psAuthenticationServer>(this,&psAuthenticationServer::HandleAuthCharacter),MSGTYPE_AUTHCHARACTER,REQUIRE_ANY_CLIENT); + psserver->GetEventManager()->Subscribe(this,new NetMessageCallback<psAuthenticationServer>(this,&psAuthenticationServer::HandleStatusUpdate),MSGTYPE_CLIENTSTATUS,REQUIRE_ANY_CLIENT); } psAuthenticationServer::~psAuthenticationServer() @@ -99,7 +97,6 @@ psserver->GetEventManager()->Unsubscribe(this,MSGTYPE_AUTHENTICATE); psserver->GetEventManager()->Unsubscribe(this,MSGTYPE_DISCONNECT); psserver->GetEventManager()->Unsubscribe(this,MSGTYPE_AUTHCHARACTER); - psserver->GetEventManager()->Unsubscribe(this,MSGTYPE_SYSTEM); psserver->GetEventManager()->Unsubscribe(this,MSGTYPE_CLIENTSTATUS); } if (msgstringsmessage) @@ -108,45 +105,11 @@ void psAuthenticationServer::HandleMessage(MsgEntry *me,Client *client) { - if (me == NULL) - { - Bug1("No Message Entity Found"); - return; - } - - switch (me->GetType()) - { - case MSGTYPE_AUTHCHARACTER: - HandleAuthCharacter( me ); - break; - - case MSGTYPE_AUTHENTICATE: - HandleAuthent(me); - break; - - case MSGTYPE_PREAUTHENTICATE: - HandlePreAuthent(me); - break; - - case MSGTYPE_DISCONNECT: - HandleDisconnect(me, "Your client has disconnected. If you are seeing this message a connection error has likely occurred."); - break; - - case MSGTYPE_CLIENTSTATUS: - HandleStatusUpdate(me, client); - break; - } + // required for backward compatibility with pre-functor days but not used here } -void psAuthenticationServer::HandleAuthCharacter( MsgEntry* me ) +void psAuthenticationServer::HandleAuthCharacter( MsgEntry* me, Client *client ) { - Client *client = clients->FindAny(me->clientnum); - if (!client) - { - Bug2("Couldn't find client %d?!?",me->clientnum); - return; - } - psCharacterPickerMessage charpick( me ); if (!charpick.valid) { @@ -230,7 +193,7 @@ } -void psAuthenticationServer::HandlePreAuthent(MsgEntry *me) +void psAuthenticationServer::HandlePreAuthent(MsgEntry *me, Client *notused) { psPreAuthenticationMessage msg(me); if (!msg.valid) @@ -246,7 +209,7 @@ reply.SendMessage(); } -void psAuthenticationServer::HandleAuthent(MsgEntry *me) +void psAuthenticationServer::HandleAuthent(MsgEntry *me, Client *notused) { csTicks start = csGetTicks(); @@ -539,11 +502,9 @@ psserver->GetLogCSV()->Write(CSV_AUTHENT, status); } -void psAuthenticationServer::HandleDisconnect(MsgEntry* me,const char *msg) +void psAuthenticationServer::HandleDisconnect(MsgEntry* me,Client *client) { psDisconnectMessage mesg(me); - - Client *client = clients->FindAny(me->clientnum); // Check if this client is allowed to disconnect or if the // zombie state should be set @@ -556,7 +517,7 @@ } else { - psserver->RemovePlayer(me->clientnum,msg); + psserver->RemovePlayer(me->clientnum,"Your client has disconnected. If you are seeing this message a connection error has likely occurred."); } } Modified: trunk/src/server/authentserver.h =================================================================== --- trunk/src/server/authentserver.h 2008-11-22 16:10:24 UTC (rev 2469) +++ trunk/src/server/authentserver.h 2008-11-22 17:21:24 UTC (rev 2470) @@ -171,10 +171,10 @@ * @param me: Is a message entry that contains the authenticate message. * @see psAuthMessageApproved */ - void HandleAuthent(MsgEntry *me); + void HandleAuthent(MsgEntry *me, Client *notused); /* This just questsions a random number (clientnum) from server * It is used for authenticating*/ - void HandlePreAuthent(MsgEntry *me); + void HandlePreAuthent(MsgEntry *me, Client *notused); /** Handles a disconnect message from the message queue. * This will remove the player from the server using @@ -183,12 +183,12 @@ * @param me: Is the disconnect message that was recieved. * @param msg: Is the reason for the disconnect. */ - void HandleDisconnect(MsgEntry* me,const char *msg); + void HandleDisconnect(MsgEntry* me,Client *notused); /** Handles a message where a client picks his character to play with. * Can remove the player using psServer::RemovePlayer if invalid. */ - void HandleAuthCharacter(MsgEntry* me); + void HandleAuthCharacter(MsgEntry* me, Client *notused); }; #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |