OLD | NEW |
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 part of html; | 5 part of html; |
6 | 6 |
7 class _ConsoleVariables { | 7 class _ConsoleVariables { |
8 Map<String, Object> _data = new Map<String, Object>(); | 8 Map<String, Object> _data = new Map<String, Object>(); |
9 | 9 |
10 /** | 10 /** |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 } | 99 } |
100 var superclass = reflectClass(type).superclass; | 100 var superclass = reflectClass(type).superclass; |
101 if (superclass != null) { | 101 if (superclass != null) { |
102 return isTypeSubclassOf(superclass.reflectedType, other); | 102 return isTypeSubclassOf(superclass.reflectedType, other); |
103 } | 103 } |
104 return false; | 104 return false; |
105 } | 105 } |
106 | 106 |
107 static window() native "Utils_window"; | 107 static window() native "Utils_window"; |
108 static forwardingPrint(String message) native "Utils_forwardingPrint"; | 108 static forwardingPrint(String message) native "Utils_forwardingPrint"; |
109 static void spawnDomFunction(Function f, int replyTo) native "Utils_spawnDomFu
nction"; | |
110 static int _getNewIsolateId() native "Utils_getNewIsolateId"; | 109 static int _getNewIsolateId() native "Utils_getNewIsolateId"; |
111 | 110 |
112 // The following methods were added for debugger integration to make working | 111 // The following methods were added for debugger integration to make working |
113 // with the Dart C mirrors API simpler. | 112 // with the Dart C mirrors API simpler. |
114 // TODO(jacobr): consider moving them to a separate library. | 113 // TODO(jacobr): consider moving them to a separate library. |
115 // If Dart supported dynamic code injection, we would only inject this code | 114 // If Dart supported dynamic code injection, we would only inject this code |
116 // when the debugger is invoked. | 115 // when the debugger is invoked. |
117 | 116 |
118 /** | 117 /** |
119 * Strips the private secret prefix from member names of the form | 118 * Strips the private secret prefix from member names of the form |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 String remove(String key) native "DOMStringMap_remove_Callback"; | 358 String remove(String key) native "DOMStringMap_remove_Callback"; |
360 void clear() => Maps.clear(this); | 359 void clear() => Maps.clear(this); |
361 void forEach(void f(String key, String value)) => Maps.forEach(this, f); | 360 void forEach(void f(String key, String value)) => Maps.forEach(this, f); |
362 Iterable<String> get keys native "DOMStringMap_getKeys_Callback"; | 361 Iterable<String> get keys native "DOMStringMap_getKeys_Callback"; |
363 Iterable<String> get values => Maps.getValues(this); | 362 Iterable<String> get values => Maps.getValues(this); |
364 int get length => Maps.length(this); | 363 int get length => Maps.length(this); |
365 bool get isEmpty => Maps.isEmpty(this); | 364 bool get isEmpty => Maps.isEmpty(this); |
366 bool get isNotEmpty => Maps.isNotEmpty(this); | 365 bool get isNotEmpty => Maps.isNotEmpty(this); |
367 } | 366 } |
368 | 367 |
369 // TODO(vsm): Remove DOM isolate code. This is only used to support | |
370 // printing and timers in background isolates. Background isolates | |
371 // should just forward to the main DOM isolate instead of requiring a | |
372 // special DOM isolate. | |
373 | |
374 _makeSendPortFuture(spawnRequest) { | |
375 final completer = new Completer<SendPort>.sync(); | |
376 final port = new ReceivePort(); | |
377 port.receive((result, _) { | |
378 completer.complete(result); | |
379 port.close(); | |
380 }); | |
381 // TODO: SendPort.hashCode is ugly way to access port id. | |
382 spawnRequest(port.toSendPort().hashCode); | |
383 return completer.future; | |
384 } | |
385 | |
386 Future<SendPort> _spawnDomFunction(Function f) => | |
387 _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); }); | |
388 | |
389 final Future<SendPort> __HELPER_ISOLATE_PORT = | |
390 _spawnDomFunction(_helperIsolateMain); | |
391 | |
392 // Tricky part. | |
393 // Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then | |
394 // and to delay Timer.run is used. However, Timer.run will try to register | |
395 // another Timer and here we got stuck: event cannot be posted as then | |
396 // callback is not executed because it's delayed with timer. | |
397 // Therefore once future is resolved, it's unsafe to call .then on it | |
398 // in Timer code. | |
399 SendPort __SEND_PORT; | |
400 | |
401 _sendToHelperIsolate(msg, SendPort replyTo) { | |
402 if (__SEND_PORT != null) { | |
403 __SEND_PORT.send(msg, replyTo); | |
404 } else { | |
405 __HELPER_ISOLATE_PORT.then((port) { | |
406 __SEND_PORT = port; | |
407 __SEND_PORT.send(msg, replyTo); | |
408 }); | |
409 } | |
410 } | |
411 | |
412 final _TIMER_REGISTRY = new Map<SendPort, Timer>(); | |
413 | |
414 const _NEW_TIMER = 'NEW_TIMER'; | |
415 const _CANCEL_TIMER = 'CANCEL_TIMER'; | |
416 const _TIMER_PING = 'TIMER_PING'; | |
417 const _PRINT = 'PRINT'; | |
418 | |
419 _helperIsolateMain() { | |
420 port.receive((msg, replyTo) { | |
421 final cmd = msg[0]; | |
422 if (cmd == _NEW_TIMER) { | |
423 final duration = new Duration(milliseconds: msg[1]); | |
424 bool periodic = msg[2]; | |
425 ping() { replyTo.send(_TIMER_PING); }; | |
426 _TIMER_REGISTRY[replyTo] = periodic ? | |
427 new Timer.periodic(duration, (_) { ping(); }) : | |
428 new Timer(duration, ping); | |
429 } else if (cmd == _CANCEL_TIMER) { | |
430 _TIMER_REGISTRY.remove(replyTo).cancel(); | |
431 } else if (cmd == _PRINT) { | |
432 final message = msg[1]; | |
433 // TODO(antonm): we need somehow identify those isolates. | |
434 print('[From isolate] $message'); | |
435 } | |
436 }); | |
437 } | |
438 | |
439 final _printClosure = window.console.log; | 368 final _printClosure = window.console.log; |
440 final _pureIsolatePrintClosure = (s) { | 369 final _pureIsolatePrintClosure = (s) { |
441 _sendToHelperIsolate([_PRINT, s], null); | 370 throw new UnimplementedError("Printing from a background isolate " |
| 371 "is not supported in the browser"); |
442 }; | 372 }; |
443 | 373 |
444 final _forwardingPrintClosure = _Utils.forwardingPrint; | 374 final _forwardingPrintClosure = _Utils.forwardingPrint; |
445 | 375 |
446 class _Timer implements Timer { | 376 class _Timer implements Timer { |
447 var _canceler; | 377 var _canceler; |
448 | 378 |
449 _Timer(int milliSeconds, void callback(Timer timer), bool repeating) { | 379 _Timer(int milliSeconds, void callback(Timer timer), bool repeating) { |
450 | 380 |
451 if (repeating) { | 381 if (repeating) { |
(...skipping 18 matching lines...) Expand all Loading... |
470 } | 400 } |
471 | 401 |
472 bool get isActive => _canceler != null; | 402 bool get isActive => _canceler != null; |
473 } | 403 } |
474 | 404 |
475 get _timerFactoryClosure => | 405 get _timerFactoryClosure => |
476 (int milliSeconds, void callback(Timer timer), bool repeating) { | 406 (int milliSeconds, void callback(Timer timer), bool repeating) { |
477 return new _Timer(milliSeconds, callback, repeating); | 407 return new _Timer(milliSeconds, callback, repeating); |
478 }; | 408 }; |
479 | 409 |
480 | |
481 class _PureIsolateTimer implements Timer { | |
482 bool _isActive = true; | |
483 final ReceivePort _port = new ReceivePort(); | |
484 SendPort _sendPort; // Effectively final. | |
485 | |
486 static SendPort _SEND_PORT; | |
487 | |
488 _PureIsolateTimer(int milliSeconds, callback, repeating) { | |
489 _sendPort = _port.toSendPort(); | |
490 _port.receive((msg, replyTo) { | |
491 assert(msg == _TIMER_PING); | |
492 _isActive = repeating; | |
493 callback(this); | |
494 if (!repeating) _cancel(); | |
495 }); | |
496 | |
497 _send([_NEW_TIMER, milliSeconds, repeating]); | |
498 } | |
499 | |
500 void cancel() { | |
501 _cancel(); | |
502 _send([_CANCEL_TIMER]); | |
503 } | |
504 | |
505 void _cancel() { | |
506 _isActive = false; | |
507 _port.close(); | |
508 } | |
509 | |
510 _send(msg) { | |
511 _sendToHelperIsolate(msg, _sendPort); | |
512 } | |
513 | |
514 bool get isActive => _isActive; | |
515 } | |
516 | |
517 get _pureIsolateTimerFactoryClosure => | 410 get _pureIsolateTimerFactoryClosure => |
518 ((int milliSeconds, void callback(Timer time), bool repeating) => | 411 ((int milliSeconds, void callback(Timer time), bool repeating) => |
519 new _PureIsolateTimer(milliSeconds, callback, repeating)); | 412 throw new UnimplementedError("Timers on background isolates " |
| 413 "are not supported in the browser")); |
OLD | NEW |