Home | History | Annotate | Download | only in lib
      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