1 | | | import 'dart:async'; |
2 | | |
|
3 | | | import 'package:logger/web.dart'; |
4 | | | import 'package:using/using.dart'; |
5 | | |
|
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_interop) '../_impl/web/_local_worker.dart' as impl; |
10 | | | import '../channel.dart'; |
11 | | | import '../exceptions/exception_manager.dart'; |
12 | | | import '../iworker.dart'; |
13 | | | import '../worker/worker_request.dart'; |
14 | | | import '../worker_service.dart'; |
15 | | |
|
16 | | | /// Base local worker class. |
17 | | | /// |
18 | | | /// Local workers are similar to other Workers except that they run in the |
19 | | | /// context of the current thread. They do not create any platform thread |
20 | | | /// (such as Isolate or Web Worker) but they provide a [channel] that can be |
21 | | | /// shared with other workers to support communication between threads. One |
22 | | | /// interesting use-case is accessing UI components or platform plugins in |
23 | | | /// Flutter, where only code running in the main thread is allowed access to |
24 | | | /// such features. Creating a [LocalWorker] in the main application and sharing |
25 | | | /// its [channel] with other workers enables providing access to Flutter |
26 | | | /// features. |
27 | | | /// |
28 | | | /// Local workers wrap around a [WorkerService]. Messages sent to the local |
29 | | | /// worker are deserialized as [WorkerRequest]s and dispatched to a handler |
30 | | | /// defined in the [_service]'s [WorkerService.operations] map according to the |
31 | | | /// [WorkerRequest.command]. |
32 | | | abstract base class LocalWorker<W extends WorkerService> |
33 | | | with Releasable |
34 | | | implements WorkerService, IWorker { |
35 | | 1 | LocalWorker(this._service); |
36 | | |
|
37 | | 2 | factory LocalWorker.create(W service, [ExceptionManager? exceptionManager]) => |
38 | | 2 | impl.createLocalWorker<W>( |
39 | | 2 | service, exceptionManager ?? ExceptionManager()); |
40 | | |
|
41 | | | final W _service; |
42 | | |
|
43 | | 1 | @override |
44 | | 1 | void release() { |
45 | | 1 | stop(); |
46 | | 2 | super.release(); |
47 | | 1 | } |
48 | | |
|
49 | | | @override |
50 | | | Logger? channelLogger; |
51 | | |
|
52 | | 0 | @override |
53 | | | ExceptionManager get exceptionManager => |
54 | | 0 | (_exceptionManager ??= ExceptionManager()); |
55 | | | ExceptionManager? _exceptionManager; |
56 | | |
|
57 | | | /// The local worker's [Channel]. |
58 | | | Channel? get channel; |
59 | | |
|
60 | | | /// A [Channel] to communicate with this local worker. This channel should be |
61 | | | /// provided to clients so they can invoke services from the local worker. |
62 | | 0 | Channel? get sharedChannel => channel?.share(); |
63 | | |
|
64 | | | /// Starts the local worker. |
65 | | | @override |
66 | | | FutureOr<void> start(); |
67 | | |
|
68 | | | /// Stops the local worker. |
69 | | | @override |
70 | | | void stop(); |
71 | | |
|
72 | | | /// Forward to underlying service. |
73 | | 1 | @override |
74 | | 3 | Map<int, CommandHandler> get operations => _service.operations; |
75 | | | } |