Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / mojo / public / bindings / remote_ptr.h
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MOJO_PUBLIC_BINDINGS_REMOTE_PTR_H_
6 #define MOJO_PUBLIC_BINDINGS_REMOTE_PTR_H_
7
8 #include <assert.h>
9
10 #include "mojo/public/bindings/interface.h"
11 #include "mojo/public/bindings/lib/connector.h"
12 #include "mojo/public/system/macros.h"
13
14 namespace mojo {
15
16 // A RemotePtr is a smart-pointer for managing the connection of a message pipe
17 // to an interface proxy.
18 //
19 // EXAMPLE:
20 //
21 // Given foo.mojom containing the following interfaces:
22 //
23 //   [Peer=FooClient]
24 //   interface Foo {
25 //     void Ping();
26 //   };
27 //
28 //   [Peer=Foo]
29 //   interface FooClient {
30 //     void Pong();
31 //   };
32 //
33 // On the client side of a service, RemotePtr might be used like so:
34 //
35 //   class FooClientImpl : public FooClient {
36 //    public:
37 //     explicit FooClientImpl(ScopedFooHandle handle)
38 //         : foo_(handle.Pass(), this) {
39 //       foo_.Ping();
40 //     }
41 //     virtual void Pong() {
42 //       ...
43 //     }
44 //    private:
45 //     mojo::RemotePtr<Foo> foo_;
46 //   };
47 //
48 // On the implementation side of a service, RemotePtr might be used like so:
49 //
50 //   class FooImpl : public Foo {
51 //    public:
52 //     explicit FooImpl(ScopedFooClientHandle handle)
53 //         : client_(handle.Pass(), this) {
54 //     }
55 //     virtual void Ping() {
56 //       client_->Pong();
57 //     }
58 //    private:
59 //     mojo::RemotePtr<FooClient> client_;
60 //   };
61 //
62 // NOTE:
63 //
64 // 1- It is valid to pass NULL for the peer if you are not interested in
65 //    receiving incoming messages. Those messages will still be consumed.
66 //
67 // 2- You may optionally register an ErrorHandler on the RemotePtr to be
68 //    notified if the peer has gone away. Alternatively, you may poll the
69 //    |encountered_error()| method to check if the peer has gone away.
70 //
71 template <typename S>
72 class RemotePtr {
73   struct State;
74   MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(RemotePtr, RValue);
75
76  public:
77   RemotePtr() : state_(NULL) {}
78   explicit RemotePtr(typename Interface<S>::ScopedHandle interface_handle,
79                      typename S::_Peer* peer = NULL,
80                      ErrorHandler* error_handler = NULL,
81                      MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter())
82       : state_(new State(ScopedMessagePipeHandle(interface_handle.Pass()), peer,
83                          error_handler, waiter)) {
84   }
85
86   // Move-only constructor and operator=.
87   RemotePtr(RValue other) : state_(other.object->release()) {}
88   RemotePtr& operator=(RValue other) {
89     state_ = other.object->release();
90     return *this;
91   }
92
93   ~RemotePtr() {
94     delete state_;
95   }
96
97   bool is_null() const {
98     return !state_;
99   }
100
101   S* get() {
102     assert(state_);
103     return &state_->proxy;
104   }
105
106   S* operator->() {
107     return get();
108   }
109
110   void reset() {
111     delete state_;
112     state_ = NULL;
113   }
114
115   void reset(typename Interface<S>::ScopedHandle interface_handle,
116              typename S::_Peer* peer = NULL,
117              ErrorHandler* error_handler = NULL,
118              MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()) {
119     delete state_;
120     state_ = new State(ScopedMessagePipeHandle(interface_handle.Pass()), peer,
121                        error_handler, waiter);
122   }
123
124   bool encountered_error() const {
125     assert(state_);
126     return state_->connector.encountered_error();
127   }
128
129  private:
130   struct State {
131     State(ScopedMessagePipeHandle message_pipe, typename S::_Peer* peer,
132           ErrorHandler* error_handler, MojoAsyncWaiter* waiter)
133         : connector(message_pipe.Pass(), waiter),
134           proxy(&connector),
135           stub(peer) {
136       connector.set_error_handler(error_handler);
137       if (peer)
138         connector.set_incoming_receiver(&stub);
139     }
140     internal::Connector connector;
141     typename S::_Proxy proxy;
142     typename S::_Peer::_Stub stub;
143   };
144
145   State* release() {
146     State* state = state_;
147     state_ = NULL;
148     return state;
149   }
150
151   State* state_;
152 };
153
154 }  // namespace mojo
155
156 #endif  // MOJO_PUBLIC_BINDINGS_REMOTE_PTR_H_