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

Side by Side Diff: mojo/dart/packages/mojo/lib/src/proxy.dart

Issue 1964193002: Dart: Refactors Proxies (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Address comments Created 4 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
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 part of bindings; 5 part of bindings;
6 6
7 /// The object that [ProxyMessageHandler.errorFuture] completes with when there
8 /// is an error.
7 class ProxyError { 9 class ProxyError {
8 final String message; 10 final String message;
9 ProxyError(this.message); 11 ProxyError(this.message);
10 String toString() => "ProxyError: $message"; 12 String toString() => "ProxyError: $message";
11 } 13 }
12 14
13 abstract class Proxy extends core.MojoEventHandler { 15 /// Generated ProxyControl classes implement this interface.
16 /// ProxyControl objects are accessible through the [ctrl] field on Proxies.
17 abstract class ProxyControl implements ProxyMessageHandler {
18 String get serviceName;
19 }
20
21 /// Generated Proxy classes extend this base class.
22 class Proxy {
23 // In general it's probalby better to avoid adding fields and methods to this
24 // class. Names added to this class have to be mangled by Mojo bindings
25 // generation to avoid name conflicts.
26
27 /// Proxies control the ProxyMessageHandler by way of this [ProxyControl]
28 /// object.
29 final ProxyControl ctrl;
30
31 Proxy(this.ctrl);
32
33 /// This is a convenience method that simply forwards to ctrl.close().
34 /// If a Mojo interface has a method 'close', its name will be mangled to be
35 /// 'close_'.
36 Future close({bool immediate: false}) => ctrl.close(immediate: immediate);
37
38 /// This is a convenience method that simply forwards to
39 /// ctrl.responseOrError(). If a Mojo interface has a method
40 /// 'responseOrError', its name will be mangled to be 'responseOrError_'.
41 Future responseOrError(Future f) => ctrl.responseOrError(f);
42 }
43
44 /// Generated Proxy classes have a factory Proxy.connectToService which takes
45 /// a ServiceConnector, a url, and optionally a service name and returns a
46 /// bound Proxy. For example, every class extending the Application base class
47 /// in package:mojo/application.dart inherits and implementation of the
48 /// ServiceConnector interface.
49 abstract class ServiceConnector {
50 /// Connects [proxy] to the service called [serviceName] that lives at [url].
51 void connectToService(String url, Proxy proxy, [String serviceName]);
52 }
53
54 class ProxyMessageHandler extends core.MojoEventHandler {
14 HashMap<int, Completer> _completerMap = new HashMap<int, Completer>(); 55 HashMap<int, Completer> _completerMap = new HashMap<int, Completer>();
15 Completer _errorCompleter = new Completer(); 56 Completer _errorCompleter = new Completer();
16 Set<Completer> _errorCompleters; 57 Set<Completer> _errorCompleters;
17 int _nextId = 0; 58 int _nextId = 0;
18 int _version = 0; 59 int _version = 0;
19 int _pendingCount = 0; 60 int _pendingCount = 0;
20 61
21 Proxy.fromEndpoint(core.MojoMessagePipeEndpoint endpoint) 62 ProxyMessageHandler.fromEndpoint(core.MojoMessagePipeEndpoint endpoint)
22 : super.fromEndpoint(endpoint); 63 : super.fromEndpoint(endpoint);
23 64
24 Proxy.fromHandle(core.MojoHandle handle) : super.fromHandle(handle); 65 ProxyMessageHandler.fromHandle(core.MojoHandle handle)
66 : super.fromHandle(handle);
25 67
26 Proxy.unbound() : super.unbound(); 68 ProxyMessageHandler.unbound() : super.unbound();
27 69
28 void handleResponse(ServiceMessage reader); 70 /// The function that handles responses to sent proxy message. It should be
71 /// implemented by the generated ProxyControl classes that extend
72 /// [ProxyMessageHandler].
73 void handleResponse(ServiceMessage msg) {}
29 74
30 /// If there is an error in using this proxy, this future completes with 75 /// If there is an error in using this proxy, this future completes with
31 /// a ProxyError. 76 /// a ProxyError.
32 Future get errorFuture => _errorCompleter.future; 77 Future get errorFuture => _errorCompleter.future;
33 78
34 /// Version of this interface that the remote side supports. Updated when a 79 /// Version of this interface that the remote side supports. Updated when a
35 /// call to [queryVersion] or [requireVersion] is made. 80 /// call to [queryVersion] or [requireVersion] is made.
36 int get version => _version; 81 int get version => _version;
37 82
38 /// Returns a service description, which exposes the mojom type information 83 /// Returns a service description, which exposes the mojom type information
39 /// of the service being proxied. 84 /// of the service being proxied.
40 /// Note: The description is null or incomplete if type info is unavailable. 85 /// Note: The description is null or incomplete if type info is unavailable.
41 service_describer.ServiceDescription get description => null; 86 service_describer.ServiceDescription get description => null;
42 87
88 @override
43 void handleRead() { 89 void handleRead() {
44 var result = endpoint.queryAndRead(); 90 var result = endpoint.queryAndRead();
45 if ((result.data == null) || (result.dataLength == 0)) { 91 if ((result.data == null) || (result.dataLength == 0)) {
46 proxyError("Read from message pipe endpoint failed"); 92 proxyError("Read from message pipe endpoint failed");
47 return; 93 return;
48 } 94 }
49 try { 95 try {
50 var message = new ServiceMessage.fromMessage(new Message(result.data, 96 var message = new ServiceMessage.fromMessage(new Message(result.data,
51 result.handles, result.dataLength, result.handlesLength)); 97 result.handles, result.dataLength, result.handlesLength));
52 _pendingCount--; 98 _pendingCount--;
53 if (ControlMessageHandler.isControlMessage(message)) { 99 if (ControlMessageHandler.isControlMessage(message)) {
54 _handleControlMessageResponse(message); 100 _handleControlMessageResponse(message);
55 return; 101 return;
56 } 102 }
57 handleResponse(message); 103 handleResponse(message);
58 } on MojoCodecError catch (e) { 104 } on MojoCodecError catch (e) {
59 proxyError(e.toString()); 105 proxyError(e.toString());
60 close(immediate: true); 106 close(immediate: true);
61 } 107 }
62 } 108 }
63 109
110 @override
64 void handleWrite() { 111 void handleWrite() {
65 proxyError("Unexpected writable signal"); 112 proxyError("Unexpected writable signal");
66 } 113 }
67 114
68 @override 115 @override
69 Future close({bool immediate: false}) { 116 Future close({bool immediate: false}) {
70 // Drop the completers for outstanding calls. The Futures will never 117 // Drop the completers for outstanding calls. The Futures will never
71 // complete. 118 // complete.
72 _completerMap.clear(); 119 _completerMap.clear();
73 120
74 // Signal to any pending calls that the Proxy is closed. 121 // Signal to any pending calls that the ProxyMessageHandler is closed.
75 if (_pendingCount > 0) { 122 if (_pendingCount > 0) {
76 proxyError("The Proxy is closed."); 123 proxyError("The ProxyMessageHandler is closed.");
77 } 124 }
78 125
79 return super.close(immediate: immediate); 126 return super.close(immediate: immediate);
80 } 127 }
81 128
82 void sendMessage(Struct message, int name) { 129 void sendMessage(Struct message, int name) {
83 if (!isBound) { 130 if (!isBound) {
84 proxyError("The Proxy is closed."); 131 proxyError("The ProxyMessageHandler is closed.");
85 return; 132 return;
86 } 133 }
87 if (!isOpen) { 134 if (!isOpen) {
88 beginHandlingEvents(); 135 beginHandlingEvents();
89 } 136 }
90 var header = new MessageHeader(name); 137 var header = new MessageHeader(name);
91 var serviceMessage = message.serializeWithHeader(header); 138 var serviceMessage = message.serializeWithHeader(header);
92 endpoint.write(serviceMessage.buffer, serviceMessage.buffer.lengthInBytes, 139 endpoint.write(serviceMessage.buffer, serviceMessage.buffer.lengthInBytes,
93 serviceMessage.handles); 140 serviceMessage.handles);
94 if (endpoint.status != core.MojoResult.kOk) { 141 if (endpoint.status != core.MojoResult.kOk) {
95 proxyError("Write to message pipe endpoint failed."); 142 proxyError("Write to message pipe endpoint failed.");
96 } 143 }
97 } 144 }
98 145
99 Future sendMessageWithRequestId(Struct message, int name, int id, int flags) { 146 Future sendMessageWithRequestId(Struct message, int name, int id, int flags) {
100 var completer = new Completer(); 147 var completer = new Completer();
101 if (!isBound) { 148 if (!isBound) {
102 proxyError("The Proxy is closed."); 149 proxyError("The ProxyMessageHandler is closed.");
103 return completer.future; 150 return completer.future;
104 } 151 }
105 if (!isOpen) { 152 if (!isOpen) {
106 beginHandlingEvents(); 153 beginHandlingEvents();
107 } 154 }
108 if (id == -1) { 155 if (id == -1) {
109 id = _nextId++; 156 id = _nextId++;
110 } 157 }
111 158
112 var header = new MessageHeader.withRequestId(name, flags, id); 159 var header = new MessageHeader.withRequestId(name, flags, id);
113 var serviceMessage = message.serializeWithHeader(header); 160 var serviceMessage = message.serializeWithHeader(header);
114 endpoint.write(serviceMessage.buffer, serviceMessage.buffer.lengthInBytes, 161 endpoint.write(serviceMessage.buffer, serviceMessage.buffer.lengthInBytes,
115 serviceMessage.handles); 162 serviceMessage.handles);
116 163
117 if (endpoint.status == core.MojoResult.kOk) { 164 if (endpoint.status == core.MojoResult.kOk) {
118 _completerMap[id] = completer; 165 _completerMap[id] = completer;
119 _pendingCount++; 166 _pendingCount++;
120 } else { 167 } else {
121 proxyError("Write to message pipe endpoint failed: ${endpoint}"); 168 proxyError("Write to message pipe endpoint failed: ${endpoint}");
122 } 169 }
123 return completer.future; 170 return completer.future;
124 } 171 }
125 172
126 // Need a getter for this for access in subclasses. 173 // Need a getter for this for access in subclasses.
127 HashMap<int, Completer> get completerMap => _completerMap; 174 HashMap<int, Completer> get completerMap => _completerMap;
128 175
129 String toString() { 176 String toString() {
130 var superString = super.toString(); 177 var superString = super.toString();
131 return "Proxy(${superString})"; 178 return "ProxyMessageHandler(${superString})";
132 } 179 }
133 180
134 /// Queries the max version that the remote side supports. 181 /// Queries the max version that the remote side supports.
135 /// Updates [version]. 182 /// Updates [version].
136 Future<int> queryVersion() async { 183 Future<int> queryVersion() async {
137 var params = new icm.RunMessageParams(); 184 var params = new icm.RunMessageParams();
138 params.reserved0 = 16; 185 params.reserved0 = 16;
139 params.reserved1 = 0; 186 params.reserved1 = 0;
140 params.queryVersion = new icm.QueryVersion(); 187 params.queryVersion = new icm.QueryVersion();
141 var response = await sendMessageWithRequestId( 188 var response = await sendMessageWithRequestId(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 226 }
180 227
181 /// [responseOrError] returns a [Future] that completes to whatever [f] 228 /// [responseOrError] returns a [Future] that completes to whatever [f]
182 /// completes to unless [errorFuture] completes first. When [errorFuture] 229 /// completes to unless [errorFuture] completes first. When [errorFuture]
183 /// completes first, the [Future] returned by [responseOrError] completes with 230 /// completes first, the [Future] returned by [responseOrError] completes with
184 /// an error using the object that [errorFuture] completed with. 231 /// an error using the object that [errorFuture] completed with.
185 /// 232 ///
186 /// Example usage: 233 /// Example usage:
187 /// 234 ///
188 /// try { 235 /// try {
189 /// result = await MyProxy.responseOrError(MyProxy.ptr.call(a,b,c)); 236 /// result = await myProxy.responseOrError(myProxy.call(a,b,c));
190 /// } catch (e) { 237 /// } catch (e) {
191 /// ... 238 /// ...
192 /// } 239 /// }
193 Future responseOrError(Future f) { 240 Future responseOrError(Future f) {
194 assert(f != null); 241 assert(f != null);
195 if (_errorCompleters == null) { 242 if (_errorCompleters == null) {
196 _errorCompleters = new Set<Completer>(); 243 _errorCompleters = new Set<Completer>();
197 errorFuture.then((e) { 244 errorFuture.then((e) {
198 for (var completer in _errorCompleters) { 245 for (var completer in _errorCompleters) {
199 assert(!completer.isCompleted); 246 assert(!completer.isCompleted);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 return; 281 return;
235 } 282 }
236 completerMap.remove(message.header.requestId); 283 completerMap.remove(message.header.requestId);
237 if (c.isCompleted) { 284 if (c.isCompleted) {
238 proxyError("Control message response completer already completed"); 285 proxyError("Control message response completer already completed");
239 return; 286 return;
240 } 287 }
241 c.complete(response); 288 c.complete(response);
242 } 289 }
243 } 290 }
244
245 /// Generated Proxy classes implement this interface.
246 abstract class ProxyBase {
247 final Proxy impl = null;
248 final String serviceName = null;
249 Object get ptr;
250 }
251
252 /// Generated Proxy classes have a factory Proxy.connectToService which takes
253 /// a ServiceConnector, a url, and optionally a service name and returns a
254 /// bound Proxy. For example, every class extending the Application base class
255 /// in package:mojo/application.dart inherits and implementation of the
256 /// ServiceConnector interface.
257 abstract class ServiceConnector {
258 /// Connects [proxy] to the service called [serviceName] that lives at [url].
259 void connectToService(String url, ProxyBase proxy, [String serviceName]);
260 }
OLDNEW
« no previous file with comments | « mojo/dart/packages/mojo/lib/src/event_subscription.dart ('k') | mojo/dart/packages/mojo/sources.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698