1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | import 'dart:async'; |
6 | |
7 | import '_isolates_io.dart' |
8 | if (dart.library.js_util) '_isolates_web.dart' as isolates; |
9 | |
10 | /// Signature for the callback passed to [compute]. |
11 | /// |
12 | /// {@macro flutter.foundation.compute.callback} |
13 | /// |
14 | typedef ComputeCallback<M, R> = FutureOr<R> Function(M message); |
15 | |
16 | /// The signature of [compute], which spawns an isolate, runs `callback` on |
17 | /// that isolate, passes it `message`, and (eventually) returns the value |
18 | /// returned by `callback`. |
19 | typedef ComputeImpl = Future<R> Function<M, R>(ComputeCallback<M, R> callback, M message, { String? debugLabel }); |
20 | |
21 | /// Asynchronously runs the given [callback] - with the provided [message] - |
22 | /// in the background and completes with the result. |
23 | /// |
24 | /// {@template flutter.foundation.compute.usecase} |
25 | /// This is useful for operations that take longer than a few milliseconds, and |
26 | /// which would therefore risk skipping frames. For tasks that will only take a |
27 | /// few milliseconds, consider [SchedulerBinding.scheduleTask] instead. |
28 | /// {@endtemplate} |
29 | /// |
30 | /// {@youtube 560 315 https://www.youtube.com/watch?v=5AxWC49ZMzs} |
31 | /// |
32 | /// {@tool snippet} |
33 | /// The following code uses the [compute] function to check whether a given |
34 | /// integer is a prime number. |
35 | /// |
36 | /// ```dart |
37 | /// Future<bool> isPrime(int value) { |
38 | /// return compute(_calculate, value); |
39 | /// } |
40 | /// |
41 | /// bool _calculate(int value) { |
42 | /// if (value == 1) { |
43 | /// return false; |
44 | /// } |
45 | /// for (int i = 2; i < value; ++i) { |
46 | /// if (value % i == 0) { |
47 | /// return false; |
48 | /// } |
49 | /// } |
50 | /// return true; |
51 | /// } |
52 | /// ``` |
53 | /// {@end-tool} |
54 | /// |
55 | /// On web platforms this will run [callback] on the current eventloop. |
56 | /// On native platforms this will run [callback] in a separate isolate. |
57 | /// |
58 | /// {@template flutter.foundation.compute.callback} |
59 | /// |
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. |
63 | /// |
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. |
66 | /// |
67 | /// {@endtemplate} |
68 | /// |
69 | /// On native platforms `await compute(fun, message)` is equivalent to |
70 | /// `await Isolate.run(() => fun(message))`. See also [Isolate.run]. |
71 | /// |
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 | } |
78 | |