Index: ipc/ipc_message_templates.h |
diff --git a/ipc/ipc_message_templates.h b/ipc/ipc_message_templates.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..caf9cfc46bfb432de289685ea72ad2d721a8560a |
--- /dev/null |
+++ b/ipc/ipc_message_templates.h |
@@ -0,0 +1,199 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef IPC_IPC_MESSAGE_TEMPLATES_H_ |
+#define IPC_IPC_MESSAGE_TEMPLATES_H_ |
+ |
+#include <stdint.h> |
+ |
+#include <type_traits> |
+ |
+#include "base/tuple.h" |
+#include "ipc/ipc_message.h" |
+#include "ipc/ipc_message_utils.h" |
+ |
+namespace IPC { |
+ |
+// This function is for all the async IPCs that don't pass an extra parameter |
+// using IPC_BEGIN_MESSAGE_MAP_WITH_PARAM. |
+template <typename ObjT, typename Method, typename P, typename Tuple> |
+void DispatchToMethod(ObjT* obj, Method method, P*, const Tuple& tuple) { |
+ base::DispatchToMethod(obj, method, tuple); |
+} |
+ |
+template <typename ObjT, |
+ typename Method, |
+ typename P, |
+ typename Tuple, |
+ size_t... Ns> |
+void DispatchToMethodImpl(ObjT* obj, |
+ Method method, |
+ P* parameter, |
+ const Tuple& tuple, |
+ base::IndexSequence<Ns...>) { |
+ // TODO(mdempsky): Apply UnwrapTraits like base::DispatchToMethod? |
+ (obj->*method)(parameter, base::get<Ns>(tuple)...); |
+} |
+ |
+// The following function is for async IPCs which have a dispatcher with an |
+// extra parameter specified using IPC_BEGIN_MESSAGE_MAP_WITH_PARAM. |
+template <typename ObjT, typename P, typename... Args, typename... Ts> |
+typename std::enable_if<sizeof...(Args) == sizeof...(Ts)>::type |
+DispatchToMethod(ObjT* obj, |
+ void (ObjT::*method)(P*, Args...), |
+ P* parameter, |
+ const base::Tuple<Ts...>& tuple) { |
+ DispatchToMethodImpl(obj, method, parameter, tuple, |
+ base::MakeIndexSequence<sizeof...(Ts)>()); |
+} |
+ |
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple> |
+class CommonAsyncMessage; |
+ |
+template <uint32_t Id, const char* Name, typename... Ins> |
danakj
2015/12/19 00:15:06
There's a real lack of comments in here to explain
mdempsky
2015/12/19 02:14:48
I'll add some. (To be fair, I preserved *both* of
|
+class CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>> |
+ : public Message { |
+ public: |
+ using Schema = MessageSchema<base::Tuple<Ins...>>; |
+ using Param = typename Schema::Param; |
+ enum { ID = Id }; |
+ |
+ CommonAsyncMessage(int32_t routing_id, const Ins&... ins); |
+ |
+ static bool Read(const Message* msg, Param* p); |
+ static void Log(std::string* name, const Message* msg, std::string* l); |
+ |
+ template <class T, class S, class P, class Method> |
+ static bool Dispatch(const Message* msg, |
+ T* obj, |
+ S* sender, |
+ P* parameter, |
+ Method func) { |
+ Param p; |
+ if (Read(msg, &p)) { |
+ DispatchToMethod(obj, func, parameter, p); |
+ return true; |
+ } |
+ return false; |
+ } |
+}; |
+ |
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple> |
+class CommonSyncMessage; |
+ |
+template <uint32_t Id, const char* Name, typename... Ins, typename... Outs> |
+class CommonSyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>> |
+ : public SyncMessage { |
+ public: |
+ using Schema = SyncMessageSchema< |
+ base::Tuple<Ins...>, |
+ typename base::TupleTypes<base::Tuple<Outs...>>::RefTuple>; |
+ using ReplyParam = typename Schema::ReplyParam; |
+ using SendParam = typename Schema::SendParam; |
+ enum { ID = Id }; |
+ |
+ CommonSyncMessage(int32_t routing_id, const Ins&... ins, Outs*... outs); |
+ |
+ static bool ReadSendParam(const Message* msg, SendParam* p); |
+ static bool ReadReplyParam( |
+ const Message* msg, |
+ typename base::TupleTypes<ReplyParam>::ValueTuple* p); |
+ static void Log(std::string* name, const Message* msg, std::string* l); |
+ |
+ template <class T, class S, class P, class Method> |
+ static bool Dispatch(const Message* msg, |
+ T* obj, |
+ S* sender, |
+ P* parameter, |
+ Method func) { |
+ SendParam send_params; |
+ bool ok = ReadSendParam(msg, &send_params); |
+ return Schema::DispatchWithSendParams(ok, send_params, msg, obj, sender, |
+ func); |
+ } |
+ |
+ template <class T, class P, class Method> |
+ static bool DispatchDelayReply(const Message* msg, |
+ T* obj, |
+ P* parameter, |
+ Method func) { |
+ SendParam send_params; |
+ bool ok = ReadSendParam(msg, &send_params); |
+ return Schema::DispatchDelayReplyWithSendParams(ok, send_params, msg, obj, |
+ func); |
+ } |
+ |
+ template <typename... Args> |
+ static void WriteReplyParams(Message* reply, Args... args) { |
+ Schema::WriteReplyParams(reply, args...); |
+ } |
+}; |
+ |
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple> |
+class AsyncControlMessage; |
+ |
+template <uint32_t Id, const char* Name, typename... Ins> |
+class AsyncControlMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>> |
+ : public CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>> { |
+ public: |
+ AsyncControlMessage(const Ins&... ins) |
+ : CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>>( |
+ MSG_ROUTING_CONTROL, |
+ ins...) {} |
+}; |
+ |
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple> |
+class AsyncRoutedMessage; |
+ |
+template <uint32_t Id, const char* Name, typename... Ins> |
+class AsyncRoutedMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>> |
+ : public CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>> { |
+ public: |
+ AsyncRoutedMessage(int32_t routing_id, const Ins&... ins) |
+ : CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>>( |
+ routing_id, |
+ ins...) {} |
+}; |
+ |
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple> |
+class SyncControlMessage; |
+ |
+template <uint32_t Id, const char* Name, typename... Ins, typename... Outs> |
+class SyncControlMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>> |
+ : public CommonSyncMessage<Id, |
+ Name, |
+ base::Tuple<Ins...>, |
+ base::Tuple<Outs...>> { |
+ public: |
+ SyncControlMessage(const Ins&... ins, Outs*... outs) |
+ : CommonSyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>>( |
+ MSG_ROUTING_CONTROL, |
+ ins..., |
+ outs...) {} |
+}; |
+ |
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple> |
+class SyncRoutedMessage; |
+ |
+template <uint32_t Id, const char* Name, typename... Ins, typename... Outs> |
+class SyncRoutedMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>> |
+ : public CommonSyncMessage<Id, |
+ Name, |
+ base::Tuple<Ins...>, |
+ base::Tuple<Outs...>> { |
+ public: |
+ SyncRoutedMessage(int32_t routing_id, const Ins&... ins, Outs*... outs) |
+ : CommonSyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>>( |
+ routing_id, |
+ ins..., |
+ outs...) {} |
+}; |
+ |
+} // namespace IPC |
+ |
+#if defined(IPC_MESSAGE_IMPL) |
+#include "ipc/ipc_message_templates_impl.h" |
+#endif |
+ |
+#endif // IPC_IPC_MESSAGE_TEMPLATES_H_ |