1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#ifndef MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/public/cpp/bindings/interface_ptr.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace mojo {
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Used in methods that return instances of remote objects.
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename Interface>
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class InterfaceRequest {
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfaceRequest, RValue)
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InterfaceRequest() {}
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InterfaceRequest(RValue other) {
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    handle_ = other.object->handle_.Pass();
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InterfaceRequest& operator=(RValue other) {
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    handle_ = other.object->handle_.Pass();
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return *this;
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns true if the request has yet to be completed.
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool is_pending() const { return handle_.is_valid(); }
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void Bind(ScopedMessagePipeHandle handle) {
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    handle_ = handle.Pass();
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedMessagePipeHandle PassMessagePipe() {
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return handle_.Pass();
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedMessagePipeHandle handle_;
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename Interface>
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)InterfaceRequest<Interface> MakeRequest(ScopedMessagePipeHandle handle) {
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InterfaceRequest<Interface> request;
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  request.Bind(handle.Pass());
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return request.Pass();
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Used to construct a request that synchronously binds an InterfacePtr<..>,
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// making it immediately usable upon return. The resulting request object may
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// then be later bound to an InterfaceImpl<..> via BindToRequest.
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Given the following interface:
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//   interface Foo {
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//     CreateBar(Bar& bar);
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//   }
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The caller of CreateBar would have code similar to the following:
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//   InterfacePtr<Foo> foo = ...;
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//   InterfacePtr<Bar> bar;
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//   foo->CreateBar(Get(&bar));
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Upon return from CreateBar, |bar| is ready to have methods called on it.
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename Interface>
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)InterfaceRequest<Interface> Get(InterfacePtr<Interface>* ptr) {
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MessagePipe pipe;
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ptr->Bind(pipe.handle0.Pass());
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return MakeRequest<Interface>(pipe.handle1.Pass());
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace mojo
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_
77