| 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 |