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

Side by Side Diff: lib/dom/templates/html/frog/html_frog.darttemplate

Issue 10695111: Add support for JS->Dart and Dart->dart via *PortSync. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 years, 5 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 | « client/dart.js ('k') | lib/dom/templates/html/frog/impl_Window.darttemplate » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // DO NOT EDIT 5 // DO NOT EDIT
6 // Auto-generated dart:html library. 6 // Auto-generated dart:html library.
7 7
8 #library('html'); 8 #library('html');
9 9
10 #import('dart:isolate'); 10 #import('dart:isolate');
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 Element query(String selector) => _document.query(selector); 44 Element query(String selector) => _document.query(selector);
45 ElementList queryAll(String selector) => _document.queryAll(selector); 45 ElementList queryAll(String selector) => _document.queryAll(selector);
46 46
47 // Workaround for tags like <cite> that lack their own Element subclass -- 47 // Workaround for tags like <cite> that lack their own Element subclass --
48 // Dart issue 1990. 48 // Dart issue 1990.
49 class _HTMLElementImpl extends _ElementImpl native "*HTMLElement" { 49 class _HTMLElementImpl extends _ElementImpl native "*HTMLElement" {
50 } 50 }
51 51
52 // TODO(vsm): Move this to a separate Isolates.dart file. 52 // TODO(vsm): Move this to a separate Isolates.dart file.
53 _serialize(var message) { 53 _serialize(var message) {
54 // TODO(kasperl): Specialize the serializer. 54 return new _JsSerializer().traverse(message);
55 return new _Serializer().traverse(message); 55 }
56
57 class _JsSerializer extends _Serializer {
58
59 visitSendPortSync(SendPortSync x) {
60 if (x is _JsSendPortSync) return visitJsSendPortSync(x);
61 if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
62 if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
63 throw "Illegal underlying port $x";
64 }
65
66 visitJsSendPortSync(_JsSendPortSync x) {
67 return [ 'sendport', 'nativejs', x._id ];
68 }
69
70 visitLocalSendPortSync(_LocalSendPortSync x) {
71 return [ 'sendport', 'dart2js',
72 ReceivePortSync._isolateId, x._receivePort._portId ];
73 }
74
75 visitRemoteSendPortSync(_RemoteSendPortSync x) {
76 return [ 'sendport', 'dart2js',
77 x._receivePort._isolateId, x._receivePort._portId ];
78 }
56 } 79 }
57 80
58 _deserialize(var message) { 81 _deserialize(var message) {
59 return new _JsDeserializer().deserialize(message); 82 return new _JsDeserializer().deserialize(message);
60 } 83 }
61 84
62 class _JsDeserializer extends _Deserializer { 85 class _JsDeserializer extends _Deserializer {
63 86
64 deserializeSendPort(List x) { 87 deserializeSendPort(List x) {
65 num id = x[1]; 88 String tag = x[1];
66 return new _JsSendPortSync(id); 89 switch (tag) {
90 case 'nativejs':
91 num id = x[2];
92 return new _JsSendPortSync(id);
93 case 'dart2js':
94 num isolateId = x[2];
95 num portId = x[3];
96 return ReceivePortSync._lookup(isolateId, portId);
97 default:
98 throw 'Illegal SendPortSync type: $tag';
99 }
67 } 100 }
68 101
69 } 102 }
70 103
104 // The receiver is JS.
71 class _JsSendPortSync implements SendPortSync { 105 class _JsSendPortSync implements SendPortSync {
72 106
73 num _id; 107 num _id;
74 _JsSendPortSync(this._id); 108 _JsSendPortSync(this._id);
75 109
76 callSync(var message) { 110 callSync(var message) {
77 var serialized = _serialize(message); 111 var serialized = _serialize(message);
78 var result = 112 var result =
79 JS('var', @'ReceivePortSync.dispatchCall(#, #)', _id, serialized); 113 JS('var', @'ReceivePortSync.dispatchCall(#, #)', _id, serialized);
80 return _deserialize(result); 114 return _deserialize(result);
81 } 115 }
82 116
83 } 117 }
118
119 // TODO(vsm): Handle Dartium isolates.
120 // The receiver is a different Dart isolate, compiled to JS.
121 class _RemoteSendPortSync implements SendPortSync {
122
123 int _isolateId;
124 int _portId;
125 _RemoteSendPortSync(this._isolateId, this._portId);
126
127 callSync(var message) {
128 var serialized = _serialize(message);
129 var result = _call(_isolateId, _portId, serialized);
130 return _deserialize(result);
131 }
132
133 static _call(int isolateId, int portId, var message) {
134 var target = 'dart-port-$isolateId-$portId';
135 // TODO(vsm): Make this re-entrant.
136 // TODO(vsm): Set this up set once, on the first call.
137 var source = '$target-result';
138 var result = null;
139 var listener = (TextEvent e) {
140 result = JSON.parse(e.data);
141 };
142 window.on[source].add(listener);
143 _dispatchEvent(target, [source, message]);
144 window.on[source].remove(listener);
145 return result;
146 }
147 }
148
149 // The receiver is in the same Dart isolate, compiled to JS.
150 class _LocalSendPortSync implements SendPortSync {
151
152 ReceivePortSync _receivePort;
153
154 _LocalSendPortSync._internal(this._receivePort);
155
156 callSync(var message) {
157 // TODO(vsm): Do a more efficient deep copy.
158 var copy = _deserialize(_serialize(message));
159 var result = _receivePort._callback(copy);
160 return _deserialize(_serialize(result));
161 }
162 }
163
164 // TODO(vsm): Move this to dart:isolate. This will take some
165 // refactoring as there are dependences here on the DOM. Users
166 // interact with this class (or interface if we change it) directly -
167 // new ReceivePortSync. I think most of the DOM logic could be
168 // delayed until the corresponding SendPort is registered on the
169 // window.
170
171 // A Dart2JS ReceivePortSync (tagged 'dart2js' when serialized) is
172 // identifiable / resolvable by the combination of its isolateid and
173 // portid. When a corresponding SendPort is used within the same
174 // isolate, the _portMap below can be used to obtain the
175 // ReceivePortSync directly. Across isolates (or from JS), an
176 // EventListener can be used to communicate with the port indirectly.
177 class ReceivePortSync {
178
179 static Map<int, ReceivePortSync> _portMap;
180 static int _portIdCount;
181 static int _cachedIsolateId;
182
183 num _portId;
184 Function _callback;
185 EventListener _listener;
186
187 ReceivePortSync() {
188 if (_portIdCount == null) {
189 _portIdCount = 0;
190 _portMap = new Map<int, ReceivePortSync>();
191 }
192 _portId = _portIdCount++;
193 _portMap[_portId] = this;
194 }
195
196 static int get _isolateId() {
197 // TODO(vsm): Make this coherent with existing isolate code.
198 if (_cachedIsolateId == null) {
199 _cachedIsolateId = _getNewIsolateId();
200 }
201 return _cachedIsolateId;
202 }
203
204 static int _getNewIsolateId() native @'''
205 if (!window.$dart$isolate$counter) {
206 window.$dart$isolate$counter = 1;
207 }
208 return window.$dart$isolate$counter++;
209 ''';
210
211 static String _getListenerName(isolateId, portId) =>
212 'dart-port-$isolateId-$portId';
213 String get _listenerName() => _getListenerName(_isolateId, _portId);
214
215 void receive(callback(var message)) {
216 // Clear old listener.
217 if (_callback != null) {
218 window.on[_listenerName].remove(_listener);
219 }
220
221 _callback = callback;
222
223 // Install new listener.
224 var sendport = toSendPort();
225 _listener = (TextEvent e) {
226 var data = JSON.parse(e.data);
227 var replyTo = data[0];
228 var message = _deserialize(data[1]);
229 var result = sendport.callSync(message);
230 _dispatchEvent(replyTo, _serialize(result));
231 };
232 window.on[_listenerName].add(_listener);
233 }
234
235 void close() {
236 _portMap.remove(_portId);
237 window.on[_listenerName].remove(_listener);
238 }
239
240 SendPortSync toSendPort() {
241 return new _LocalSendPortSync._internal(this);
242 }
243
244 static SendPortSync _lookup(int isolateId, int portId) {
245 if (isolateId == _isolateId) {
246 return _portMap[portId].toSendPort();
247 } else {
248 return new _RemoteSendPortSync(isolateId, portId);
249 }
250 }
251 }
252
253 void _dispatchEvent(String receiver, var message) {
254 var event = document.$dom_createEvent('TextEvent');
255 event.initTextEvent(receiver, false, false, window, JSON.stringify(message));
256 window.$dom_dispatchEvent(event);
257 }
OLDNEW
« no previous file with comments | « client/dart.js ('k') | lib/dom/templates/html/frog/impl_Window.darttemplate » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698