chromium/ppapi/proxy/dispatch_reply_message.h

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file provides infrastructure for dispatching messasges from host
// resource, inlcuding reply messages or unsolicited replies. Normal IPC Reply
// handlers can't take extra parameters. We want to take a
// ResourceMessageReplyParams as a parameter.

#ifndef PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_
#define PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_

#include <tuple>
#include <utility>

#include "base/functional/callback.h"
#include "base/notreached.h"
#include "base/tuple.h"
#include "ipc/ipc_message_macros.h"
#include "ppapi/c/pp_errors.h"

namespace ppapi {
namespace proxy {

class ResourceMessageReplyParams;

template <typename ObjT, typename Method, typename TupleType, size_t... indices>
inline void DispatchResourceReplyImpl(ObjT* obj,
                                      Method method,
                                      const ResourceMessageReplyParams& params,
                                      TupleType&& args_tuple,
                                      std::index_sequence<indices...>) {}

// Runs |method| on |obj| with |params| and expanded |args_tuple|.
// I.e. Followings are equivalent.
//   DispatchResourceReply(obj, &Obj::Method, params, std::tie(a, b, c));
//   obj->Method(params, a, b, c);
template <typename ObjT, typename Method, typename TupleType>
inline void DispatchResourceReply(ObjT* obj,
                                  Method method,
                                  const ResourceMessageReplyParams& params,
                                  TupleType&& args_tuple) {}

template <typename CallbackType, typename TupleType, size_t... indices>
inline void DispatchResourceReplyImpl(CallbackType&& callback,
                                      const ResourceMessageReplyParams& params,
                                      TupleType&& args_tuple,
                                      std::index_sequence<indices...>) {}

// Runs |callback| with |params| and expanded |args_tuple|.
// I.e. Followings are equivalent.
//   DispatchResourceReply(callback, params, std::tie(a, b, c));
//   callback.Run(params, a, b, c);
template <typename CallbackType, typename TupleType>
inline void DispatchResourceReply(CallbackType&& callback,
                                  const ResourceMessageReplyParams& params,
                                  TupleType&& args_tuple) {}

// Used to dispatch resource replies. In most cases, you should not call this
// function to dispatch a resource reply manually, but instead use
// |PluginResource::CallBrowser|/|PluginResource::CallRenderer| with a
// |base::OnceCallback| which will be called when a reply message is received
// (see plugin_resource.h).
//
// This function will call your callback with the nested reply message's
// parameters on success. On failure, your callback will be called with each
// parameter having its default constructed value.
//
// Resource replies are a bit weird in that the host will automatically
// generate a reply in error cases (when the call handler returns error rather
// than returning "completion pending"). This makes it more convenient to write
// the call message handlers. But this also means that the reply handler has to
// handle both the success case (when all of the reply message paramaters are
// specified) and the error case (when the nested reply message is empty).
// In both cases the resource will want to issue completion callbacks to the
// plugin.
//
// This function handles the error case by calling your reply handler with the
// default value for each paramater in the error case. In most situations this
// will be the right thing. You should always dispatch completion callbacks
// using the result code present in the ResourceMessageReplyParams.
template<class MsgClass, class ObjT, class Method>
void DispatchResourceReplyOrDefaultParams(
    ObjT* obj,
    Method method,
    const ResourceMessageReplyParams& reply_params,
    const IPC::Message& msg) {}

template <typename MsgClass, typename CallbackType>
void DispatchResourceReplyOrDefaultParams(
    CallbackType&& callback,
    const ResourceMessageReplyParams& reply_params,
    const IPC::Message& msg) {}

// When using PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL* below, use this macro to
// begin the map instead of IPC_BEGIN_MESSAGE_MAP. The reason is that the macros
// in src/ipc are all closely tied together, and there might be errors for
// unused variables or other errors if they're used with these macros.
#define PPAPI_BEGIN_MESSAGE_MAP(class_name, msg)

// Note that this only works for message with 1 or more parameters. For
// 0-parameter messages you need to use the _0 version below (since there are
// no params in the message).
#define PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(msg_class, member_func)

#define PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_0(msg_class, member_func)

#define PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(code)

#define PPAPI_END_MESSAGE_MAP()

}  // namespace proxy
}  // namespace ppapi

#endif  // PPAPI_PROXY_DISPATCH_REPLY_MESSAGE_H_