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

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: Cleanup and 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
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 = _call(_id, serialized); 112 var result = _call(_id, serialized);
79 return _deserialize(result); 113 return _deserialize(result);
80 } 114 }
81 115
82 static _call(num id, var message) native @""" 116 static _call(num id, var message) native @"""
83 return ReceivePortSync.dispatchCall(id, message); 117 return ReceivePortSync.dispatchCall(id, message);
84 """; 118 """;
85 119
86 } 120 }
121
122 // TODO(vsm): Handle Dartium isolates.
123 // The receiver is a different Dart isolate, compiled to JS.
124 class _RemoteSendPortSync implements SendPortSync {
125
126 int _isolateId;
127 int _portId;
128 _RemoteSendPortSync(this._isolateId, this._portId);
129
130 callSync(var message) {
131 var serialized = _serialize(message);
132 var result = _call(_isolateId, _portId, serialized);
133 return _deserialize(result);
134 }
135
136 static _call(int isolateId, int portId, var message) {
137 var target = 'dart-port-$isolateId-$portId';
138 // TODO(vsm): Make this re-entrant.
139 // TODO(vsm): Set this up set once, on the first call.
140 var source = '$target-result';
141 var result = null;
142 var listener = (TextEvent e) {
143 result = JSON.parse(e.data);
144 };
145 window.on[source].add(listener);
146 _dispatchEvent(target, [source, message]);
147 window.on[source].remove(listener);
148 return result;
149 }
150 }
151
152 // The receiver is in the same Dart isolate, compiled to JS.
153 class _LocalSendPortSync implements SendPortSync {
154
155 ReceivePortSync _receivePort;
156
157 _LocalSendPortSync._internal(this._receivePort);
158
159 callSync(var message) {
160 // TODO(vsm): Do a more efficient deep copy.
161 var copy = _deserialize(_serialize(message));
162 var result = _receivePort._callback(copy);
163 return _deserialize(_serialize(result));
164 }
165 }
166
167 // TODO(vsm): Move this to dart:isolate. This will take some
168 // refactoring as there are dependences here on the DOM. Users
169 // interact with this class (or interface if we change it) directly -
170 // new ReceivePortSync. I think most of the DOM logic could be
171 // delayed until the corresponding SendPort is registered on the
172 // window.
173
174 // A Dart2JS ReceivePortSync (tagged 'dart2js' when serialized) is
175 // identifiable / resolvable by the combination of its isolateid and
176 // portid. When a corresponding SendPort is used within the same
177 // isolate, the _portMap below can be used to obtain the
178 // ReceivePortSync directly. Across isolates (or from JS), an
179 // EventListener can be used to communicate with the port indirectly.
180 class ReceivePortSync {
181
182 static Map<int, ReceivePortSync> _portMap;
183 static int _portIdCount;
184 static int _cachedIsolateId;
185
186 num _portId;
187 Function _callback;
188 EventListener _listener;
189
190 ReceivePortSync() {
191 if (_portIdCount == null) {
192 _portIdCount = 0;
193 _portMap = new Map<int, ReceivePortSync>();
194 }
195 _portId = _portIdCount++;
196 _portMap[_portId] = this;
197 }
198
199 static int get _isolateId() {
200 // TODO(vsm): Make this coherent with existing isolate code.
201 if (_cachedIsolateId == null) {
202 _cachedIsolateId = _getNewIsolateId();
203 }
204 return _cachedIsolateId;
205 }
206
207 static int _getNewIsolateId() native @'''
208 if (!window.$dart$isolate$counter) {
209 window.$dart$isolate$counter = 1;
210 }
211 return window.$dart$isolate$counter++;
212 ''';
213
214 static String _getListenerName(isolateId, portId) =>
215 'dart-port-$isolateId-$portId';
216 String get _listenerName() => _getListenerName(_isolateId, _portId);
217
218 void receive(callback(var message)) {
219 // Clear old listener.
220 if (_callback != null) {
221 window.on[_listenerName].remove(_listener);
222 }
223
224 _callback = callback;
225
226 // Install new listener.
227 var sendport = toSendPort();
228 _listener = (TextEvent e) {
229 var data = JSON.parse(e.data);
230 var replyTo = data[0];
231 var message = _deserialize(data[1]);
232 var result = sendport.callSync(message);
233 _dispatchEvent(replyTo, _serialize(result));
234 };
235 window.on[_listenerName].add(_listener);
236 }
237
238 void close() {
239 _portMap.remove(_portId);
240 window.on[_listenerName].remove(_listener);
241 }
242
243 SendPortSync toSendPort() {
244 return new _LocalSendPortSync._internal(this);
245 }
246
247 static SendPortSync _lookup(int isolateId, int portId) {
248 if (isolateId == _isolateId) {
249 return _portMap[portId].toSendPort();
250 } else {
251 return new _RemoteSendPortSync(isolateId, portId);
252 }
253 }
254 }
255
256 void _dispatchEvent(String receiver, var message) {
257 var event = document.$dom_createEvent('TextEvent');
258 event.initTextEvent(receiver, false, false, window, JSON.stringify(message));
259 window.$dom_dispatchEvent(event);
260 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698