diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-12 16:26:11 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-12 16:26:11 +0000 |
commit | 128daf6bc3b24d366cf8f252ebe20f70818ea1b7 (patch) | |
tree | 8f6c4f5cf42904532664f7786857400be61251b7 /mojo/public | |
parent | cd4186fcba54ce17d0c16467fdb8835286aa466f (diff) | |
download | chromium_src-128daf6bc3b24d366cf8f252ebe20f70818ea1b7.zip chromium_src-128daf6bc3b24d366cf8f252ebe20f70818ea1b7.tar.gz chromium_src-128daf6bc3b24d366cf8f252ebe20f70818ea1b7.tar.bz2 |
Create Application class
BUG=
R=darin@chromium.org
Review URL: https://codereview.chromium.org/135513008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250731 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/public')
-rw-r--r-- | mojo/public/shell/application.h | 46 | ||||
-rw-r--r-- | mojo/public/shell/lib/application.cc | 57 | ||||
-rw-r--r-- | mojo/public/shell/lib/service.cc | 10 | ||||
-rw-r--r-- | mojo/public/shell/lib/shell.mojom | 2 | ||||
-rw-r--r-- | mojo/public/shell/service.h | 93 |
5 files changed, 162 insertions, 46 deletions
diff --git a/mojo/public/shell/application.h b/mojo/public/shell/application.h new file mode 100644 index 0000000..57bd2fd --- /dev/null +++ b/mojo/public/shell/application.h @@ -0,0 +1,46 @@ +// 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_SHELL_APPLICATION_H_ +#define MOJO_PUBLIC_SHELL_APPLICATION_H_ + +#include <vector> + +#include "mojo/public/bindings/remote_ptr.h" +#include "mojo/public/shell/service.h" +#include "mojo/public/system/core_cpp.h" +#include "mojom/shell.h" + +namespace mojo { + +class Application : public internal::ServiceFactoryBase::Owner, + public ShellClient { + public: + explicit Application(ScopedShellHandle shell_handle); + explicit Application(MojoHandle shell_handle); + virtual ~Application(); + + // internal::ServiceFactoryBase::Owner methods. + virtual Shell* GetShell() MOJO_OVERRIDE; + // Takes ownership of |service_factory|. + virtual void AddServiceFactory(internal::ServiceFactoryBase* service_factory) + MOJO_OVERRIDE; + virtual void RemoveServiceFactory( + internal::ServiceFactoryBase* service_factory) MOJO_OVERRIDE; + + protected: + // ShellClient methods. + virtual void AcceptConnection(const mojo::String& url, + ScopedMessagePipeHandle client_handle) + MOJO_OVERRIDE; + + private: + typedef std::vector<internal::ServiceFactoryBase*> ServiceFactoryList; + ServiceFactoryList service_factories_; + RemotePtr<Shell> shell_; +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_SHELL_APPLICATION_H_ diff --git a/mojo/public/shell/lib/application.cc b/mojo/public/shell/lib/application.cc new file mode 100644 index 0000000..dde3227 --- /dev/null +++ b/mojo/public/shell/lib/application.cc @@ -0,0 +1,57 @@ +// 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. + +#include "mojo/public/shell/application.h" + +namespace mojo { + +Application::Application(ScopedShellHandle shell_handle) + : shell_(shell_handle.Pass(), this) { +} + +Application::Application(MojoHandle shell_handle) + : shell_(mojo::MakeScopedHandle(ShellHandle(shell_handle)).Pass()) {} + +Application::~Application() { + for (ServiceFactoryList::iterator it = service_factories_.begin(); + it != service_factories_.end(); ++it) { + delete *it; + } +} + +Shell* Application::GetShell() { + return shell_.get(); +} + +void Application::AddServiceFactory( + internal::ServiceFactoryBase* service_factory) { + service_factories_.push_back(service_factory); + set_service_factory_owner(service_factory, this); +} + +void Application::RemoveServiceFactory( + internal::ServiceFactoryBase* service_factory) { + for (ServiceFactoryList::iterator it = service_factories_.begin(); + it != service_factories_.end(); ++it) { + if (*it == service_factory) { + service_factories_.erase(it); + delete service_factory; + break; + } + } + if (service_factories_.empty()) + shell_.reset(); +} + +void Application::AcceptConnection(const mojo::String& url, + ScopedMessagePipeHandle client_handle) { + // TODO(davemoore): This method must be overridden by an Application subclass + // to dispatch to the right ServiceFactory. We need to figure out an approach + // to registration to make this better. + assert(1 == service_factories_.size()); + return service_factories_.front()->AcceptConnection(url.To<std::string>(), + client_handle.Pass()); +} + +} // namespace mojo diff --git a/mojo/public/shell/lib/service.cc b/mojo/public/shell/lib/service.cc index e4ca1a1..8ae0d05 100644 --- a/mojo/public/shell/lib/service.cc +++ b/mojo/public/shell/lib/service.cc @@ -5,15 +5,9 @@ #include "mojo/public/shell/service.h" namespace mojo { - -ServiceFactoryBase::ServiceFactoryBase(ScopedShellHandle shell_handle) - : shell_(shell_handle.Pass(), this) { -} +namespace internal { ServiceFactoryBase::~ServiceFactoryBase() {} -void ServiceFactoryBase::DisconnectFromShell() { - shell_.reset(); -} - +} // namespace internal } // namespace mojo diff --git a/mojo/public/shell/lib/shell.mojom b/mojo/public/shell/lib/shell.mojom index 65fc790..69827da5 100644 --- a/mojo/public/shell/lib/shell.mojom +++ b/mojo/public/shell/lib/shell.mojom @@ -13,7 +13,7 @@ interface Shell { [Peer=Shell] interface ShellClient { - void AcceptConnection(handle<message_pipe> client_handle); + void AcceptConnection(string url, handle<message_pipe> client_handle); }; } diff --git a/mojo/public/shell/service.h b/mojo/public/shell/service.h index 26bac9b..1a68353 100644 --- a/mojo/public/shell/service.h +++ b/mojo/public/shell/service.h @@ -18,7 +18,6 @@ // and the Initialize() method. // class FooImpl : public Foo { // public: -// typedef MyContext SharedContext; // FooImpl(); // void Initialize(ServiceFactory<FooImpl>* service_factory, // ScopedMessagePipeHandle client_handle @@ -27,10 +26,8 @@ // RemotePtr<FooPeer> client_; // }; // -// To instantiate such a service: -// ServiceFactory<FooImpl> service_factory(shell_handle.Pass()); // -// To simplify further Foo can use the Service<> template. +// To simplify further FooImpl can use the Service<> template. // class FooImpl : public Service<Foo, FooImpl> { // public: // FooImpl(); @@ -38,47 +35,73 @@ // <Foo implementation> // }; // -// Optionally the clases can be specializeed with a shared context +// Instances of FooImpl will be created by a specialized ServiceFactory +// +// ServiceFactory<FooImpl> +// +// Optionally the classes can be specializeed with a shared context // class ServiceFactory<FooImpl, MyContext> // and // class FooImpl : public Service<Foo, FooImpl, MyContext> // -// ServiceFactory<FooImpl> service_factory(shell_handle.Pass(), my_context) +// foo_factory = new ServiceFactory<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 ServiceFactories. +// +// Application app(shell_handle); +// app.AddServiceFactory(new ServiceFactory<FooImpl>); +// +// // Specialization of ServiceFactory. // ServiceImpl: Implementation of Service interface. // Context: Optional type of shared context.v +// +// namespace mojo { -class ServiceFactoryBase : public ShellClient { +namespace internal { +class ServiceFactoryBase { public: + class Owner { + public: + virtual Shell* GetShell() = 0; + virtual void AddServiceFactory( + internal::ServiceFactoryBase* service_factory) = 0; + virtual void RemoveServiceFactory( + internal::ServiceFactoryBase* service_factory) = 0; + + protected: + void set_service_factory_owner(ServiceFactoryBase* service_factory, + Owner* owner) { + service_factory->owner_ = owner; + } + }; + ServiceFactoryBase() : owner_(NULL) {} virtual ~ServiceFactoryBase(); + Shell* GetShell() { return owner_->GetShell(); } + virtual void AcceptConnection(const std::string& url, + ScopedMessagePipeHandle client_handle) = 0; protected: - ServiceFactoryBase(ScopedShellHandle shell_handle); - Shell* shell() { return shell_.get(); } - // Destroys connection to Shell. - void DisconnectFromShell(); - - private: - RemotePtr<Shell> shell_; + Owner* owner_; }; +} // namespace internal template <class ServiceImpl, typename Context=void> -class ServiceFactory : public ServiceFactoryBase { +class ServiceFactory : public internal::ServiceFactoryBase { public: - ServiceFactory(ScopedShellHandle shell_handle, Context* context = NULL) - : ServiceFactoryBase(shell_handle.Pass()), - context_(context) { - } + ServiceFactory(Context* context = NULL) : context_(context) {} virtual ~ServiceFactory() { - while (!services_.empty()) - delete services_.front(); + for (typename ServiceList::iterator it = services_.begin(); + it != services_.end(); ++it) { + delete *it; + } } - virtual void AcceptConnection(ScopedMessagePipeHandle client_handle) + virtual void AcceptConnection(const std::string& url, + ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE { ServiceImpl* service = new ServiceImpl(); service->Initialize(this, client_handle.Pass()); @@ -90,16 +113,15 @@ class ServiceFactory : public ServiceFactoryBase { it != services_.end(); ++it) { if (*it == service) { services_.erase(it); + delete service; if (services_.empty()) - DisconnectFromShell(); + owner_->RemoveServiceFactory(this); return; } } } - Context* context() const { - return context_; - } + Context* context() const { return context_; } private: typedef std::vector<ServiceImpl*> ServiceList; @@ -114,13 +136,10 @@ class ServiceFactory : public ServiceFactoryBase { template <class ServiceInterface, class ServiceImpl, typename Context=void> class Service : public ServiceInterface { public: - virtual ~Service() { - service_factory_->RemoveService(static_cast<ServiceImpl*>(this)); - } + virtual ~Service() {} protected: - friend class ServiceFactory<ServiceImpl, Context>; - Service() : reaper_(this) {} + Service() : reaper_(this), service_factory_(NULL) {} void Initialize(ServiceFactory<ServiceImpl, Context>* service_factory, ScopedMessagePipeHandle client_handle) { @@ -129,13 +148,11 @@ class Service : public ServiceInterface { MakeScopedHandle( InterfaceHandle<typename ServiceInterface::_Peer>( client_handle.release().value())).Pass(), - this, &reaper_); - } - - Context* context() const { - return service_factory_->context(); + this, + &reaper_); } + Context* context() const { return service_factory_->context(); } typename ServiceInterface::_Peer* client() { return client_.get(); } private: @@ -146,11 +163,13 @@ class Service : public ServiceInterface { Reaper(Service<ServiceInterface, ServiceImpl, Context>* service) : service_(service) {} virtual void OnError() { - delete service_; + service_->service_factory_->RemoveService( + static_cast<ServiceImpl*>(service_)); } private: Service<ServiceInterface, ServiceImpl, Context>* service_; }; + friend class ServiceFactory<ServiceImpl, Context>; Reaper reaper_; ServiceFactory<ServiceImpl, Context>* service_factory_; RemotePtr<typename ServiceInterface::_Peer> client_; |