11import 'dart:async' ;
22import 'dart:isolate' ;
33
4+ import 'package:logging/logging.dart' ;
5+ import 'package:meta/meta.dart' ;
46import 'package:sane/src/exceptions.dart' ;
7+ import 'package:sane/src/extensions.dart' ;
58import 'package:sane/src/isolate_messages/exception.dart' ;
9+ import 'package:sane/src/isolate_messages/exit.dart' ;
610import 'package:sane/src/isolate_messages/interface.dart' ;
711import 'package:sane/src/sane.dart' ;
812
13+ final _logger = Logger ('sane.isolate' );
14+
15+ @internal
916class SaneIsolate {
1017 SaneIsolate ._(
1118 this ._isolate,
1219 this ._sendPort,
13- this ._exitReceivePort,
14- ) : _exited = false {
15- _exitReceivePort.listen ((message) {
16- assert (message == null );
17- _exited = true ;
18- });
19- }
20+ );
2021
2122 final Isolate _isolate;
2223 final SendPort _sendPort;
23- final ReceivePort _exitReceivePort;
24-
25- bool _exited;
26-
27- bool get exited => _exited;
2824
2925 static Future <SaneIsolate > spawn (Sane sane) async {
3026 final receivePort = ReceivePort ();
31- final exitReceivePort = ReceivePort ();
3227
3328 final isolate = await Isolate .spawn (
3429 _entryPoint,
3530 (receivePort.sendPort, sane),
36- onExit: exitReceivePort .sendPort,
31+ onExit: receivePort .sendPort,
3732 );
3833
39- final sendPort = await receivePort.first as SendPort ;
40- return SaneIsolate ._(isolate, sendPort, exitReceivePort);
41- }
34+ final sendPortCompleter = Completer <SendPort >();
35+ receivePort.listen ((message) {
36+ switch (message) {
37+ case SendPort ():
38+ sendPortCompleter.complete (message);
39+ case LogRecord ():
40+ _logger.redirect (message);
41+ case null :
42+ receivePort.close ();
43+ }
44+ });
4245
43- void kill () {
44- _isolate. kill (priority : Isolate .immediate );
46+ final sendPort = await sendPortCompleter.future;
47+ return SaneIsolate ._(isolate, sendPort );
4548 }
4649
50+ void kill () => _isolate.kill (priority: Isolate .immediate);
51+
4752 Future <T > sendMessage <T extends IsolateResponse >(
4853 IsolateMessage <T > message,
4954 ) async {
@@ -75,10 +80,16 @@ typedef _EntryPointArgs = (SendPort sendPort, Sane sane);
7580void _entryPoint (_EntryPointArgs args) {
7681 final (sendPort, sane) = args;
7782
83+ Logger .root.level = Level .ALL ;
84+ Logger .root.onRecord.forEach (sendPort.send);
85+
7886 final receivePort = ReceivePort ();
7987 sendPort.send (receivePort.sendPort);
8088
81- receivePort.cast <_IsolateMessageEnvelope >().listen ((envelope) async {
89+ late StreamSubscription <_IsolateMessageEnvelope > subscription;
90+
91+ subscription =
92+ receivePort.cast <_IsolateMessageEnvelope >().listen ((envelope) async {
8293 final _IsolateMessageEnvelope (: message, : replyPort) = envelope;
8394
8495 IsolateResponse response;
@@ -93,6 +104,10 @@ void _entryPoint(_EntryPointArgs args) {
93104 }
94105
95106 replyPort.send (response);
107+
108+ if (message is ExitMessage ) {
109+ await subscription.cancel ();
110+ }
96111 });
97112}
98113
@@ -108,8 +123,10 @@ class _IsolateMessageEnvelope {
108123
109124late Map <String , SaneDevice > _devices;
110125
126+ @internal
111127SaneDevice getDevice (String name) => _devices[name]! ;
112128
129+ @internal
113130void setDevices (Iterable <SaneDevice > devices) {
114131 _devices = {
115132 for (final device in devices) device.name: device,
0 commit comments