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_LIB_REMOTE_PTR_H_ 6 #define MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_ 7 8 #include <assert.h> 9 10 #include "mojo/public/bindings/lib/connector.h" 11 #include "mojo/public/system/macros.h" 12 13 namespace mojo { 14 15 // A RemotePtr is a smart-pointer for managing the connection of a message pipe 16 // to an interface proxy. 17 // 18 // EXAMPLE 19 // 20 // On the client side of a service, RemotePtr might be used like so: 21 // 22 // class FooClientImpl : public FooClientStub { 23 // public: 24 // explicit FooClientImpl(const mojo::MessagePipeHandle& message_pipe) 25 // : foo_(message_pipe) { 26 // foo_.SetPeer(this); 27 // foo_.Ping(); 28 // } 29 // virtual void Pong() { 30 // ... 31 // } 32 // private: 33 // mojo::RemotePtr<Foo> foo_; 34 // }; 35 // 36 // On the implementation side of a service, RemotePtr might be used like so: 37 // 38 // class FooImpl : public FooStub { 39 // public: 40 // explicit FooImpl(const mojo::MessagePipeHandle& message_pipe) 41 // : client_(message_pipe) { 42 // client_.SetPeer(this); 43 // } 44 // virtual void Ping() { 45 // client_->Pong(); 46 // } 47 // private: 48 // mojo::RemotePtr<FooClient> client_; 49 // }; 50 // 51 template <typename S> 52 class RemotePtr { 53 MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(RemotePtr, RValue); 54 55 public: 56 RemotePtr() : state_(NULL) {} 57 explicit RemotePtr(ScopedMessagePipeHandle message_pipe) 58 : state_(new State(message_pipe.Pass())) { 59 } 60 61 // Move-only constructor and operator=. 62 RemotePtr(RValue other) : state_(other.object->release()) {} 63 RemotePtr& operator=(RValue other) { 64 state_ = other.object->release(); 65 return *this; 66 } 67 68 ~RemotePtr() { 69 delete state_; 70 } 71 72 bool is_null() const { 73 return !state_; 74 } 75 76 S* get() { 77 assert(state_); 78 return &state_->proxy; 79 } 80 81 S* operator->() { 82 return get(); 83 } 84 85 void reset() { 86 delete state_; 87 state_ = NULL; 88 } 89 90 void reset(ScopedMessagePipeHandle message_pipe) { 91 delete state_; 92 state_ = new State(message_pipe.Pass()); 93 } 94 95 bool encountered_error() const { 96 assert(state_); 97 return state_->connector.encountered_error(); 98 } 99 100 void SetPeer(typename S::_Peer::_Stub* peer) { 101 assert(state_); 102 state_->connector.SetIncomingReceiver(peer); 103 } 104 105 private: 106 struct State { 107 State(ScopedMessagePipeHandle message_pipe) 108 : connector(message_pipe.Pass()), 109 proxy(&connector) { 110 } 111 internal::Connector connector; 112 typename S::_Proxy proxy; 113 }; 114 115 State* release() { 116 State* state = state_; 117 state_ = NULL; 118 return state; 119 } 120 121 State* state_; 122 }; 123 124 } // namespace mojo 125 126 #endif // MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_ 127