From 3d46ab920b47a2ecb250c6f890f3559ef913cb0b Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Thu, 17 Mar 2022 18:45:21 -0700 Subject: [PATCH] Reorganize compute docs and add sample code (#100253) --- .../flutter/lib/src/foundation/isolates.dart | 93 ++++++++++++------- 1 file changed, 61 insertions(+), 32 deletions(-) diff --git a/packages/flutter/lib/src/foundation/isolates.dart b/packages/flutter/lib/src/foundation/isolates.dart index b06d238b6a..3b9d651f4c 100644 --- a/packages/flutter/lib/src/foundation/isolates.dart +++ b/packages/flutter/lib/src/foundation/isolates.dart @@ -11,44 +11,83 @@ import '_isolates_io.dart' /// /// {@macro flutter.foundation.compute.types} /// -/// Instances of [ComputeCallback] must be sendable between isolates i.e. -/// top-level functions, static methods or a closures that only capture objects -/// sendable between isolates or an instance methods which instance properties -/// are also sendable. +/// Instances of [ComputeCallback] must be functions that can be sent to an +/// isolate. +/// {@macro flutter.foundation.compute.callback} /// -/// {@macro flutter.foundation.compute.closure.note} -/// -/// {@macro flutter.foundation.compute.limitations} +/// {@macro flutter.foundation.compute.types} typedef ComputeCallback = FutureOr Function(Q message); /// The signature of [compute], which spawns an isolate, runs `callback` on /// that isolate, passes it `message`, and (eventually) returns the value /// returned by `callback`. /// +/// {@macro flutter.foundation.compute.usecase} +/// +/// The function used as `callback` must be one that can be sent to an isolate. +/// {@macro flutter.foundation.compute.callback} +/// +/// {@macro flutter.foundation.compute.types} +/// +/// The `debugLabel` argument can be specified to provide a name to add to the +/// [Timeline]. This is useful when profiling an application. +typedef ComputeImpl = Future Function(ComputeCallback callback, Q message, { String? debugLabel }); + +/// A function that spawns an isolate and runs the provided `callback` on that +/// isolate, passes it the provided `message`, and (eventually) returns the +/// value returned by `callback`. +/// +/// {@template flutter.foundation.compute.usecase} /// This is useful for operations that take longer than a few milliseconds, and /// which would therefore risk skipping frames. For tasks that will only take a /// few milliseconds, consider [SchedulerBinding.scheduleTask] instead. +/// {@endtemplate} +/// +/// {@youtube 560 315 https://www.youtube.com/watch?v=5AxWC49ZMzs} +/// +/// {@tool snippet} +/// The following code uses the [compute] function to check whether a given +/// integer is a prime number. +/// +/// ```dart +/// Future isPrime(int value) { +/// return compute(_calculate, value); +/// } +/// +/// bool _calculate(int value) { +/// if (value == 1) { +/// return false; +/// } +/// for (int i = 2; i < value; ++i) { +/// if (value % i == 0) { +/// return false; +/// } +/// } +/// return true; +/// } +/// ``` +/// {@end-tool} +/// +/// The function used as `callback` must be one that can be sent to an isolate. +/// {@template flutter.foundation.compute.callback} +/// Qualifying functions include: +/// +/// * top-level functions +/// * static methods +/// * closures that only capture objects that can be sent to an isolate +/// +/// Using closures must be done with care. Due to +/// [dart-lang/sdk#36983](https://github.com/dart-lang/sdk/issues/36983) a +/// closure may captures objects that, while not directly used in the closure +/// itself, may prevent it from being sent to an isolate. +/// {@endtemplate} /// /// {@template flutter.foundation.compute.types} /// The [compute] method accepts the following parameters: /// /// * `Q` is the type of the message that kicks off the computation. -/// /// * `R` is the type of the value returned. -/// {@endtemplate} /// -/// The `callback` must be sendable between isolates i.e. a top-level function, -/// static method or a closure that only captures objects sendable between -/// isolates or an instance method which instance properties are also sendable. -/// -/// {@template flutter.foundation.compute.closure.note} -/// However, using arbitrary closures should be done with great care because -/// it may be that the closure captures more variables than initially thought. -/// See the underlying [dart-lang/sdk#36983](https://github.com/dart-lang/sdk/issues/36983) -/// issue. -/// {@endtemplate} -/// -/// {@template flutter.foundation.compute.limitations} /// There are limitations on the values that can be sent and received to and /// from isolates. These limitations constrain the values of `Q` and `R` that /// are possible. See the discussion at [SendPort.send]. @@ -56,17 +95,7 @@ typedef ComputeCallback = FutureOr Function(Q message); /// The same limitations apply to any errors generated by the computation. /// {@endtemplate} /// -/// The `debugLabel` argument can be specified to provide a name to add to the -/// [Timeline]. This is useful when profiling an application. -typedef ComputeImpl = Future Function(ComputeCallback callback, Q message, { String? debugLabel }); - -/// A function that spawns an isolate and runs a callback on that isolate. This -/// method should be used to execute parallel tasks that reduce the risk of -/// skipping frames. -/// -/// {@youtube 560 315 https://www.youtube.com/watch?v=5AxWC49ZMzs} -/// /// See also: /// -/// * [ComputeImpl], for function parameters and usage details. +/// * [ComputeImpl], for the [compute] function's signature. const ComputeImpl compute = isolates.compute;