OLD | NEW |
| (Empty) |
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/router.h" | |
12 #include "mojo/public/cpp/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, | |
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, | |
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_->router.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 : router(message_pipe.Pass(), waiter), | |
134 proxy(&router), | |
135 stub(peer) { | |
136 router.set_error_handler(error_handler); | |
137 if (peer) | |
138 router.set_incoming_receiver(&stub); | |
139 } | |
140 internal::Router router; | |
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_ | |
OLD | NEW |