Chromium Code Reviews| 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_ |