Skip to content

Commit fc3571e

Browse files
authored
Improve documentation of compute() function (#116878)
This improves the documentation of the `compute()` function as follows: * Instead of making `compute` a top-level constant, we make it a function. This allows the generated API docs to show a function signature with parameters and their names, making it *much* clearer to users what function is being documented. * We mention that on web-backends this is running `compute()` on the normal eventloop whereas on on native platforms it runs in a separate isolate. * We mention that callback, message and result have to be sendable across isolates. We also mention that they may be copied. * We link to both `Isolate.run` & `SendPort.send` for more information. * We use `M` for the type of `message` instead the rather confusing `Q`.
1 parent dcd2170 commit fc3571e

File tree

3 files changed

+24
-46
lines changed

3 files changed

+24
-46
lines changed

packages/flutter/lib/src/foundation/_isolates_io.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import 'isolates.dart' as isolates;
1111
export 'isolates.dart' show ComputeCallback;
1212

1313
/// The dart:io implementation of [isolate.compute].
14-
Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, {String? debugLabel}) async {
14+
@pragma('vm:prefer-inline')
15+
Future<R> compute<M, R>(isolates.ComputeCallback<M, R> callback, M message, {String? debugLabel}) async {
1516
debugLabel ??= kReleaseMode ? 'compute' : callback.toString();
1617

1718
return Isolate.run<R>(() {

packages/flutter/lib/src/foundation/_isolates_web.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import 'isolates.dart' as isolates;
77
export 'isolates.dart' show ComputeCallback;
88

99
/// The dart:html implementation of [isolate.compute].
10-
Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { String? debugLabel }) async {
10+
@pragma('dart2js:tryInline')
11+
Future<R> compute<M, R>(isolates.ComputeCallback<M, R> callback, M message, { String? debugLabel }) async {
1112
// To avoid blocking the UI immediately for an expensive function call, we
1213
// pump a single frame to allow the framework to complete the current set
1314
// of work.

packages/flutter/lib/src/foundation/isolates.dart

+20-44
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,17 @@ import '_isolates_io.dart'
99

1010
/// Signature for the callback passed to [compute].
1111
///
12-
/// {@macro flutter.foundation.compute.types}
13-
///
14-
/// Instances of [ComputeCallback] must be functions that can be sent to an
15-
/// isolate.
1612
/// {@macro flutter.foundation.compute.callback}
1713
///
18-
/// {@macro flutter.foundation.compute.types}
19-
typedef ComputeCallback<Q, R> = FutureOr<R> Function(Q message);
14+
typedef ComputeCallback<M, R> = FutureOr<R> Function(M message);
2015

2116
/// The signature of [compute], which spawns an isolate, runs `callback` on
2217
/// that isolate, passes it `message`, and (eventually) returns the value
2318
/// returned by `callback`.
24-
///
25-
/// {@macro flutter.foundation.compute.usecase}
26-
///
27-
/// The function used as `callback` must be one that can be sent to an isolate.
28-
/// {@macro flutter.foundation.compute.callback}
29-
///
30-
/// {@macro flutter.foundation.compute.types}
31-
///
32-
/// The `debugLabel` argument can be specified to provide a name to add to the
33-
/// [Timeline]. This is useful when profiling an application.
34-
typedef ComputeImpl = Future<R> Function<Q, R>(ComputeCallback<Q, R> callback, Q message, { String? debugLabel });
19+
typedef ComputeImpl = Future<R> Function<M, R>(ComputeCallback<M, R> callback, M message, { String? debugLabel });
3520

36-
/// A function that spawns an isolate and runs the provided `callback` on that
37-
/// isolate, passes it the provided `message`, and (eventually) returns the
38-
/// value returned by `callback`.
21+
/// Asynchronously runs the given [callback] - with the provided [message] -
22+
/// in the background and completes with the result.
3923
///
4024
/// {@template flutter.foundation.compute.usecase}
4125
/// This is useful for operations that take longer than a few milliseconds, and
@@ -68,34 +52,26 @@ typedef ComputeImpl = Future<R> Function<Q, R>(ComputeCallback<Q, R> callback, Q
6852
/// ```
6953
/// {@end-tool}
7054
///
71-
/// The function used as `callback` must be one that can be sent to an isolate.
72-
/// {@template flutter.foundation.compute.callback}
73-
/// Qualifying functions include:
74-
///
75-
/// * top-level functions
76-
/// * static methods
77-
/// * closures that only capture objects that can be sent to an isolate
55+
/// On web platforms this will run [callback] on the current eventloop.
56+
/// On native platforms this will run [callback] in a separate isolate.
7857
///
79-
/// Using closures must be done with care. Due to
80-
/// [dart-lang/sdk#36983](https://github.com/dart-lang/sdk/issues/36983) a
81-
/// closure may capture objects that, while not directly used in the closure
82-
/// itself, may prevent it from being sent to an isolate.
83-
/// {@endtemplate}
84-
///
85-
/// {@template flutter.foundation.compute.types}
86-
/// The [compute] method accepts the following parameters:
58+
/// {@template flutter.foundation.compute.callback}
8759
///
88-
/// * `Q` is the type of the message that kicks off the computation.
89-
/// * `R` is the type of the value returned.
60+
/// The `callback`, the `message` given to it as well as the result have to be
61+
/// objects that can be sent across isolates (as they may be transitively copied
62+
/// if needed). The majority of objects can be sent across isolates.
9063
///
91-
/// There are limitations on the values that can be sent and received to and
92-
/// from isolates. These limitations constrain the values of `Q` and `R` that
93-
/// are possible. See the discussion at [SendPort.send].
64+
/// See [SendPort.send] for more information about exceptions as well as a note
65+
/// of warning about sending closures, which can capture more state than needed.
9466
///
95-
/// The same limitations apply to any errors generated by the computation.
9667
/// {@endtemplate}
9768
///
98-
/// See also:
69+
/// On native platforms `await compute(fun, message)` is equivalent to
70+
/// `await Isolate.run(() => fun(message))`. See also [Isolate.run].
9971
///
100-
/// * [ComputeImpl], for the [compute] function's signature.
101-
const ComputeImpl compute = isolates.compute;
72+
/// The `debugLabel` - if provided - is used as name for the isolate that
73+
/// executes `callback`. [Timeline] events produced by that isolate will have
74+
/// the name associated with them. This is useful when profiling an application.
75+
Future<R> compute<M, R>(ComputeCallback<M, R> callback, M message, {String? debugLabel}) {
76+
return isolates.compute<M, R>(callback, message, debugLabel: debugLabel);
77+
}

0 commit comments

Comments
 (0)