summaryrefslogtreecommitdiffstats
path: root/chrome_frame/sync_msg_reply_dispatcher.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome_frame/sync_msg_reply_dispatcher.h')
-rw-r--r--chrome_frame/sync_msg_reply_dispatcher.h72
1 files changed, 47 insertions, 25 deletions
diff --git a/chrome_frame/sync_msg_reply_dispatcher.h b/chrome_frame/sync_msg_reply_dispatcher.h
index 724c007..7d47bd1 100644
--- a/chrome_frame/sync_msg_reply_dispatcher.h
+++ b/chrome_frame/sync_msg_reply_dispatcher.h
@@ -23,14 +23,22 @@
// cases where you care about the return values of synchronous messages.
//
// Sample usage pattern:
+// Define a class which inherits from SyncMessageCallContext which specifies
+// the output_type tuple and has a Completed member function.
+// class SampleContext
+// : public SyncMessageReplyDispatcher::SyncMessageCallContext {
+// public:
+// typedef Tuple1<int> output_type;
+// void Completed(int arg) {}
+// };
//
// // Add handling for desired message types.
// class SyncMessageReplyDispatcherImpl : public SyncMessageReplyDispatcher {
// virtual bool HandleMessageType(const IPC::Message& msg,
-// const MessageSent& origin) {
-// switch (origin.type) {
+// SyncMessageReplyDispatcher* context) {
+// switch (context->message_type()) {
// case AutomationMsg_CreateExternalTab::ID:
-// InvokeCallback<Tuple3<HWND, HWND, int> >(msg, origin);
+// InvokeCallback<CreateExternalTabContext>(msg, context);
// break;
// [HANDLING FOR OTHER EXPECTED MESSAGE TYPES]
// }
@@ -40,29 +48,42 @@
// IPC::SyncChannel channel_;
// channel_.AddFilter(new SyncMessageReplyDispatcherImpl());
//
-// sync_->Push(msg, NewCallback(this, CallbackMethod, this);
+// sync_->Push(msg, new SampleContext, this);
// channel_->ChannelProxy::Send(msg);
//
class SyncMessageReplyDispatcher : public IPC::ChannelProxy::MessageFilter {
public:
+ class SyncMessageCallContext {
+ public:
+ SyncMessageCallContext()
+ : id_(0),
+ message_type_(0),
+ key_(NULL) {}
+
+ virtual ~SyncMessageCallContext() {}
+
+ uint32 message_type() const {
+ return message_type_;
+ }
+
+ private:
+ int id_;
+ uint32 message_type_;
+ void* key_;
+
+ friend class SyncMessageReplyDispatcher;
+ };
+
SyncMessageReplyDispatcher() {}
- void Push(IPC::SyncMessage* msg, void* callback, void* key);
+ void Push(IPC::SyncMessage* msg, SyncMessageCallContext* context,
+ void* key);
void Cancel(void* key);
protected:
- struct MessageSent {
- MessageSent() {}
- MessageSent(int id, uint32 type, void* callback, void* key)
- : id(id), callback(callback), type(type), key(key) {}
- int id;
- void* callback;
- void* key;
- uint32 type;
- };
+ typedef std::deque<SyncMessageCallContext*> PendingSyncMessageQueue;
- typedef std::deque<MessageSent> PendingSyncMessageQueue;
+ SyncMessageCallContext* GetContext(const IPC::Message& msg);
- bool Pop(const IPC::Message& msg, MessageSent* t);
virtual bool OnMessageReceived(const IPC::Message& msg);
// Child classes must implement a handler for the message types they are
@@ -70,21 +91,22 @@ class SyncMessageReplyDispatcher : public IPC::ChannelProxy::MessageFilter {
// to any of the sync messages you are handling, then you don't have to
// implement this.
virtual bool HandleMessageType(const IPC::Message& msg,
- const MessageSent& origin);
+ SyncMessageCallContext* context);
template <typename T>
- void InvokeCallback(const IPC::Message& msg, const MessageSent& origin) {
- // Ensure we delete the callback
- scoped_ptr<CallbackRunner<T> > c(
- reinterpret_cast<CallbackRunner<T>*>(origin.callback));
- if (origin.key == NULL) { // Canceled
+ void InvokeCallback(const IPC::Message& msg,
+ SyncMessageCallContext* call_context) {
+ if (!call_context || !call_context->key_) {
+ NOTREACHED() << "Invalid context parameter";
return;
}
- T tmp; // Acts as "initializer" for output parameters.
- IPC::ParamDeserializer<T> deserializer(tmp);
+ T* context = static_cast<T*>(call_context);
+ T::output_type tmp; // Acts as "initializer" for output parameters.
+ IPC::ParamDeserializer<T::output_type> deserializer(tmp);
if (deserializer.MessageReplyDeserializer::SerializeOutputParameters(msg)) {
- c->RunWithParams(deserializer.out_);
+ DispatchToMethod(context, &T::Completed, deserializer.out_);
+ delete context;
} else {
// TODO(stoyan): How to handle errors?
}