Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: mojo/public/cpp/shell/lib/service_connector.h

Issue 287143003: Mojo: Internalize ServiceConnector<> (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add missing function Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mojo/public/cpp/shell/lib/service.cc ('k') | mojo/public/cpp/shell/lib/service_connector.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_PUBLIC_SHELL_SERVICE_H_ 5 #ifndef MOJO_PUBLIC_CPP_SHELL_LIB_SERVICE_CONNECTOR_H_
6 #define MOJO_PUBLIC_SHELL_SERVICE_H_ 6 #define MOJO_PUBLIC_CPP_SHELL_LIB_SERVICE_CONNECTOR_H_
7 7
8 #include <assert.h> 8 #include <assert.h>
9 9
10 #include <vector> 10 #include <vector>
11 11
12 #include "mojo/public/cpp/bindings/allocation_scope.h" 12 #include "mojo/public/cpp/bindings/allocation_scope.h"
13 #include "mojo/public/interfaces/shell/shell.mojom.h" 13 #include "mojo/public/interfaces/shell/shell.mojom.h"
14 14
15 // Utility classes for creating ShellClients that vend service instances.
16 // To use define a class that implements your specific server api, e.g. FooImpl
17 // to implement a service named Foo. That class must define an empty constructor
18 // and the Initialize() method.
19 // class FooImpl : public Foo {
20 // public:
21 // FooImpl();
22 // void Initialize();
23 // private:
24 // ServiceConnector<FooImpl>* service_connector_;
25 // };
26 //
27 //
28 // To simplify further FooImpl can use the ServiceConnection<> template.
29 // class FooImpl : public ServiceConnection<Foo, FooImpl> {
30 // public:
31 // FooImpl();
32 // ...
33 // <Foo implementation>
34 // };
35 //
36 // Instances of FooImpl will be created by a specialized ServiceConnector
37 //
38 // ServiceConnector<FooImpl>
39 //
40 // Optionally the classes can be specializeed with a shared context
41 // class ServiceConnector<FooImpl, MyContext>
42 // and
43 // class FooImpl : public ServiceConnection<Foo, FooImpl, MyContext>
44 //
45 // foo_connector = new ServiceConnector<FooImpl, MyContext>(my_context);
46 // instances of FooImpl can call context() and retrieve the value of my_context.
47 //
48 // Lastly create an Application instance that collects all the
49 // ServiceConnectors.
50 //
51 // Application app(shell_handle);
52 // app.AddServiceConnector(new ServiceConnector<FooImpl>);
53 //
54 //
55 // Specialization of ServiceConnector.
56 // ServiceImpl: Implementation of Service interface.
57 // Context: Optional type of shared context.v
58 //
59 //
60 namespace mojo { 15 namespace mojo {
16 namespace internal {
61 17
62 namespace internal { 18 template <class ServiceImpl, typename Context>
19 class ServiceConnector;
20
21 // Specialization of ServiceConnection.
22 // ServiceImpl: Subclass of InterfaceImpl<...>.
23 // Context: Type of shared context.
24 template <class ServiceImpl, typename Context>
25 class ServiceConnection : public ServiceImpl {
26 public:
27 ServiceConnection() : ServiceImpl() {}
28 ServiceConnection(Context* context) : ServiceImpl(context) {}
29
30 virtual void OnConnectionError() MOJO_OVERRIDE {
31 service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this));
32 ServiceImpl::OnConnectionError();
33 }
34
35 private:
36 friend class ServiceConnector<ServiceImpl, Context>;
37
38 // Called shortly after this class is instantiated.
39 void set_service_connector(
40 ServiceConnector<ServiceImpl, Context>* connector) {
41 service_connector_ = connector;
42 }
43
44 ServiceConnector<ServiceImpl, Context>* service_connector_;
45 };
46
47 template <typename ServiceImpl, typename Context>
48 struct ServiceConstructor {
49 static ServiceConnection<ServiceImpl, Context>* New(Context* context) {
50 return new ServiceConnection<ServiceImpl, Context>(context);
51 }
52 };
53
54 template <typename ServiceImpl>
55 struct ServiceConstructor<ServiceImpl, void> {
56 public:
57 static ServiceConnection<ServiceImpl, void>* New(void* context) {
58 return new ServiceConnection<ServiceImpl, void>();
59 }
60 };
61
63 class ServiceConnectorBase { 62 class ServiceConnectorBase {
64 public: 63 public:
65 class Owner : public ShellClient { 64 class Owner : public ShellClient {
66 public: 65 public:
67 Owner(ScopedMessagePipeHandle shell_handle); 66 Owner(ScopedMessagePipeHandle shell_handle);
68 virtual ~Owner(); 67 virtual ~Owner();
69 Shell* shell() { return shell_.get(); } 68 Shell* shell() { return shell_.get(); }
70 virtual void AddServiceConnector( 69 virtual void AddServiceConnector(
71 internal::ServiceConnectorBase* service_connector) = 0; 70 internal::ServiceConnectorBase* service_connector) = 0;
72 virtual void RemoveServiceConnector( 71 virtual void RemoveServiceConnector(
73 internal::ServiceConnectorBase* service_connector) = 0; 72 internal::ServiceConnectorBase* service_connector) = 0;
74 73
75 protected: 74 protected:
76 void set_service_connector_owner(ServiceConnectorBase* service_connector, 75 void set_service_connector_owner(ServiceConnectorBase* service_connector,
77 Owner* owner) { 76 Owner* owner) {
78 service_connector->owner_ = owner; 77 service_connector->owner_ = owner;
79 } 78 }
80 ShellPtr shell_; 79 ShellPtr shell_;
81 }; 80 };
82 ServiceConnectorBase() : owner_(NULL) {} 81 ServiceConnectorBase() : owner_(NULL) {}
83 virtual ~ServiceConnectorBase(); 82 virtual ~ServiceConnectorBase();
84 Shell* shell() { return owner_->shell(); } 83 Shell* shell() { return owner_->shell(); }
85 virtual void AcceptConnection(const std::string& url, 84 virtual void AcceptConnection(const std::string& url,
86 ScopedMessagePipeHandle client_handle) = 0; 85 ScopedMessagePipeHandle client_handle) = 0;
87 86
88 protected: 87 protected:
89 Owner* owner_; 88 Owner* owner_;
90 }; 89 };
91 } // namespace internal
92 90
93 template <class ServiceImpl, typename Context=void> 91 template <class ServiceImpl, typename Context=void>
94 class ServiceConnector : public internal::ServiceConnectorBase { 92 class ServiceConnector : public internal::ServiceConnectorBase {
95 public: 93 public:
96 ServiceConnector(Context* context = NULL) : context_(context) {} 94 ServiceConnector(Context* context = NULL) : context_(context) {}
97 95
98 virtual ~ServiceConnector() { 96 virtual ~ServiceConnector() {
99 ConnectionList doomed; 97 ConnectionList doomed;
100 doomed.swap(connections_); 98 doomed.swap(connections_);
101 for (typename ConnectionList::iterator it = doomed.begin(); 99 for (typename ConnectionList::iterator it = doomed.begin();
102 it != doomed.end(); ++it) { 100 it != doomed.end(); ++it) {
103 delete *it; 101 delete *it;
104 } 102 }
105 assert(connections_.empty()); // No one should have added more! 103 assert(connections_.empty()); // No one should have added more!
106 } 104 }
107 105
108 virtual void AcceptConnection(const std::string& url, 106 virtual void AcceptConnection(const std::string& url,
109 ScopedMessagePipeHandle handle) MOJO_OVERRIDE { 107 ScopedMessagePipeHandle handle) MOJO_OVERRIDE {
110 ServiceImpl* impl = BindToPipe(new ServiceImpl(), handle.Pass()); 108 ServiceConnection<ServiceImpl, Context>* impl =
111 impl->set_connector(this); 109 ServiceConstructor<ServiceImpl, Context>::New(context_);
110 impl->set_service_connector(this);
111 BindToPipe(impl, handle.Pass());
112 112
113 connections_.push_back(impl); 113 connections_.push_back(impl);
114
115 impl->Initialize();
116 } 114 }
117 115
118 void RemoveConnection(ServiceImpl* impl) { 116 void RemoveConnection(ServiceImpl* impl) {
119 // Called from ~ServiceImpl, in response to a connection error. 117 // Called from ~ServiceImpl, in response to a connection error.
120 for (typename ConnectionList::iterator it = connections_.begin(); 118 for (typename ConnectionList::iterator it = connections_.begin();
121 it != connections_.end(); ++it) { 119 it != connections_.end(); ++it) {
122 if (*it == impl) { 120 if (*it == impl) {
123 delete impl; 121 delete impl;
124 connections_.erase(it); 122 connections_.erase(it);
125 if (connections_.empty()) 123 if (connections_.empty())
126 owner_->RemoveServiceConnector(this); 124 owner_->RemoveServiceConnector(this);
127 return; 125 return;
128 } 126 }
129 } 127 }
130 } 128 }
131 129
132 Context* context() const { return context_; } 130 Context* context() const { return context_; }
133 131
134 private: 132 private:
135 typedef std::vector<ServiceImpl*> ConnectionList; 133 typedef std::vector<ServiceImpl*> ConnectionList;
136 ConnectionList connections_; 134 ConnectionList connections_;
137 Context* context_; 135 Context* context_;
138 }; 136 };
139 137
140 // Specialization of ServiceConnection. 138 } // namespace internal
141 // ServiceInterface: Service interface.
142 // ServiceImpl: Subclass of ServiceConnection<...>.
143 // Context: Optional type of shared context.
144 template <class ServiceInterface, class ServiceImpl, typename Context=void>
145 class ServiceConnection : public InterfaceImpl<ServiceInterface> {
146 protected:
147 // NOTE: shell() and context() are not available at construction time.
148 // Initialize() will be called once those are available.
149 ServiceConnection() : service_connector_(NULL) {}
150
151 virtual ~ServiceConnection() {}
152
153 virtual void OnConnectionError() MOJO_OVERRIDE {
154 service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this));
155 }
156
157 // Shadow this method in ServiceImpl to perform one-time initialization.
158 // At the time this is called, shell() and context() will be available.
159 // NOTE: No need to call the base class Initialize from your subclass. It
160 // will always be a no-op.
161 void Initialize() {}
162
163 Shell* shell() {
164 return service_connector_->shell();
165 }
166
167 Context* context() const {
168 return service_connector_->context();
169 }
170
171 private:
172 friend class ServiceConnector<ServiceImpl, Context>;
173
174 // Called shortly after this class is instantiated.
175 void set_connector(ServiceConnector<ServiceImpl, Context>* connector) {
176 service_connector_ = connector;
177 }
178
179 ServiceConnector<ServiceImpl, Context>* service_connector_;
180 };
181
182 template <typename Interface>
183 inline void ConnectTo(Shell* shell, const std::string& url,
184 InterfacePtr<Interface>* ptr) {
185 MessagePipe pipe;
186 ptr->Bind(pipe.handle0.Pass());
187
188 AllocationScope scope;
189 shell->Connect(url, pipe.handle1.Pass());
190 }
191
192 } // namespace mojo 139 } // namespace mojo
193 140
194 #endif // MOJO_PUBLIC_SHELL_SERVICE_H_ 141 #endif // MOJO_PUBLIC_CPP_SHELL_LIB_SERVICE_CONNECTOR_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/shell/lib/service.cc ('k') | mojo/public/cpp/shell/lib/service_connector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698