Last active
December 14, 2015 01:08
-
-
Save kyle-go/5003400 to your computer and use it in GitHub Desktop.
dispatch message. copy from https://github.com/chenshuo/recipes/blob/master/protobuf/dispatcher.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
dispatch message. | |
copy from https://github.com/chenshuo/recipes/blob/master/protobuf/dispatcher.cc | |
*/ | |
#include <map> | |
#include <assert.h> | |
#include <iostream> | |
#include <functional> | |
class Message | |
{ | |
public: | |
virtual int GetDescriptor() | |
{ | |
//0 for default message. | |
return 0; | |
} | |
}; | |
class Callback | |
{ | |
public: | |
virtual ~Callback() {} | |
virtual void onMessage(Message* message) const = 0; | |
}; | |
template <typename T> | |
class CallbackT : public Callback | |
{ | |
public: | |
typedef std::function<void (T* message)> MessageCallback; | |
CallbackT(const MessageCallback& callback) | |
: callback_(callback) | |
{} | |
virtual void onMessage(Message* message) const | |
{ | |
T* t = static_cast<T*>(message); | |
assert(t); | |
callback_(t); | |
} | |
private: | |
MessageCallback callback_; | |
}; | |
void discardMessage(Message* message) | |
{ | |
std::cout << "Discarding " << message->GetDescriptor() << std::endl; | |
} | |
class Dispatcher | |
{ | |
public: | |
Dispatcher() | |
: defaultCallback_(discardMessage) | |
{} | |
void onMessage(Message* message) const | |
{ | |
CallbackMap::const_iterator it = callbacks_.find(message->GetDescriptor()); | |
if (it != callbacks_.end()) { | |
it->second->onMessage(message); | |
} else { | |
defaultCallback_(message); | |
} | |
} | |
template<typename T> | |
void registerMessageCallback(const typename CallbackT<T>::MessageCallback& callback) | |
{ | |
typename std::shared_ptr<CallbackT<T>> pd(new CallbackT<T>(callback)); | |
//T must support no param constructor. | |
callbacks_[T().GetDescriptor()] = pd; | |
} | |
typedef std::map<int, std::shared_ptr<Callback>> CallbackMap; | |
CallbackMap callbacks_; | |
std::function<void (Message* message)> defaultCallback_; | |
}; | |
// | |
// test | |
// | |
class Query : public Message | |
{ | |
public: | |
virtual int GetDescriptor() | |
{ | |
//1 for query messager | |
return 1; | |
} | |
//some data | |
char x_; | |
}; | |
class Answer : public Message | |
{ | |
public: | |
virtual int GetDescriptor() | |
{ | |
//2 for answer messager | |
return 2; | |
} | |
//some data | |
char x_; | |
}; | |
void onQuery(Query* query) | |
{ | |
std::cout << "onQuery: " << query->GetDescriptor() << std::endl; | |
} | |
void onAnswer(Answer* answer) | |
{ | |
std::cout << "onAnswer: " << answer->GetDescriptor() << std::endl; | |
} | |
int main() | |
{ | |
Dispatcher dispatcher; | |
dispatcher.registerMessageCallback<Query>(onQuery); | |
dispatcher.registerMessageCallback<Answer>(onAnswer); | |
Query q; | |
Answer a; | |
Message m; | |
dispatcher.onMessage(&q); | |
dispatcher.onMessage(&a); | |
dispatcher.onMessage(&m); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment