1 | | | import 'dart:async'; |
2 | | |
|
3 | | | import 'package:using/using.dart'; |
4 | | |
|
5 | | | import '../../squadron.dart'; |
6 | | | import '../_impl/xplat/_local_worker.dart' |
7 | | | if (dart.library.io) '../_impl/native/_local_worker.dart' |
8 | | | if (dart.library.html) '../_impl/web/_local_worker.dart' |
9 | | | if (dart.library.js) '../_impl/web/_local_worker.dart' |
10 | | | if (dart.library.js_interop) '../_impl/web/_local_worker.dart' as impl; |
11 | | |
|
12 | | | /// Base local worker class. |
13 | | | /// |
14 | | | /// Local workers are similar to other Workers except that they run in the |
15 | | | /// context of the current thread. They do not create any platform thread |
16 | | | /// (such as Isolate or Web Worker) but they provide a [channel] that can be |
17 | | | /// shared with other workers to support communication between threads. One |
18 | | | /// interesting use-case is accessing UI components or platform plugins in |
19 | | | /// Flutter, where only code running in the main thread is allowed access to |
20 | | | /// such features. Creating a [LocalWorker] in the main application and sharing |
21 | | | /// its [channel] with other workers enables providing access to Flutter |
22 | | | /// features. |
23 | | | /// |
24 | | | /// Local workers wrap around a [WorkerService]. Messages sent to the local |
25 | | | /// worker are deserialized as [WorkerRequest]s and dispatched to a handler |
26 | | | /// defined in the [_service]'s [WorkerService.operations] map according to the |
27 | | | /// [WorkerRequest.command]. |
28 | | | abstract interface class LocalWorker<W> |
29 | | | with Releasable |
30 | | | implements WorkerService, IWorker { |
31 | | 1 | factory LocalWorker.create(W service, |
32 | | | [OperationsMap? operations, ExceptionManager? exceptionManager]) { |
33 | | | if (operations == null) { |
34 | | 1 | if (service is WorkerService) { |
35 | | 1 | operations = service.operations; |
36 | | | } else { |
37 | | 0 | throw ArgumentError( |
38 | | 0 | 'The operations map must be provided because $W does not implement $WorkerService', |
39 | | | 'operations', |
40 | | | ); |
41 | | | } |
42 | | | } |
43 | | 1 | return impl.createLocalWorker<W>( |
44 | | | service, |
45 | | | operations, |
46 | | 1 | exceptionManager ?? ExceptionManager(), |
47 | | | ); |
48 | | | } |
49 | | |
|
50 | | | W get service; |
51 | | |
|
52 | | | @override |
53 | | | ExceptionManager get exceptionManager; |
54 | | |
|
55 | | | /// The local worker's [Channel]. |
56 | | | Channel? get channel; |
57 | | |
|
58 | | | /// Starts the local worker. |
59 | | | @override |
60 | | | FutureOr<void> start(); |
61 | | |
|
62 | | | /// Stops the local worker. |
63 | | | @override |
64 | | | void stop(); |
65 | | |
|
66 | | | /// Terminates the local worker. |
67 | | | @override |
68 | | | void terminate([TaskTerminatedException? ex]); |
69 | | |
|
70 | | | /// Forward to underlying service. |
71 | | | @override |
72 | | | OperationsMap get operations; |
73 | | | } |