| 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 |