summaryrefslogtreecommitdiffstats
path: root/mojo/public/cpp/application
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/public/cpp/application')
-rw-r--r--mojo/public/cpp/application/application_connection.h51
-rw-r--r--mojo/public/cpp/application/interface_factory.h30
-rw-r--r--mojo/public/cpp/application/interface_factory_with_context.h34
-rw-r--r--mojo/public/cpp/application/lib/mojo_main_chromium.cc16
-rw-r--r--mojo/public/cpp/application/lib/mojo_main_standalone.cc15
-rw-r--r--mojo/public/cpp/application/lib/service_connector.h110
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