xardias JLI Master
Alter: 38 Anmeldedatum: 28.12.2003 Beiträge: 804 Wohnort: Palo Alto, CA Medaillen: Keine
|
Verfasst am: 13.04.2005, 20:28 Titel: Templatisierte Listener - oder: fucking call it! |
|
|
Das Problem:
Vor allem im Netzwerkbereich wären Listener praktisch, die per Template ihre parameter ändern können:
Code: |
template<class T> struct PacketListener
{
virtual void processPacket( T* packet );
} |
Alles schön und gut, doch lassen sich diese Listener nicht verwenden, wenn man sie als PacketListener* in einer map, einem array oder sonstwas speichert. Die processPacket funktion lässt sich aus gutem Grund nicht aufrufen.
Lösung:
Hazel und ich haben dann zusmamen folgende Lösung gebastelt:
Code: | template<class T> class NetworkListenerBase
{
public:
virtual void onPacket( T* packet ) = 0;
};
class NetworkListenerHelper
{
public:
virtual void callListener( Packet* p ) = 0;
};
template<class T> class NetworkListener: public NetworkListenerBase<T>, public NetworkListenerHelper
{
void callListener( Packet* p )
{
this->onPacket( (T*) p->data );
}
}; |
So lassen sich zeiger auf NetworkListenerHelper speichern und aufrufen.
Ein beispiel:
Code: | class NetworkManager
{
private:
std::map<unsigned int, NetworkListenerHelper*> listener;
public:
template<class T> void addListener( T* listener )
{
this->listener[T::packetId] = static_cast<NetworkListenerHelper*> listener;
}
void dispatchPacket( const unsigned char& id, Packet* packet )
{
if( listener.find(id) != listener.end() )
{
listener[id]->callListener( packet );
}
}
}; |
Kritik erwünscht
hazel und xardias
PS: Kann das jemand ins FAQ forum verschieben?
[Edit]
Hazel: Ich hab es in Entwicklung geschoben, weil im FAQ Forum Feedback untersagt ist, soweit ich weiß. |
|