Line data Source code
1 : import 'dart:async'; 2 : import 'dart:isolate'; 3 : 4 : import 'package:combine/combine.dart'; 5 : import 'package:combine/src/bindings/isolate_bindings/isolate_binding.dart'; 6 : import 'package:combine/src/combine_isolate/native_combine_isolate.dart'; 7 : import 'package:combine/src/isolate_factory/isolate_factory.dart'; 8 : import 'package:combine/src/isolate_messenger/internal_isolate_messenger/native_internal_isolate_messenger.dart'; 9 : import 'package:combine/src/method_channel_middleware/isolated_method_channel_middleware.dart'; 10 : import 'package:combine/src/method_channel_middleware/ui_method_channel_middleware.dart'; 11 : import 'package:flutter/services.dart'; 12 : 13 : /// It is used to create [Isolate] and setup all necessary stuff 14 : /// which is needed to use method channels. 15 : class IsolateFactoryImpl extends IsolateFactory { 16 : @override 17 5 : Future<CombineIsolate> create<T>( 18 : IsolateEntryPoint<T> entryPoint, { 19 : Map<String, Object?>? argumentsMap, 20 : T? argument, 21 : String? debugName, 22 : bool errorsAreFatal = true, 23 : }) async { 24 5 : final receivePort = ReceivePort(); 25 10 : final isolate = await Isolate.spawn<_IsolateSetup<T>>( 26 : _runInIsolate<T>, 27 5 : _IsolateSetup<T>( 28 5 : receivePort.sendPort, 29 : entryPoint, 30 : argumentsMap, 31 : argument, 32 : ), 33 : debugName: debugName, 34 : errorsAreFatal: errorsAreFatal, 35 : paused: false, 36 : ); 37 : 38 10 : final receivePortStream = receivePort.asBroadcastStream().cast<Object>(); 39 10 : final sendPort = await receivePortStream.first as SendPort; 40 : 41 5 : final isolateMessenger = NativeInternalIsolateMessenger( 42 : sendPort, 43 : receivePortStream, 44 : ); 45 : 46 5 : final methodChannelMiddleware = UIMethodChannelMiddleware( 47 10 : ServicesBinding.instance!.defaultBinaryMessenger, 48 : isolateMessenger, 49 5 : )..initialize(); 50 5 : return NativeCombineIsolate( 51 : isolate, 52 5 : isolateMessenger.toIsolateMessenger(), 53 5 : () { 54 5 : receivePort.close(); 55 5 : methodChannelMiddleware.dispose(); 56 : }, 57 : ); 58 : } 59 : 60 5 : static void _runInIsolate<T>(_IsolateSetup<T> setup) { 61 5 : final receivePort = ReceivePort(); 62 5 : final isolateMessenger = NativeInternalIsolateMessenger( 63 5 : setup.sendPort, 64 10 : receivePort.asBroadcastStream().cast<Object>(), 65 : ); 66 10 : isolateMessenger.send(receivePort.sendPort); 67 : 68 5 : final isolateContext = IsolateContext( 69 5 : argument: setup.argument, 70 5 : messenger: isolateMessenger.toIsolateMessenger(), 71 : ); 72 : 73 10 : IsolatedMethodChannelMiddleware(isolateMessenger).initialize(); 74 5 : IsolateBinding(); 75 10 : setup.entryPoint(isolateContext); 76 : } 77 : } 78 : 79 : class _IsolateSetup<T> { 80 5 : _IsolateSetup( 81 : this.sendPort, 82 : this.entryPoint, 83 : this.argumentsMap, 84 : this.argument, 85 : ); 86 : 87 : final SendPort sendPort; 88 : final IsolateEntryPoint<T> entryPoint; 89 : final Map<String, Object?>? argumentsMap; 90 : final T? argument; 91 : }