diff options
Diffstat (limited to 'mojo/public')
-rw-r--r-- | mojo/public/cpp/bindings/error_handler.h | 9 | ||||
-rw-r--r-- | mojo/public/cpp/bindings/interface_impl.h | 9 | ||||
-rw-r--r-- | mojo/public/cpp/bindings/lib/interface_impl_internal.h | 20 | ||||
-rw-r--r-- | mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc | 18 | ||||
-rw-r--r-- | mojo/public/cpp/shell/application.h | 60 | ||||
-rw-r--r-- | mojo/public/cpp/shell/connect.h | 25 | ||||
-rw-r--r-- | mojo/public/cpp/shell/lib/service_connector.cc (renamed from mojo/public/cpp/shell/lib/service.cc) | 2 | ||||
-rw-r--r-- | mojo/public/cpp/shell/lib/service_connector.h (renamed from mojo/public/cpp/shell/service.h) | 159 |
8 files changed, 167 insertions, 135 deletions
diff --git a/mojo/public/cpp/bindings/error_handler.h b/mojo/public/cpp/bindings/error_handler.h index a6f0a4a..8ce1af2 100644 --- a/mojo/public/cpp/bindings/error_handler.h +++ b/mojo/public/cpp/bindings/error_handler.h @@ -14,15 +14,6 @@ class ErrorHandler { virtual void OnConnectionError() = 0; }; -// Used when you'd like to extend a base class with the same method signature -// as ErrorHandler. -template <typename Base> -class WithErrorHandler : public Base { - public: - virtual ~WithErrorHandler() {} - virtual void OnConnectionError() = 0; -}; - } // namespace mojo #endif // MOJO_PUBLIC_CPP_BINDINGS_ERROR_HANDLER_H_ diff --git a/mojo/public/cpp/bindings/interface_impl.h b/mojo/public/cpp/bindings/interface_impl.h index a9d0947..15dc980 100644 --- a/mojo/public/cpp/bindings/interface_impl.h +++ b/mojo/public/cpp/bindings/interface_impl.h @@ -13,18 +13,17 @@ namespace mojo { // InterfaceImpl<..> is designed to be the base class of an interface // implementation. It may be bound to a pipe or a proxy, see BindToPipe and // BindToProxy. -// -// NOTE: A base class of WithErrorHandler<Interface> is used to avoid multiple -// inheritance. This base class inserts the signature of ErrorHandler into the -// inheritance chain. template <typename Interface> -class InterfaceImpl : public WithErrorHandler<Interface> { +class InterfaceImpl : public internal::InterfaceImplBase<Interface> { public: typedef typename Interface::Client Client; InterfaceImpl() : internal_state_(this) {} virtual ~InterfaceImpl() {} + // Subclasses can override this to handle post connection initialization. + virtual void OnConnectionEstablished() {} + // Subclasses must handle connection errors. virtual void OnConnectionError() = 0; diff --git a/mojo/public/cpp/bindings/lib/interface_impl_internal.h b/mojo/public/cpp/bindings/lib/interface_impl_internal.h index 26f2443..e661290 100644 --- a/mojo/public/cpp/bindings/lib/interface_impl_internal.h +++ b/mojo/public/cpp/bindings/lib/interface_impl_internal.h @@ -15,11 +15,19 @@ namespace mojo { namespace internal { template <typename Interface> +class InterfaceImplBase : public Interface { + public: + virtual ~InterfaceImplBase() {} + virtual void OnConnectionEstablished() = 0; + virtual void OnConnectionError() = 0; +}; + +template <typename Interface> class InterfaceImplState : public ErrorHandler { public: typedef typename Interface::Client Client; - explicit InterfaceImplState(WithErrorHandler<Interface>* instance) + explicit InterfaceImplState(InterfaceImplBase<Interface>* instance) : router_(NULL), client_(NULL), proxy_(NULL) { @@ -58,7 +66,8 @@ class InterfaceImplState : public ErrorHandler { proxy_ = new typename Client::Proxy_(router_); - stub_.sink()->SetClient(proxy_); + instance()->SetClient(proxy_); + instance()->OnConnectionEstablished(); } Router* router() { return router_; } @@ -67,9 +76,12 @@ class InterfaceImplState : public ErrorHandler { Client* client() { return client_; } private: + InterfaceImplBase<Interface>* instance() { + return static_cast<InterfaceImplBase<Interface>*>(stub_.sink()); + } + virtual void OnConnectionError() MOJO_OVERRIDE { - static_cast<WithErrorHandler<Interface>*>(stub_.sink())-> - OnConnectionError(); + instance()->OnConnectionError(); } Router* router_; diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc index 4410e6f..541aba1 100644 --- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc +++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc @@ -32,7 +32,13 @@ class MathCalculatorImpl : public InterfaceImpl<math::Calculator> { public: virtual ~MathCalculatorImpl() {} - MathCalculatorImpl() : total_(0.0) { + MathCalculatorImpl() + : total_(0.0), + got_connection_(false) { + } + + virtual void OnConnectionEstablished() MOJO_OVERRIDE { + got_connection_ = true; } virtual void OnConnectionError() MOJO_OVERRIDE { @@ -53,8 +59,13 @@ class MathCalculatorImpl : public InterfaceImpl<math::Calculator> { client()->Output(total_); } - private: + bool got_connection() const { + return got_connection_; + } + +private: double total_; + bool got_connection_; }; class MathCalculatorUIImpl : public math::CalculatorUI { @@ -116,7 +127,8 @@ class InterfacePtrTest : public testing::Test { TEST_F(InterfacePtrTest, EndToEnd) { math::CalculatorPtr calc; - BindToProxy(new MathCalculatorImpl(), &calc); + MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc); + EXPECT_TRUE(impl->got_connection()); // Suppose this is instantiated in a process that has pipe1_. MathCalculatorUIImpl calculator_ui(calc.Pass()); diff --git a/mojo/public/cpp/shell/application.h b/mojo/public/cpp/shell/application.h index 933077b..3e016d1 100644 --- a/mojo/public/cpp/shell/application.h +++ b/mojo/public/cpp/shell/application.h @@ -7,24 +7,61 @@ #include <vector> -#include "mojo/public/cpp/shell/service.h" +#include "mojo/public/cpp/shell/connect.h" +#include "mojo/public/cpp/shell/lib/service_connector.h" #include "mojo/public/cpp/system/core.h" #include "mojo/public/interfaces/shell/shell.mojom.h" namespace mojo { +// Utility class for creating ShellClients that vend service instances. +// To use define a class that implements your specific server api, e.g. FooImpl +// to implement a service named Foo. +// That class must subclass an InterfaceImpl specialization. +// +// If there is context that is to be shared amongst all instances, define a +// constructor with that class as its only argument, otherwise define an empty +// constructor. +// +// class FooImpl : public InterfaceImpl<Foo> { +// public: +// FooImpl() {} +// }; +// +// or +// +// class BarImpl : public InterfaceImpl<Bar> { +// public: +// // context will remain valid for the lifetime of BarImpl. +// BarImpl(BarContext* context) : context_(context) {} +// private: +// BarContext* context; +// }; +// +// Create an Application instance that collects any service implementations. +// +// Application app(shell_handle); +// app.AddService<FooImpl>(); +// +// BarContext context; +// app.AddService<BarImpl>(&context); +// +// class Application : public internal::ServiceConnectorBase::Owner { public: explicit Application(ScopedMessagePipeHandle shell_handle); explicit Application(MojoHandle shell_handle); virtual ~Application(); - // internal::ServiceConnectorBase::Owner methods. - // Takes ownership of |service_connector|. - virtual void AddServiceConnector( - internal::ServiceConnectorBase* service_connector) MOJO_OVERRIDE; - virtual void RemoveServiceConnector( - internal::ServiceConnectorBase* service_connector) MOJO_OVERRIDE; + template <typename Impl, typename Context> + void AddService(Context* context) { + AddServiceConnector(new internal::ServiceConnector<Impl, Context>(context)); + } + + template <typename Impl> + void AddService() { + AddServiceConnector(new internal::ServiceConnector<Impl, void>(NULL)); + } template <typename Interface> void ConnectTo(const std::string& url, InterfacePtr<Interface>* ptr) { @@ -33,11 +70,20 @@ class Application : public internal::ServiceConnectorBase::Owner { protected: // ShellClient methods. + // Override this to dispatch to correct service when there's more than one. + // TODO(davemoore): Augment this with name registration. virtual void AcceptConnection(const mojo::String& url, ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE; private: + // internal::ServiceConnectorBase::Owner methods. + // Takes ownership of |service_connector|. + virtual void AddServiceConnector( + internal::ServiceConnectorBase* service_connector) MOJO_OVERRIDE; + virtual void RemoveServiceConnector( + internal::ServiceConnectorBase* service_connector) MOJO_OVERRIDE; + typedef std::vector<internal::ServiceConnectorBase*> ServiceConnectorList; ServiceConnectorList service_connectors_; }; diff --git a/mojo/public/cpp/shell/connect.h b/mojo/public/cpp/shell/connect.h new file mode 100644 index 0000000..caee589 --- /dev/null +++ b/mojo/public/cpp/shell/connect.h @@ -0,0 +1,25 @@ +// Copyright 2014 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_CPP_SHELL_CONNECT_H_ +#define MOJO_PUBLIC_CPP_SHELL_CONNECT_H_ + +#include "mojo/public/cpp/bindings/allocation_scope.h" +#include "mojo/public/interfaces/shell/shell.mojom.h" + +namespace mojo { + +template <typename Interface> +inline void ConnectTo(Shell* shell, const std::string& url, + InterfacePtr<Interface>* ptr) { + MessagePipe pipe; + ptr->Bind(pipe.handle0.Pass()); + + AllocationScope scope; + shell->Connect(url, pipe.handle1.Pass()); +} + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_SHELL_CONNECT_H_ diff --git a/mojo/public/cpp/shell/lib/service.cc b/mojo/public/cpp/shell/lib/service_connector.cc index 2f2e542..18f34b6 100644 --- a/mojo/public/cpp/shell/lib/service.cc +++ b/mojo/public/cpp/shell/lib/service_connector.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/public/cpp/shell/service.h" +#include "mojo/public/cpp/shell/lib/service_connector.h" namespace mojo { namespace internal { diff --git a/mojo/public/cpp/shell/service.h b/mojo/public/cpp/shell/lib/service_connector.h index c546289..421cb72 100644 --- a/mojo/public/cpp/shell/service.h +++ b/mojo/public/cpp/shell/lib/service_connector.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_PUBLIC_SHELL_SERVICE_H_ -#define MOJO_PUBLIC_SHELL_SERVICE_H_ +#ifndef MOJO_PUBLIC_CPP_SHELL_LIB_SERVICE_CONNECTOR_H_ +#define MOJO_PUBLIC_CPP_SHELL_LIB_SERVICE_CONNECTOR_H_ #include <assert.h> @@ -12,54 +12,53 @@ #include "mojo/public/cpp/bindings/allocation_scope.h" #include "mojo/public/interfaces/shell/shell.mojom.h" -// Utility classes for creating ShellClients that vend service instances. -// To use define a class that implements your specific server api, e.g. FooImpl -// to implement a service named Foo. That class must define an empty constructor -// and the Initialize() method. -// class FooImpl : public Foo { -// public: -// FooImpl(); -// void Initialize(); -// private: -// ServiceConnector<FooImpl>* service_connector_; -// }; -// -// -// To simplify further FooImpl can use the ServiceConnection<> template. -// class FooImpl : public ServiceConnection<Foo, FooImpl> { -// public: -// FooImpl(); -// ... -// <Foo implementation> -// }; -// -// Instances of FooImpl will be created by a specialized ServiceConnector -// -// ServiceConnector<FooImpl> -// -// Optionally the classes can be specializeed with a shared context -// class ServiceConnector<FooImpl, MyContext> -// and -// class FooImpl : public ServiceConnection<Foo, FooImpl, MyContext> -// -// foo_connector = new ServiceConnector<FooImpl, MyContext>(my_context); -// instances of FooImpl can call context() and retrieve the value of my_context. -// -// Lastly create an Application instance that collects all the -// ServiceConnectors. -// -// Application app(shell_handle); -// app.AddServiceConnector(new ServiceConnector<FooImpl>); -// -// -// Specialization of ServiceConnector. -// ServiceImpl: Implementation of Service interface. -// Context: Optional type of shared context.v -// -// namespace mojo { - namespace internal { + +template <class ServiceImpl, typename Context> +class ServiceConnector; + +// Specialization of ServiceConnection. +// ServiceImpl: Subclass of InterfaceImpl<...>. +// Context: Type of shared context. +template <class ServiceImpl, typename Context> +class ServiceConnection : public ServiceImpl { + public: + ServiceConnection() : ServiceImpl() {} + ServiceConnection(Context* context) : ServiceImpl(context) {} + + virtual void OnConnectionError() MOJO_OVERRIDE { + service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this)); + ServiceImpl::OnConnectionError(); + } + +private: + friend class ServiceConnector<ServiceImpl, Context>; + + // Called shortly after this class is instantiated. + void set_service_connector( + ServiceConnector<ServiceImpl, Context>* connector) { + service_connector_ = connector; + } + + ServiceConnector<ServiceImpl, Context>* service_connector_; +}; + +template <typename ServiceImpl, typename Context> +struct ServiceConstructor { + static ServiceConnection<ServiceImpl, Context>* New(Context* context) { + return new ServiceConnection<ServiceImpl, Context>(context); + } +}; + +template <typename ServiceImpl> +struct ServiceConstructor<ServiceImpl, void> { + public: + static ServiceConnection<ServiceImpl, void>* New(void* context) { + return new ServiceConnection<ServiceImpl, void>(); + } +}; + class ServiceConnectorBase { public: class Owner : public ShellClient { @@ -88,7 +87,6 @@ class ServiceConnectorBase { protected: Owner* owner_; }; -} // namespace internal template <class ServiceImpl, typename Context=void> class ServiceConnector : public internal::ServiceConnectorBase { @@ -107,12 +105,12 @@ class ServiceConnector : public internal::ServiceConnectorBase { virtual void AcceptConnection(const std::string& url, ScopedMessagePipeHandle handle) MOJO_OVERRIDE { - ServiceImpl* impl = BindToPipe(new ServiceImpl(), handle.Pass()); - impl->set_connector(this); + ServiceConnection<ServiceImpl, Context>* impl = + ServiceConstructor<ServiceImpl, Context>::New(context_); + impl->set_service_connector(this); + BindToPipe(impl, handle.Pass()); connections_.push_back(impl); - - impl->Initialize(); } void RemoveConnection(ServiceImpl* impl) { @@ -137,58 +135,7 @@ class ServiceConnector : public internal::ServiceConnectorBase { Context* context_; }; -// Specialization of ServiceConnection. -// ServiceInterface: Service interface. -// ServiceImpl: Subclass of ServiceConnection<...>. -// Context: Optional type of shared context. -template <class ServiceInterface, class ServiceImpl, typename Context=void> -class ServiceConnection : public InterfaceImpl<ServiceInterface> { - protected: - // NOTE: shell() and context() are not available at construction time. - // Initialize() will be called once those are available. - ServiceConnection() : service_connector_(NULL) {} - - virtual ~ServiceConnection() {} - - virtual void OnConnectionError() MOJO_OVERRIDE { - service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this)); - } - - // Shadow this method in ServiceImpl to perform one-time initialization. - // At the time this is called, shell() and context() will be available. - // NOTE: No need to call the base class Initialize from your subclass. It - // will always be a no-op. - void Initialize() {} - - Shell* shell() { - return service_connector_->shell(); - } - - Context* context() const { - return service_connector_->context(); - } - - private: - friend class ServiceConnector<ServiceImpl, Context>; - - // Called shortly after this class is instantiated. - void set_connector(ServiceConnector<ServiceImpl, Context>* connector) { - service_connector_ = connector; - } - - ServiceConnector<ServiceImpl, Context>* service_connector_; -}; - -template <typename Interface> -inline void ConnectTo(Shell* shell, const std::string& url, - InterfacePtr<Interface>* ptr) { - MessagePipe pipe; - ptr->Bind(pipe.handle0.Pass()); - - AllocationScope scope; - shell->Connect(url, pipe.handle1.Pass()); -} - +} // namespace internal } // namespace mojo -#endif // MOJO_PUBLIC_SHELL_SERVICE_H_ +#endif // MOJO_PUBLIC_CPP_SHELL_LIB_SERVICE_CONNECTOR_H_ |