summaryrefslogtreecommitdiffstats
path: root/mojo/public
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/public')
-rw-r--r--mojo/public/cpp/bindings/error_handler.h9
-rw-r--r--mojo/public/cpp/bindings/interface_impl.h9
-rw-r--r--mojo/public/cpp/bindings/lib/interface_impl_internal.h20
-rw-r--r--mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc18
-rw-r--r--mojo/public/cpp/shell/application.h60
-rw-r--r--mojo/public/cpp/shell/connect.h25
-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_