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-04-01 01:23:07 Functions: - 0 0

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

Generated by: LCOV version 2.0-1