diff options
Diffstat (limited to 'mojo/public/cpp/application')
6 files changed, 109 insertions, 147 deletions
diff --git a/mojo/public/cpp/application/application_connection.h b/mojo/public/cpp/application/application_connection.h index 2044af1..c0e3480 100644 --- a/mojo/public/cpp/application/application_connection.h +++ b/mojo/public/cpp/application/application_connection.h @@ -21,51 +21,26 @@ namespace mojo { // 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. +// Then implement an InterfaceFactory<Foo> that binds instances of FooImpl to +// InterfaceRequest<Foo>s and register that on the connection. // -// class FooImpl : public InterfaceImpl<Foo> { -// public: -// explicit FooImpl(ApplicationConnnection* connection) {} -// }; +// connection->AddService(&factory); // -// or +// Or if you have multiple factories implemented by the same type, explicitly +// specify the interface to register the factory for: // -// class BarImpl : public InterfaceImpl<Bar> { -// public: -// // contexts will remain valid for the lifetime of BarImpl. -// BarImpl(ApplicationConnnection* connection, BarContext* service_context) -// : connection_(connection), servicecontext_(context) {} +// connection->AddService<Foo>(&my_foo_and_bar_factory_); +// connection->AddService<Bar>(&my_foo_and_bar_factory_); // -// Create an ApplicationDelegate instance and pass it to the constructor -// of an ApplicationImpl. The delegate will be called when new connections are -// made to other applications. -// -// connection->AddService<FooImpl>(); -// -// BarContext context; -// connection->AddService<BarImpl>(&context); +// The InterfaceFactory must outlive the ApplicationConnection. class ApplicationConnection { public: virtual ~ApplicationConnection(); - // Impl’s constructor will receive two arguments: - // Impl::Impl(Application::Context* app_context, - // ServiceContext* svc_context) - template <typename Impl, typename ServiceContext> - void AddService(ServiceContext* context) { - AddServiceConnector( - new internal::ServiceConnector<Impl, ServiceContext>(Impl::Name_, - context)); - } - - // Impl’s constructor will receive one argument: - // Impl::Impl(Application::Context* app_context) - template <typename Impl> - void AddService() { + template <typename Interface> + void AddService(InterfaceFactory<Interface>* factory) { AddServiceConnector( - new internal::ServiceConnector<Impl, void>(Impl::Name_, NULL)); + new internal::InterfaceFactoryConnector<Interface>(factory)); } // Connect to the service implementing |Interface|. @@ -96,8 +71,8 @@ class ApplicationConnection { // Raw ServiceProvider interface to remote application. virtual ServiceProvider* GetServiceProvider() = 0; -private: - virtual void AddServiceConnector( + private: + virtual void AddServiceConnector( internal::ServiceConnectorBase* service_connector) = 0; }; diff --git a/mojo/public/cpp/application/interface_factory.h b/mojo/public/cpp/application/interface_factory.h new file mode 100644 index 0000000..90abd13 --- /dev/null +++ b/mojo/public/cpp/application/interface_factory.h @@ -0,0 +1,30 @@ +// 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_APPLICATION_INTERFACE_FACTORY_H_ +#define MOJO_PUBLIC_CPP_APPLICATION_INTERFACE_FACTORY_H_ + +#include "mojo/public/cpp/bindings/interface_impl.h" +#include "mojo/public/cpp/bindings/interface_request.h" + +namespace mojo { + +class ApplicationConnection; +template <typename Interface> class InterfaceRequest; + +// Implement this class to provide implementations of a given interface and +// bind them to incoming requests. The implementation of this class is +// responsible for managing the lifetime of the implementations of the +// interface. +template <typename Interface> +class InterfaceFactory { + public: + virtual ~InterfaceFactory() {} + virtual void Create(ApplicationConnection* connection, + InterfaceRequest<Interface> request) = 0; +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_APPLICATION_INTERFACE_FACTORY_H_ diff --git a/mojo/public/cpp/application/interface_factory_with_context.h b/mojo/public/cpp/application/interface_factory_with_context.h new file mode 100644 index 0000000..8ea7215 --- /dev/null +++ b/mojo/public/cpp/application/interface_factory_with_context.h @@ -0,0 +1,34 @@ +// 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_APPLICATION_INTERFACE_FACTORY_WITH_CONTEXT_H_ +#define MOJO_PUBLIC_CPP_APPLICATION_INTERFACE_FACTORY_WITH_CONTEXT_H_ + +#include "mojo/public/cpp/application/interface_factory.h" + +namespace mojo { + +// Use this class to allocate and bind instances of Impl constructed with a +// context parameter to interface requests. The lifetime of the constructed +// Impls is bound to the pipe. +template <typename Impl, + typename Context, + typename Interface = typename Impl::ImplementedInterface> +class InterfaceFactoryWithContext : public InterfaceFactory<Interface> { + public: + explicit InterfaceFactoryWithContext(Context* context) : context_(context) {} + virtual ~InterfaceFactoryWithContext() {} + + virtual void Create(ApplicationConnection* connection, + InterfaceRequest<Interface> request) MOJO_OVERRIDE { + BindToRequest(new Impl(context_), &request); + } + + private: + Context* context_; +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_APPLICATION_INTERFACE_FACTORY_WITH_CONTEXT_H_ diff --git a/mojo/public/cpp/application/lib/mojo_main_chromium.cc b/mojo/public/cpp/application/lib/mojo_main_chromium.cc index 269b7a2..d8c5e3f 100644 --- a/mojo/public/cpp/application/lib/mojo_main_chromium.cc +++ b/mojo/public/cpp/application/lib/mojo_main_chromium.cc @@ -14,12 +14,16 @@ extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( #if !defined(COMPONENT_BUILD) base::AtExitManager at_exit; #endif - base::MessageLoop loop; - scoped_ptr<mojo::ApplicationDelegate> delegate( - mojo::ApplicationDelegate::Create()); - mojo::ApplicationImpl app(delegate.get()); - app.BindShell(shell_handle); - loop.Run(); + scoped_ptr<mojo::ApplicationDelegate> delegate; + { + // We have to shut down the MessageLoop before destroying the + // ApplicationDelegate. + base::MessageLoop loop; + delegate.reset(mojo::ApplicationDelegate::Create()); + mojo::ApplicationImpl app(delegate.get()); + app.BindShell(shell_handle); + loop.Run(); + } return MOJO_RESULT_OK; } diff --git a/mojo/public/cpp/application/lib/mojo_main_standalone.cc b/mojo/public/cpp/application/lib/mojo_main_standalone.cc index 0ba078b..6071b6b 100644 --- a/mojo/public/cpp/application/lib/mojo_main_standalone.cc +++ b/mojo/public/cpp/application/lib/mojo_main_standalone.cc @@ -10,12 +10,17 @@ extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( MojoHandle shell_handle) { mojo::Environment env; - mojo::RunLoop loop; - mojo::ApplicationDelegate* delegate = mojo::ApplicationDelegate::Create(); + mojo::ApplicationDelegate* delegate = NULL; { - mojo::ApplicationImpl app(delegate); - app.BindShell(shell_handle); - loop.Run(); + // We have to shut down the RunLoop before destroying the + // ApplicationDelegate. + mojo::RunLoop loop; + delegate = mojo::ApplicationDelegate::Create(); + { + mojo::ApplicationImpl app(delegate); + app.BindShell(shell_handle); + loop.Run(); + } } delete delegate; diff --git a/mojo/public/cpp/application/lib/service_connector.h b/mojo/public/cpp/application/lib/service_connector.h index d2de48b..aeb7de1 100644 --- a/mojo/public/cpp/application/lib/service_connector.h +++ b/mojo/public/cpp/application/lib/service_connector.h @@ -5,10 +5,8 @@ #ifndef MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_ #define MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_ -#include <assert.h> - -#include <vector> - +#include "mojo/public/cpp/application/interface_factory.h" +#include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/interfaces/service_provider/service_provider.mojom.h" namespace mojo { @@ -16,59 +14,6 @@ class ApplicationConnection; 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: - explicit ServiceConnection(ApplicationConnection* connection) - : ServiceImpl(connection) {} - ServiceConnection(ApplicationConnection* connection, - Context* context) : ServiceImpl(connection, 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_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnection); -}; - -template <typename ServiceImpl, typename Context> -struct ServiceConstructor { - static ServiceConnection<ServiceImpl, Context>* New( - ApplicationConnection* connection, - Context* context) { - return new ServiceConnection<ServiceImpl, Context>( - connection, context); - } -}; - -template <typename ServiceImpl> -struct ServiceConstructor<ServiceImpl, void> { - public: - static ServiceConnection<ServiceImpl, void>* New( - ApplicationConnection* connection, - void* context) { - return new ServiceConnection<ServiceImpl, void>(connection); - } -}; - class ServiceConnectorBase { public: ServiceConnectorBase(const std::string& name); @@ -86,53 +31,22 @@ class ServiceConnectorBase { MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnectorBase); }; -template <class ServiceImpl, typename Context=void> -class ServiceConnector : public internal::ServiceConnectorBase { +template <typename Interface> +class InterfaceFactoryConnector : public ServiceConnectorBase { public: - ServiceConnector(const std::string& name, Context* context = NULL) - : ServiceConnectorBase(name), context_(context) {} - - virtual ~ServiceConnector() { - ConnectionList doomed; - doomed.swap(connections_); - for (typename ConnectionList::iterator it = doomed.begin(); - it != doomed.end(); ++it) { - delete *it; - } - assert(connections_.empty()); // No one should have added more! - } + explicit InterfaceFactoryConnector(InterfaceFactory<Interface>* factory) + : ServiceConnectorBase(Interface::Name_), factory_(factory) {} + virtual ~InterfaceFactoryConnector() {} virtual void ConnectToService(const std::string& name, - ScopedMessagePipeHandle handle) MOJO_OVERRIDE { - ServiceConnection<ServiceImpl, Context>* impl = - ServiceConstructor<ServiceImpl, Context>::New(application_connection_, - context_); - impl->set_service_connector(this); - BindToPipe(impl, handle.Pass()); - - connections_.push_back(impl); - } - - void RemoveConnection(ServiceImpl* impl) { - // Called from ~ServiceImpl, in response to a connection error. - for (typename ConnectionList::iterator it = connections_.begin(); - it != connections_.end(); ++it) { - if (*it == impl) { - delete impl; - connections_.erase(it); - return; - } - } + ScopedMessagePipeHandle client_handle) { + factory_->Create(application_connection_, + MakeRequest<Interface>(client_handle.Pass())); } - Context* context() const { return context_; } - private: - typedef std::vector<ServiceImpl*> ConnectionList; - ConnectionList connections_; - Context* context_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnector); + InterfaceFactory<Interface>* factory_; + MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceFactoryConnector); }; } // namespace internal |