// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_ #define MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_ #include <assert.h> #include "mojo/public/bindings/lib/connector.h" #include "mojo/public/system/macros.h" namespace mojo { // A RemotePtr is a smart-pointer for managing the connection of a message pipe // to an interface proxy. // // EXAMPLE // // On the client side of a service, RemotePtr might be used like so: // // class FooClientImpl : public FooClientStub { // public: // explicit FooClientImpl(const mojo::MessagePipeHandle& message_pipe) // : foo_(message_pipe) { // foo_.SetPeer(this); // foo_.Ping(); // } // virtual void Pong() { // ... // } // private: // mojo::RemotePtr<Foo> foo_; // }; // // On the implementation side of a service, RemotePtr might be used like so: // // class FooImpl : public FooStub { // public: // explicit FooImpl(const mojo::MessagePipeHandle& message_pipe) // : client_(message_pipe) { // client_.SetPeer(this); // } // virtual void Ping() { // client_->Pong(); // } // private: // mojo::RemotePtr<FooClient> client_; // }; // template <typename S> class RemotePtr { MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(RemotePtr, RValue); public: RemotePtr() : state_(NULL) {} explicit RemotePtr(ScopedMessagePipeHandle message_pipe) : state_(new State(message_pipe.Pass())) { } // Move-only constructor and operator=. RemotePtr(RValue other) : state_(other.object->release()) {} RemotePtr& operator=(RValue other) { state_ = other.object->release(); return *this; } ~RemotePtr() { delete state_; } bool is_null() const { return !state_; } S* get() { assert(state_); return &state_->proxy; } S* operator->() { return get(); } void reset() { delete state_; state_ = NULL; } void reset(ScopedMessagePipeHandle message_pipe) { delete state_; state_ = new State(message_pipe.Pass()); } bool encountered_error() const { assert(state_); return state_->connector.encountered_error(); } void SetPeer(typename S::_Peer::_Stub* peer) { assert(state_); state_->connector.SetIncomingReceiver(peer); } private: struct State { State(ScopedMessagePipeHandle message_pipe) : connector(message_pipe.Pass()), proxy(&connector) { } internal::Connector connector; typename S::_Proxy proxy; }; State* release() { State* state = state_; state_ = NULL; return state; } State* state_; }; } // namespace mojo #endif // MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_