OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 // part of dart.async; | |
6 | |
7 /** | |
8 * A basic asynchronous notification. | |
9 */ | |
10 abstract class Signal { | |
11 factory Signal.delayed(int milliseconds) { | |
12 var completer = new SignalCompleter(); | |
13 new Timer(milliseconds, (_) => completer.complete()); | |
14 return completer.signal; | |
15 } | |
16 /** | |
17 * The [onComplete] handler is called when the signal completes. | |
18 * | |
19 * If the signal is already complete, the [onComplete] handler is called | |
20 * as soon as possible, but no sooner than the next time an event is fired. | |
21 */ | |
22 void then(void onComplete()); | |
23 } | |
24 | |
25 typedef _SignalCompleteHandler(); | |
26 | |
27 /** | |
28 * Simple [Signal] controller that creates a [Signal] and allows completing it. | |
29 */ | |
30 class SignalCompleter { | |
31 final Signal signal; | |
32 SignalCompleter() : signal = new _SignalImpl(); | |
33 void complete() { | |
34 _SignalImpl mySignal = signal; | |
35 mySignal._complete(); | |
36 } | |
37 } | |
38 | |
39 /** | |
40 * Simple Signal implementation receiving its completion from a | |
41 * [SignalCompleter]. | |
42 */ | |
43 class _SignalImpl implements Signal { | |
44 /** Single-linked list of "done" event handlers to notify. */ | |
45 _SignalListener _listeners = null; | |
46 | |
47 /** Whether the signal is already completed. */ | |
48 bool _isComplete = false; | |
49 | |
50 void then(void onComplete()) { | |
51 _listeners = new _SignalListener(_listeners, onComplete); | |
52 if (_isComplete) { | |
53 // Schedule the done events as soon as the event queue is ready. | |
54 new Timer(0, (Timer timer) { _sendDone(); }); | |
55 } | |
56 } | |
57 | |
58 /** | |
59 * Complete the signal. | |
60 * | |
61 * This immediately notifies all listeners on the signal. | |
62 */ | |
63 void _complete() { | |
64 assert(!_isComplete); // Only complete once. | |
65 _isComplete = true; | |
66 _sendDone(); | |
67 } | |
68 | |
69 /** | |
70 * Notify all listeners. | |
71 */ | |
72 void _sendDone() { | |
73 while (_listeners != null) { | |
74 _DoneHandler onDone = _listeners.listener; | |
75 _listeners = _listeners.next; | |
76 try { | |
77 onDone(); | |
78 } catch (e, s) { | |
79 new AsyncError(e, s).throwDelayed(); | |
80 } | |
81 } | |
82 } | |
83 } | |
84 | |
85 /** Single-linked list element of the listeners on a [_SignalImpl]. */ | |
86 class _SignalListener { | |
87 _SignalListener next; | |
88 _SignalCompleteHandler listener; | |
89 _SignalListener(this.next, this.listener); | |
90 } | |
OLD | NEW |