Index: sdk/lib/async/zone.dart |
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart |
index 24f83f8bd8ba69a5ce7468aa031005d93a9d2266..14b9f885e23f9d1ce511e64c060300653dcf89f5 100644 |
--- a/sdk/lib/async/zone.dart |
+++ b/sdk/lib/async/zone.dart |
@@ -8,6 +8,13 @@ typedef R ZoneCallback<R>(); |
typedef R ZoneUnaryCallback<R, T>(T arg); |
typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2); |
+/// *Experimental*. Might disappear without warning. |
+typedef T TaskCreate<T, S extends TaskSpecification>( |
+ S specification, Zone zone); |
+/// *Experimental*. Might disappear without warning. |
+typedef void TaskRun<T, A>(T task, A arg); |
+ |
+ |
// TODO(floitsch): we are abusing generic typedefs as typedefs for generic |
// functions. |
/*ABUSE*/ |
@@ -33,19 +40,31 @@ typedef ZoneBinaryCallback<R, T1, T2> RegisterBinaryCallbackHandler<R, T1, T2>( |
Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)); |
typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent, |
Zone zone, Object error, StackTrace stackTrace); |
+/// *Experimental*. Might disappear without warning. |
+/*ABUSE*/ |
+typedef T CreateTaskHandler<T, S extends TaskSpecification>( |
+ Zone self, ZoneDelegate parent, Zone zone, |
+ TaskCreate<T, S> create, S taskSpecification); |
+/// *Experimental*. Might disappear without warning. |
+/*ABUSE*/ |
+typedef void RunTaskHandler<T, A>(Zone self, ZoneDelegate parent, Zone zone, |
+ TaskRun<T, A> run, T task, A arg); |
typedef void ScheduleMicrotaskHandler( |
Zone self, ZoneDelegate parent, Zone zone, void f()); |
-typedef Timer CreateTimerHandler( |
- Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f()); |
-typedef Timer CreatePeriodicTimerHandler( |
- Zone self, ZoneDelegate parent, Zone zone, |
- Duration period, void f(Timer timer)); |
typedef void PrintHandler( |
Zone self, ZoneDelegate parent, Zone zone, String line); |
typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone, |
ZoneSpecification specification, |
Map zoneValues); |
+// The following typedef declarations are used by functionality which |
+// will be removed and replaced by tasksif the task experiment is successful. |
+typedef Timer CreateTimerHandler( |
+ Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f()); |
+typedef Timer CreatePeriodicTimerHandler( |
+ Zone self, ZoneDelegate parent, Zone zone, |
+ Duration period, void f(Timer timer)); |
+ |
/** Pair of error and stack trace. Returned by [Zone.errorCallback]. */ |
class AsyncError implements Error { |
final Object error; |
@@ -56,10 +75,41 @@ class AsyncError implements Error { |
String toString() => '$error'; |
} |
+/** |
+ * A task specification contains the necessary information to create a task. |
+ * |
+ * See [Zone.createTask] for how a specification is used to create a task. |
+ * |
+ * Task specifications should be public and it should be possible to create |
+ * new instances as a user. That is, custom zones should be able to replace |
+ * an existing specification with a modified one. |
+ * |
+ * *Experimental*. This class might disappear without warning. |
+ */ |
+abstract class TaskSpecification { |
+ /** |
+ * Description of the task. |
+ * |
+ * This string is unused by the root-zone, but might be used for debugging, |
+ * and testing. As such, it should be relatively unique in its category. |
+ * |
+ * As a general guideline we recommend: "package-name.library.action". |
+ */ |
+ String get name; |
+ |
+ /** |
+ * Whether the scheduled task triggers at most once. |
+ * |
+ * If the task is not a one-shot task, it may need to be canceled to prevent |
+ * further iterations of the task. |
+ */ |
+ bool get isOneShot; |
+} |
class _ZoneFunction<T extends Function> { |
final _Zone zone; |
final T function; |
+ |
const _ZoneFunction(this.zone, this.function); |
} |
@@ -85,6 +135,9 @@ class _ZoneFunction<T extends Function> { |
abstract class ZoneSpecification { |
/** |
* Creates a specification with the provided handlers. |
+ * |
+ * The task-related parameters ([createTask] and [runTask]) are experimental |
+ * and might be removed without warning. |
*/ |
const factory ZoneSpecification({ |
HandleUncaughtErrorHandler handleUncaughtError, |
@@ -96,7 +149,11 @@ abstract class ZoneSpecification { |
RegisterBinaryCallbackHandler registerBinaryCallback, |
ErrorCallbackHandler errorCallback, |
ScheduleMicrotaskHandler scheduleMicrotask, |
+ CreateTaskHandler createTask, |
+ RunTaskHandler runTask, |
+ // TODO(floitsch): mark as deprecated once tasks are non-experimental. |
CreateTimerHandler createTimer, |
+ // TODO(floitsch): mark as deprecated once tasks are non-experimental. |
CreatePeriodicTimerHandler createPeriodicTimer, |
PrintHandler print, |
ForkHandler fork |
@@ -105,6 +162,9 @@ abstract class ZoneSpecification { |
/** |
* Creates a specification from [other] with the provided handlers overriding |
* the ones in [other]. |
+ * |
+ * The task-related parameters ([createTask] and [runTask]) are experimental |
+ * and might be removed without warning. |
*/ |
factory ZoneSpecification.from(ZoneSpecification other, { |
HandleUncaughtErrorHandler handleUncaughtError: null, |
@@ -116,7 +176,11 @@ abstract class ZoneSpecification { |
RegisterBinaryCallbackHandler registerBinaryCallback: null, |
ErrorCallbackHandler errorCallback: null, |
ScheduleMicrotaskHandler scheduleMicrotask: null, |
+ CreateTaskHandler createTask: null, |
+ RunTaskHandler runTask: null, |
+ // TODO(floitsch): mark as deprecated once tasks are non-experimental. |
CreateTimerHandler createTimer: null, |
+ // TODO(floitsch): mark as deprecated once tasks are non-experimental. |
CreatePeriodicTimerHandler createPeriodicTimer: null, |
PrintHandler print: null, |
ForkHandler fork: null |
@@ -132,11 +196,14 @@ abstract class ZoneSpecification { |
registerBinaryCallback: registerBinaryCallback ?? |
other.registerBinaryCallback, |
errorCallback: errorCallback ?? other.errorCallback, |
+ |
+ createTask: createTask ?? other.createTask, |
+ runTask: runTask ?? other.runTask, |
+ print : print ?? other.print, |
+ fork: fork ?? other.fork, |
scheduleMicrotask: scheduleMicrotask ?? other.scheduleMicrotask, |
createTimer : createTimer ?? other.createTimer, |
- createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer, |
- print : print ?? other.print, |
- fork: fork ?? other.fork); |
+ createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer); |
} |
HandleUncaughtErrorHandler get handleUncaughtError; |
@@ -148,10 +215,17 @@ abstract class ZoneSpecification { |
RegisterBinaryCallbackHandler get registerBinaryCallback; |
ErrorCallbackHandler get errorCallback; |
ScheduleMicrotaskHandler get scheduleMicrotask; |
- CreateTimerHandler get createTimer; |
- CreatePeriodicTimerHandler get createPeriodicTimer; |
+ /// *Experimental*. Might disappear without warning. |
+ CreateTaskHandler get createTask; |
+ /// *Experimental*. Might disappear without warning. |
+ RunTaskHandler get runTask; |
PrintHandler get print; |
ForkHandler get fork; |
+ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ CreateTimerHandler get createTimer; |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ CreatePeriodicTimerHandler get createPeriodicTimer; |
} |
/** |
@@ -172,10 +246,14 @@ class _ZoneSpecification implements ZoneSpecification { |
this.registerBinaryCallback: null, |
this.errorCallback: null, |
this.scheduleMicrotask: null, |
- this.createTimer: null, |
- this.createPeriodicTimer: null, |
+ this.createTask: null, |
+ this.runTask: null, |
this.print: null, |
- this.fork: null |
+ this.fork: null, |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ this.createTimer: null, |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ this.createPeriodicTimer: null |
}); |
final HandleUncaughtErrorHandler handleUncaughtError; |
@@ -187,10 +265,15 @@ class _ZoneSpecification implements ZoneSpecification { |
final RegisterBinaryCallbackHandler registerBinaryCallback; |
final ErrorCallbackHandler errorCallback; |
final ScheduleMicrotaskHandler scheduleMicrotask; |
- final CreateTimerHandler createTimer; |
- final CreatePeriodicTimerHandler createPeriodicTimer; |
+ final CreateTaskHandler createTask; |
+ final RunTaskHandler runTask; |
final PrintHandler print; |
final ForkHandler fork; |
+ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ final CreateTimerHandler createTimer; |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ final CreatePeriodicTimerHandler createPeriodicTimer; |
} |
/** |
@@ -217,10 +300,23 @@ abstract class ZoneDelegate { |
Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)); |
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace); |
void scheduleMicrotask(Zone zone, void f()); |
- Timer createTimer(Zone zone, Duration duration, void f()); |
- Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); |
+ |
+ /// *Experimental*. Might disappear without notice. |
+ Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/( |
+ Zone zone, TaskCreate/*<T, S>*/ create, |
+ TaskSpecification/*=S*/ specification); |
+ /// *Experimental*. Might disappear without notice. |
+ void runTask/*<T, A>*/( |
+ Zone zone, TaskRun/*<T, A>*/ run, Object/*=T*/ task, |
+ Object/*=A*/ argument); |
+ |
void print(Zone zone, String line); |
Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues); |
+ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ Timer createTimer(Zone zone, Duration duration, void f()); |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); |
} |
/** |
@@ -411,13 +507,100 @@ abstract class Zone { |
void scheduleMicrotask(void f()); |
/** |
+ * Creates a task in the current zone. |
+ * |
+ * A task represents an asynchronous operation or process that reports back |
+ * through the event loop. |
+ * |
+ * This function allows the zone to intercept the initialization of the |
+ * task while the [runTask] function is invoked when the task reports back. |
+ * |
+ * By default, in the root zone, the [create] function is invoked with the |
+ * [specification] as argument. It returns a task object which is used for all |
+ * future interactions between the zone and the task. The object is |
+ * a unique instance representing the task. It is generally returned to |
+ * whoever initiated the task. |
+ * For example, the HTML library uses the returned [StreamSubscription] as |
+ * task object when users register an event listener. |
+ * |
+ * Tasks are created when the program starts an operation that reports back |
+ * through the event loop. For example, a timer or an HTTP request both |
+ * return through the event loop and are therefore tasks. |
+ * |
+ * If the [create] function is not invoked (because a custom zone has |
+ * replaced or intercepted it), then the operation is *not* started. This |
+ * means that a custom zone can intercept tasks, like HTTP requests. |
+ * |
+ * A task goes through the following steps: |
+ * - a user invokes a library function that should eventually return through |
+ * the event loop. |
+ * - the library function creates a [TaskSpecification] that contains the |
+ * necessary information to start the operation, and invokes |
+ * `Zone.current.createTask` with the specification and a [create] closure. |
+ * The closure, when invoked, uses the specification to start the operation |
+ * (usually by interacting with the underlying system, or as a native |
+ * extension), and returns a task object that identifies the running task. |
+ * - custom zones handle the request and (unless completely intercepted and |
+ * aborted), end up calling the root zone's [createTask] which runs the |
+ * provided `create` closure, which may have been replaced at this point. |
+ * - later, the asynchronous operation returns through the event loop. |
+ * It invokes [Zone.runTask] on the zone in which the task should run |
+ * (and which was originally passed to the `create` function by |
+ * `createTask`). The [runTask] function receives the |
+ * task object, a `run` function and an argument. As before, custom zones |
+ * may intercept this call. Eventually (unless aborted), the `run` function |
+ * is invoked. This last step may happen multiple times for tasks that are |
+ * not oneshot tasks (see [ZoneSpecification.isOneShot]). |
+ * |
+ * Custom zones may replace the [specification] with a different one, thus |
+ * modifying the task parameters. An operation that wishes to be an |
+ * interceptable task must publicly specify the types that intercepting code |
+ * sees: |
+ * - The specification type (extending [TaskSpecification]) which holds the |
+ * information available when intercepting the `createTask` call. |
+ * - The task object type, returned by `createTask` and [create]. This object |
+ * may simply be typed as [Object]. |
+ * - The argument type, if [runTask] takes a meaningful argument. |
+ * |
+ * *Experimental*. Might disappear without notice. |
+ */ |
+ Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/( |
+ /*=T*/ create(TaskSpecification/*=S*/ specification, Zone zone), |
+ TaskSpecification/*=S*/ specification); |
+ |
+ /** |
+ * Runs a task callback. |
+ * |
+ * This function is invoked, when an operation, started through [createTask], |
+ * generates an event. |
+ * |
+ * Generally, tasks schedule Dart code in the global event loop when the |
+ * [createTask] function is invoked. Since the |
+ * event loop does not expect any return value from the code it runs, the |
+ * [runTask] function is a void function. |
+ * |
+ * The [task] object must be the same as the one created with [createTask]. |
+ * |
+ * It is good practice that task operations provide a meaningful [argument], |
+ * so that custom zones can interact with it. They might want to log or |
+ * replace the argument before calling the [run] function. |
+ * |
+ * *Experimental*. Might disappear without notice. |
+ */ |
+ void runTask/*<T, A>*/( |
+ /*=T*/ run(/*=T*/ task, /*=A*/ argument), Object/*=T*/ task, |
+ Object/*=A*/ argument); |
+ |
+ /** |
* Creates a Timer where the callback is executed in this zone. |
*/ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
Timer createTimer(Duration duration, void callback()); |
/** |
* Creates a periodic Timer where the callback is executed in this zone. |
*/ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
Timer createPeriodicTimer(Duration period, void callback(Timer timer)); |
/** |
@@ -523,7 +706,7 @@ class _ZoneDelegate implements ZoneDelegate { |
// TODO(floitsch): make this a generic method call on '<R>' once it's |
// supported. Remove the unnecessary cast. |
return handler(implZone, _parentDelegate(implZone), zone, f) |
- as Object/*=ZoneCallback<R>*/; |
+ as dynamic/*=ZoneCallback<R>*/; |
} |
ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( |
@@ -534,7 +717,7 @@ class _ZoneDelegate implements ZoneDelegate { |
// TODO(floitsch): make this a generic method call on '<R, T>' once it's |
// supported. Remove the unnecessary cast. |
return handler(implZone, _parentDelegate(implZone), zone, f) |
- as Object/*=ZoneUnaryCallback<R, T>*/; |
+ as dynamic/*=ZoneUnaryCallback<R, T>*/; |
} |
ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/( |
@@ -545,7 +728,7 @@ class _ZoneDelegate implements ZoneDelegate { |
// TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
// it's supported. Remove the unnecessary cast. |
return handler(implZone, _parentDelegate(implZone), zone, f) |
- as Object/*=ZoneBinaryCallback<R, T1, T2>*/; |
+ as dynamic/*=ZoneBinaryCallback<R, T1, T2>*/; |
} |
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) { |
@@ -564,18 +747,25 @@ class _ZoneDelegate implements ZoneDelegate { |
handler(implZone, _parentDelegate(implZone), zone, f); |
} |
- Timer createTimer(Zone zone, Duration duration, void f()) { |
- var implementation = _delegationTarget._createTimer; |
+ Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/( |
+ Zone zone, TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification) { |
+ var implementation = _delegationTarget._createTask; |
_Zone implZone = implementation.zone; |
- CreateTimerHandler handler = implementation.function; |
- return handler(implZone, _parentDelegate(implZone), zone, duration, f); |
+ // TODO(floitsch): make the handler call a generic method call on '<T, S>' |
+ // once it's supported. Remove the unnecessary cast. |
+ var handler = |
+ implementation.function as CreateTaskHandler/*<T, S>*/; |
+ return handler( |
+ implZone, _parentDelegate(implZone), zone, create, specification); |
} |
- Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) { |
- var implementation = _delegationTarget._createPeriodicTimer; |
+ void runTask/*<T, A>*/(Zone zone, TaskRun run, Object /*=T*/ task, |
+ Object /*=A*/ argument) { |
+ var implementation = _delegationTarget._runTask; |
_Zone implZone = implementation.zone; |
- CreatePeriodicTimerHandler handler = implementation.function; |
- return handler(implZone, _parentDelegate(implZone), zone, period, f); |
+ RunTaskHandler handler = implementation.function; |
+ // TODO(floitsch): make this a generic call on '<T, A>'. |
+ handler(implZone, _parentDelegate(implZone), zone, run, task, argument); |
} |
void print(Zone zone, String line) { |
@@ -593,6 +783,22 @@ class _ZoneDelegate implements ZoneDelegate { |
return handler( |
implZone, _parentDelegate(implZone), zone, specification, zoneValues); |
} |
+ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ Timer createTimer(Zone zone, Duration duration, void f()) { |
+ var implementation = _delegationTarget._createTimer; |
+ _Zone implZone = implementation.zone; |
+ CreateTimerHandler handler = implementation.function; |
+ return handler(implZone, _parentDelegate(implZone), zone, duration, f); |
+ } |
+ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) { |
+ var implementation = _delegationTarget._createPeriodicTimer; |
+ _Zone implZone = implementation.zone; |
+ CreatePeriodicTimerHandler handler = implementation.function; |
+ return handler(implZone, _parentDelegate(implZone), zone, period, f); |
+ } |
} |
@@ -610,11 +816,17 @@ abstract class _Zone implements Zone { |
_ZoneFunction<RegisterBinaryCallbackHandler> get _registerBinaryCallback; |
_ZoneFunction<ErrorCallbackHandler> get _errorCallback; |
_ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask; |
- _ZoneFunction<CreateTimerHandler> get _createTimer; |
- _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer; |
+ _ZoneFunction<CreateTaskHandler> get _createTask; |
+ _ZoneFunction<RunTaskHandler> get _runTask; |
_ZoneFunction<PrintHandler> get _print; |
_ZoneFunction<ForkHandler> get _fork; |
_ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError; |
+ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ _ZoneFunction<CreateTimerHandler> get _createTimer; |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer; |
+ |
_Zone get parent; |
ZoneDelegate get _delegate; |
Map get _map; |
@@ -636,12 +848,17 @@ class _CustomZone extends _Zone { |
_ZoneFunction<RegisterBinaryCallbackHandler> _registerBinaryCallback; |
_ZoneFunction<ErrorCallbackHandler> _errorCallback; |
_ZoneFunction<ScheduleMicrotaskHandler> _scheduleMicrotask; |
- _ZoneFunction<CreateTimerHandler> _createTimer; |
- _ZoneFunction<CreatePeriodicTimerHandler> _createPeriodicTimer; |
+ _ZoneFunction<CreateTaskHandler> _createTask; |
+ _ZoneFunction<RunTaskHandler> _runTask; |
_ZoneFunction<PrintHandler> _print; |
_ZoneFunction<ForkHandler> _fork; |
_ZoneFunction<HandleUncaughtErrorHandler> _handleUncaughtError; |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ _ZoneFunction<CreateTimerHandler> _createTimer; |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ _ZoneFunction<CreatePeriodicTimerHandler> _createPeriodicTimer; |
+ |
// A cached delegate to this zone. |
ZoneDelegate _delegateCache; |
@@ -692,13 +909,14 @@ class _CustomZone extends _Zone { |
? new _ZoneFunction<ScheduleMicrotaskHandler>( |
this, specification.scheduleMicrotask) |
: parent._scheduleMicrotask; |
- _createTimer = (specification.createTimer != null) |
- ? new _ZoneFunction<CreateTimerHandler>(this, specification.createTimer) |
- : parent._createTimer; |
- _createPeriodicTimer = (specification.createPeriodicTimer != null) |
- ? new _ZoneFunction<CreatePeriodicTimerHandler>( |
- this, specification.createPeriodicTimer) |
- : parent._createPeriodicTimer; |
+ _createTask = (specification.createTask != null) |
+ ? new _ZoneFunction<CreateTaskHandler>( |
+ this, specification.createTask) |
+ : parent._createTask; |
+ _runTask = (specification.runTask != null) |
+ ? new _ZoneFunction<RunTaskHandler>( |
+ this, specification.runTask) |
+ : parent._runTask; |
_print = (specification.print != null) |
? new _ZoneFunction<PrintHandler>(this, specification.print) |
: parent._print; |
@@ -709,6 +927,16 @@ class _CustomZone extends _Zone { |
? new _ZoneFunction<HandleUncaughtErrorHandler>( |
this, specification.handleUncaughtError) |
: parent._handleUncaughtError; |
+ |
+ // Deprecated fields, once tasks are non-experimental. |
+ _createTimer = (specification.createTimer != null) |
+ ? new _ZoneFunction<CreateTimerHandler>( |
+ this, specification.createTimer) |
+ : parent._createTimer; |
+ _createPeriodicTimer = (specification.createPeriodicTimer != null) |
+ ? new _ZoneFunction<CreatePeriodicTimerHandler>( |
+ this, specification.createPeriodicTimer) |
+ : parent._createPeriodicTimer; |
} |
/** |
@@ -859,7 +1087,7 @@ class _CustomZone extends _Zone { |
// TODO(floitsch): make this a generic method call on '<R>' once it's |
// supported. Remove the unnecessary cast. |
return handler(implementation.zone, parentDelegate, this, callback) |
- as Object/*=ZoneCallback<R>*/; |
+ as dynamic/*=ZoneCallback<R>*/; |
} |
ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( |
@@ -871,7 +1099,7 @@ class _CustomZone extends _Zone { |
// TODO(floitsch): make this a generic method call on '<R, T>' once it's |
// supported. Remove the unnecessary cast. |
return handler(implementation.zone, parentDelegate, this, callback) |
- as Object/*=ZoneUnaryCallback<R, T>*/; |
+ as dynamic/*=ZoneUnaryCallback<R, T>*/; |
} |
ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/( |
@@ -883,7 +1111,7 @@ class _CustomZone extends _Zone { |
// TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
// it's supported. Remove the unnecessary cast. |
return handler(implementation.zone, parentDelegate, this, callback) |
- as Object/*=ZoneBinaryCallback<R, T1, T2>*/; |
+ as dynamic/*=ZoneBinaryCallback<R, T1, T2>*/; |
} |
AsyncError errorCallback(Object error, StackTrace stackTrace) { |
@@ -902,9 +1130,40 @@ class _CustomZone extends _Zone { |
assert(implementation != null); |
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
ScheduleMicrotaskHandler handler = implementation.function; |
- return handler(implementation.zone, parentDelegate, this, f); |
+ handler(implementation.zone, parentDelegate, this, f); |
+ } |
+ |
+ Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/( |
+ TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification) { |
+ var implementation = this._createTask; |
+ ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
+ // TODO(floitsch): make the handler call a generic method call on '<T, S>' |
+ // once it's supported. Remove the unnecessary cast. |
+ var handler = |
+ implementation.function as CreateTaskHandler/*<T, S>*/; |
+ return handler( |
+ implementation.zone, parentDelegate, this, create, specification); |
} |
+ void runTask/*<T, A>*/( |
+ TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg1) { |
+ var implementation = this._runTask; |
+ ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
+ RunTaskHandler handler = implementation.function; |
+ // TODO(floitsch): make this a generic method call on '<T, A>' once it's |
+ // supported. |
+ handler(implementation.zone, parentDelegate, this, run, task, arg1); |
+ } |
+ |
+ void print(String line) { |
+ var implementation = this._print; |
+ assert(implementation != null); |
+ ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
+ PrintHandler handler = implementation.function; |
+ return handler(implementation.zone, parentDelegate, this, line); |
+ } |
+ |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
Timer createTimer(Duration duration, void f()) { |
var implementation = this._createTimer; |
assert(implementation != null); |
@@ -913,6 +1172,7 @@ class _CustomZone extends _Zone { |
return handler(implementation.zone, parentDelegate, this, duration, f); |
} |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
Timer createPeriodicTimer(Duration duration, void f(Timer timer)) { |
var implementation = this._createPeriodicTimer; |
assert(implementation != null); |
@@ -921,14 +1181,6 @@ class _CustomZone extends _Zone { |
return handler( |
implementation.zone, parentDelegate, this, duration, f); |
} |
- |
- void print(String line) { |
- var implementation = this._print; |
- assert(implementation != null); |
- ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
- PrintHandler handler = implementation.function; |
- return handler(implementation.zone, parentDelegate, this, line); |
- } |
} |
/*=R*/ _rootHandleUncaughtError/*<R>*/( |
@@ -1006,22 +1258,39 @@ void _rootScheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, f()) { |
_scheduleAsyncCallback(f); |
} |
+Object/*=T*/ _rootCreateTask/*<T, S extends TaskSpecification>*/( |
+ Zone self, ZoneDelegate parent, Zone zone, |
+ TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification) { |
+ return create(specification, zone); |
+} |
+ |
+void _rootRunTask/*<T, A>*/( |
+ Zone self, ZoneDelegate parent, Zone zone, TaskRun run/*<T, A>*/, |
+ Object/*=T*/ task, Object/*=A*/ arg) { |
+ if (Zone._current == zone) { |
+ run(task, arg); |
+ return; |
+ } |
+ |
+ Zone old = Zone._enter(zone); |
+ try { |
+ run(task, arg); |
+ } catch (e, s) { |
+ zone.handleUncaughtError/*<dynamic>*/(e, s); |
+ } finally { |
+ Zone._leave(old); |
+ } |
+} |
+ |
Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone, |
Duration duration, void callback()) { |
- if (!identical(_ROOT_ZONE, zone)) { |
- callback = zone.bindCallback(callback); |
- } |
- return Timer._createTimer(duration, callback); |
+ return new Timer._task(zone, duration, callback); |
} |
Timer _rootCreatePeriodicTimer( |
Zone self, ZoneDelegate parent, Zone zone, |
Duration duration, void callback(Timer timer)) { |
- if (!identical(_ROOT_ZONE, zone)) { |
- // TODO(floitsch): the return type should be 'void'. |
- callback = zone.bindUnaryCallback/*<dynamic, Timer>*/(callback); |
- } |
- return Timer._createPeriodicTimer(duration, callback); |
+ return new Timer._periodicTask(zone, duration, callback); |
} |
void _rootPrint(Zone self, ZoneDelegate parent, Zone zone, String line) { |
@@ -1082,10 +1351,10 @@ class _RootZone extends _Zone { |
_ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask => |
const _ZoneFunction<ScheduleMicrotaskHandler>( |
_ROOT_ZONE, _rootScheduleMicrotask); |
- _ZoneFunction<CreateTimerHandler> get _createTimer => |
- const _ZoneFunction<CreateTimerHandler>(_ROOT_ZONE, _rootCreateTimer); |
- _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer => |
- const _ZoneFunction<CreatePeriodicTimerHandler>(_ROOT_ZONE, _rootCreatePeriodicTimer); |
+ _ZoneFunction<CreateTaskHandler> get _createTask => |
+ const _ZoneFunction<CreateTaskHandler>(_ROOT_ZONE, _rootCreateTask); |
+ _ZoneFunction<RunTaskHandler> get _runTask => |
+ const _ZoneFunction<RunTaskHandler>(_ROOT_ZONE, _rootRunTask); |
_ZoneFunction<PrintHandler> get _print => |
const _ZoneFunction<PrintHandler>(_ROOT_ZONE, _rootPrint); |
_ZoneFunction<ForkHandler> get _fork => |
@@ -1094,6 +1363,14 @@ class _RootZone extends _Zone { |
const _ZoneFunction<HandleUncaughtErrorHandler>( |
_ROOT_ZONE, _rootHandleUncaughtError); |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ _ZoneFunction<CreateTimerHandler> get _createTimer => |
+ const _ZoneFunction<CreateTimerHandler>(_ROOT_ZONE, _rootCreateTimer); |
+ // TODO(floitsch): deprecate once tasks are non-experimental. |
+ _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer => |
+ const _ZoneFunction<CreatePeriodicTimerHandler>( |
+ _ROOT_ZONE, _rootCreatePeriodicTimer); |
+ |
// The parent zone. |
_Zone get parent => null; |
@@ -1225,6 +1502,16 @@ class _RootZone extends _Zone { |
_rootScheduleMicrotask(null, null, this, f); |
} |
+ Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/( |
+ TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification) { |
+ return _rootCreateTask/*<T, S>*/(null, null, this, create, specification); |
+ } |
+ |
+ void runTask/*<T, A>*/( |
+ TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg) { |
+ _rootRunTask/*<T, A>*/(null, null, this, run, task, arg); |
+ } |
+ |
Timer createTimer(Duration duration, void f()) { |
return Timer._createTimer(duration, f); |
} |