Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / mojo / public / bindings / lib / 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_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, this) {
26 //       foo_.Ping();
27 //     }
28 //     virtual void Pong() {
29 //       ...
30 //     }
31 //    private:
32 //     mojo::RemotePtr<Foo> foo_;
33 //   };
34 //
35 // On the implementation side of a service, RemotePtr might be used like so:
36 //
37 //   class FooImpl : public FooStub {
38 //    public:
39 //     explicit FooImpl(const mojo::MessagePipeHandle& message_pipe)
40 //         : client_(message_pipe, this) {
41 //     }
42 //     virtual void Ping() {
43 //       client_->Pong();
44 //     }
45 //    private:
46 //     mojo::RemotePtr<FooClient> client_;
47 //   };
48 //
49 template <typename S>
50 class RemotePtr {
51   struct State;
52   MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(RemotePtr, RValue);
53
54  public:
55   RemotePtr() : state_(NULL) {}
56   explicit RemotePtr(ScopedMessagePipeHandle message_pipe,
57                      typename S::_Peer* peer = NULL,
58                      MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter())
59       : state_(new State(message_pipe.Pass(), peer, waiter)) {
60   }
61
62   // Move-only constructor and operator=.
63   RemotePtr(RValue other) : state_(other.object->release()) {}
64   RemotePtr& operator=(RValue other) {
65     state_ = other.object->release();
66     return *this;
67   }
68
69   ~RemotePtr() {
70     delete state_;
71   }
72
73   bool is_null() const {
74     return !state_;
75   }
76
77   S* get() {
78     assert(state_);
79     return &state_->proxy;
80   }
81
82   S* operator->() {
83     return get();
84   }
85
86   void reset() {
87     delete state_;
88     state_ = NULL;
89   }
90
91   void reset(ScopedMessagePipeHandle message_pipe,
92              typename S::_Peer* peer = NULL,
93              MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()) {
94     delete state_;
95     state_ = new State(message_pipe.Pass(), peer, waiter);
96   }
97
98   bool encountered_error() const {
99     assert(state_);
100     return state_->connector.encountered_error();
101   }
102
103  private:
104   struct State {
105     State(ScopedMessagePipeHandle message_pipe, typename S::_Peer* peer,
106           MojoAsyncWaiter* waiter)
107         : connector(message_pipe.Pass(), waiter),
108           proxy(&connector),
109           stub(peer) {
110       if (peer)
111         connector.SetIncomingReceiver(&stub);
112     }
113     internal::Connector connector;
114     typename S::_Proxy proxy;
115     typename S::_Peer::_Stub stub;
116   };
117
118   State* release() {
119     State* state = state_;
120     state_ = NULL;
121     return state;
122   }
123
124   State* state_;
125 };
126
127 }  // namespace mojo
128
129 #endif  // MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_