LCOV - code coverage report
Current view: top level - common - isolate_service.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 95.5 % 44 42
Test Date: 2025-01-30 01:10:00 Functions: - 0 0

            Line data    Source code
       1              : import 'dart:async';
       2              : import 'dart:isolate';
       3              : 
       4              : ///
       5              : /// A helper class which starts an Isolate and lets you execute Functions.
       6              : ///
       7              : 
       8              : class IsolateManager {
       9              :   Isolate? _isolate;
      10              :   SendPort? _sendPort;
      11              : 
      12            7 :   SendPort get sendPort {
      13            7 :     if (!isReady) throw Exception("IsolateManager not ready");
      14            7 :     return _sendPort!;
      15              :   }
      16              : 
      17              :   final _receivePort = ReceivePort();
      18           21 :   late final _receivePortBroadcast = _receivePort.asBroadcastStream();
      19              : 
      20              :   final completer = Completer<void>();
      21              : 
      22           21 :   bool get isReady => completer.isCompleted;
      23              : 
      24              :   bool isInitializing = false;
      25              : 
      26            7 :   Future<void> _init() async {
      27            7 :     isInitializing = true;
      28           14 :     Stopwatch stopwatch = Stopwatch()..start();
      29            7 :     ReceivePort receivePort = ReceivePort();
      30           14 :     _isolate = await Isolate.spawn<SendPort>(
      31              :       _isolateEntry,
      32            7 :       receivePort.sendPort,
      33              :     );
      34           14 :     _sendPort = await receivePort.first;
      35           28 :     _sendPort!.send(_receivePort.sendPort);
      36              : 
      37           14 :     completer.complete();
      38              : 
      39            7 :     print(
      40           14 :       "IsolateManager initialized in ${stopwatch.elapsedMilliseconds}ms",
      41              :     );
      42            7 :     isInitializing = false;
      43              :     return;
      44              :   }
      45              : 
      46            7 :   Future<T> executeTask<T, A>(IsolateTask<T, A> task) async {
      47           21 :     if (!isReady && !isInitializing) _init();
      48           14 :     await completer.future;
      49              : 
      50           14 :     sendPort.send(task);
      51           21 :     final result = await _receivePortBroadcast.firstWhere((result) {
      52            7 :       if (result is IsolateResult) {
      53           21 :         return result.id == task.id;
      54              :       }
      55              :       return false;
      56              :     });
      57              : 
      58            7 :     if (result is IsolateResult) {
      59            7 :       return result.result;
      60              :     }
      61            0 :     throw Exception("IsolateResult not found");
      62              :   }
      63              : 
      64            7 :   void dispose() {
      65           14 :     _isolate?.kill(priority: Isolate.immediate);
      66              :   }
      67              : 
      68            7 :   static void _isolateEntry(
      69              :     SendPort sendPort,
      70              :   ) async {
      71            7 :     ReceivePort receivePort = ReceivePort();
      72           14 :     sendPort.send(receivePort.sendPort);
      73              : 
      74            7 :     Stream receiveBroadcast = receivePort.asBroadcastStream();
      75            7 :     SendPort responsePort = await receiveBroadcast.first;
      76              : 
      77           14 :     receiveBroadcast.listen((task) async {
      78            7 :       if (task is IsolateTask) {
      79              :         try {
      80            7 :           final result = await task.call();
      81           14 :           responsePort.send(IsolateResult(
      82              :             result: result,
      83            7 :             id: task.id,
      84              :           ));
      85              :         } catch (e, s) {
      86            0 :           print("task failed: $task; $e $s");
      87              :         }
      88              :       }
      89              :     });
      90              :   }
      91              : }
      92              : 
      93              : class IsolateTask<T, A> {
      94              :   final FutureOr<T> Function(A arg) task;
      95              :   final A argument;
      96              :   final String id;
      97              : 
      98            7 :   IsolateTask({
      99              :     required this.task,
     100              :     required this.argument,
     101           21 :   }) : id = DateTime.now().microsecondsSinceEpoch.toString();
     102              : 
     103           28 :   FutureOr<T> call() => task(argument);
     104              : }
     105              : 
     106              : class IsolateResult<T> {
     107              :   final T result;
     108              :   final String id;
     109              : 
     110            7 :   const IsolateResult({
     111              :     required this.result,
     112              :     required this.id,
     113              :   });
     114              : }
        

Generated by: LCOV version 2.0-1