• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
RemotePtr()56   RemotePtr() : state_(NULL) {}
RemotePtr(ScopedMessagePipeHandle message_pipe)57   explicit RemotePtr(ScopedMessagePipeHandle message_pipe)
58       : state_(new State(message_pipe.Pass())) {
59   }
60 
61   // Move-only constructor and operator=.
RemotePtr(RValue other)62   RemotePtr(RValue other) : state_(other.object->release()) {}
63   RemotePtr& operator=(RValue other) {
64     state_ = other.object->release();
65     return *this;
66   }
67 
~RemotePtr()68   ~RemotePtr() {
69     delete state_;
70   }
71 
is_null()72   bool is_null() const {
73     return !state_;
74   }
75 
get()76   S* get() {
77     assert(state_);
78     return &state_->proxy;
79   }
80 
81   S* operator->() {
82     return get();
83   }
84 
reset()85   void reset() {
86     delete state_;
87     state_ = NULL;
88   }
89 
reset(ScopedMessagePipeHandle message_pipe)90   void reset(ScopedMessagePipeHandle message_pipe) {
91     delete state_;
92     state_ = new State(message_pipe.Pass());
93   }
94 
encountered_error()95   bool encountered_error() const {
96     assert(state_);
97     return state_->connector.encountered_error();
98   }
99 
SetPeer(typename S::_Peer::_Stub * peer)100   void SetPeer(typename S::_Peer::_Stub* peer) {
101     assert(state_);
102     state_->connector.SetIncomingReceiver(peer);
103   }
104 
105  private:
106   struct State {
StateState107     State(ScopedMessagePipeHandle message_pipe)
108         : connector(message_pipe.Pass()),
109           proxy(&connector) {
110     }
111     internal::Connector connector;
112     typename S::_Proxy proxy;
113   };
114 
release()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