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 | /// @docImport 'dart:developer'; |
6 | /// @docImport 'dart:isolate'; |
7 | /// |
8 | /// @docImport 'package:flutter/scheduler.dart'; |
9 | library; |
10 | |
11 | import 'dart:async'; |
12 | |
13 | import '_isolates_io.dart' |
14 | if (dart.library.js_util) '_isolates_web.dart' as isolates; |
15 | |
16 | /// Signature for the callback passed to [compute]. |
17 | /// |
18 | /// {@macro flutter.foundation.compute.callback} |
19 | /// |
20 | typedef ComputeCallback<M, R> = FutureOr<R> Function(M message); |
21 | |
22 | /// The signature of [compute], which spawns an isolate, runs `callback` on |
23 | /// that isolate, passes it `message`, and (eventually) returns the value |
24 | /// returned by `callback`. |
25 | typedef ComputeImpl = Future<R> Function<M, R>(ComputeCallback<M, R> callback, M message, { String? debugLabel }); |
26 | |
27 | /// Asynchronously runs the given [callback] - with the provided [message] - |
28 | /// in the background and completes with the result. |
29 | /// |
30 | /// {@template flutter.foundation.compute.usecase} |
31 | /// This is useful for operations that take longer than a few milliseconds, and |
32 | /// which would therefore risk skipping frames. For tasks that will only take a |
33 | /// few milliseconds, consider [SchedulerBinding.scheduleTask] instead. |
34 | /// {@endtemplate} |
35 | /// |
36 | /// {@youtube 560 315 https://www.youtube.com/watch?v=5AxWC49ZMzs} |
37 | /// |
38 | /// {@tool snippet} |
39 | /// The following code uses the [compute] function to check whether a given |
40 | /// integer is a prime number. |
41 | /// |
42 | /// ```dart |
43 | /// Future<bool> isPrime(int value) { |
44 | /// return compute(_calculate, value); |
45 | /// } |
46 | /// |
47 | /// bool _calculate(int value) { |
48 | /// if (value == 1) { |
49 | /// return false; |
50 | /// } |
51 | /// for (int i = 2; i < value; ++i) { |
52 | /// if (value % i == 0) { |
53 | /// return false; |
54 | /// } |
55 | /// } |
56 | /// return true; |
57 | /// } |
58 | /// ``` |
59 | /// {@end-tool} |
60 | /// |
61 | /// On web platforms this will run [callback] on the current eventloop. |
62 | /// On native platforms this will run [callback] in a separate isolate. |
63 | /// |
64 | /// {@template flutter.foundation.compute.callback} |
65 | /// |
66 | /// The `callback`, the `message` given to it as well as the result have to be |
67 | /// objects that can be sent across isolates (as they may be transitively copied |
68 | /// if needed). The majority of objects can be sent across isolates. |
69 | /// |
70 | /// See [SendPort.send] for more information about exceptions as well as a note |
71 | /// of warning about sending closures, which can capture more state than needed. |
72 | /// |
73 | /// {@endtemplate} |
74 | /// |
75 | /// On native platforms `await compute(fun, message)` is equivalent to |
76 | /// `await Isolate.run(() => fun(message))`. See also [Isolate.run]. |
77 | /// |
78 | /// The `debugLabel` - if provided - is used as name for the isolate that |
79 | /// executes `callback`. [Timeline] events produced by that isolate will have |
80 | /// the name associated with them. This is useful when profiling an application. |
81 | Future<R> compute<M, R>(ComputeCallback<M, R> callback, M message, {String? debugLabel}) { |
82 | return isolates.compute<M, R>(callback, message, debugLabel: debugLabel); |
83 | } |
84 | |