Skip to content

Commit

Permalink
Improve: Change to use only one RawReceivePort.
Browse files Browse the repository at this point in the history
  • Loading branch information
thongdn-it committed Sep 28, 2022
1 parent b1c624d commit dbc82d3
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 79 deletions.
7 changes: 5 additions & 2 deletions isolate_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# [3.0.0] - 30/09/2022

- Change to use only one RawReceivePort.

# [2.0.0] - 03/09/2021

* Support null-safety.
- Support null-safety.

# [1.0.0] - 30/08/2021

* Initial package.
- Initial package.
116 changes: 58 additions & 58 deletions isolate_flutter/lib/src/isolate_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class IsolateFlutter {

Isolate? _isolate;

ReceivePort? _resultPort, _exitPort, _errorPort;
late RawReceivePort _port;

late Completer _completer;
late Completer<dynamic> _completer;

IsolateFlutter._();

Expand Down Expand Up @@ -49,52 +49,30 @@ class IsolateFlutter {
final _debugLabel =
debugLabel ?? 'IsolateFlutter_${_isolateFlutter.hashCode}';

// Create ReceivePort
_isolateFlutter._resultPort = ReceivePort();
_isolateFlutter._exitPort = ReceivePort();
_isolateFlutter._errorPort = ReceivePort();

// Create Completer
_isolateFlutter._completer = Completer<R>();

// Swap an isolate
_isolateFlutter._isolate = await Isolate.spawn(
_spawn,
IsolateFlutterConfiguration<Q, FutureOr<R>>(
callback,
message,
_isolateFlutter._resultPort!.sendPort,
_debugLabel,
),
onError: _isolateFlutter._errorPort?.sendPort,
onExit: _isolateFlutter._exitPort?.sendPort,
debugName: _debugLabel,
paused: true,
);

// create listen
_isolateFlutter._errorPort?.listen((dynamic errorData) {
if (!_isolateFlutter._completer.isCompleted) {
_isolateFlutter._completer.completeError(errorData);
_isolateFlutter.stop();
}
});
_isolateFlutter._completer = Completer<dynamic>();

_isolateFlutter._exitPort?.listen((dynamic exitData) {
if (!_isolateFlutter._completer.isCompleted) {
_isolateFlutter._completer.completeError(Exception(
'IsolateFlutter -> Isolate exited without result or error.'));
_isolateFlutter.stop();
}
});
// Create ReceivePort
_isolateFlutter._port = RawReceivePort((dynamic msg) {
_isolateFlutter._completer.complete(msg);
_isolateFlutter.stop();
}, _debugLabel);

_isolateFlutter._resultPort?.listen((dynamic resultData) {
assert(resultData == null || resultData is R);
if (!_isolateFlutter._completer.isCompleted) {
_isolateFlutter._completer.complete(resultData as R);
_isolateFlutter.stop();
}
});
// Swap an isolate
try {
final _sendPort = _isolateFlutter._port.sendPort;
_isolateFlutter._isolate = await Isolate.spawn(
_spawn,
IsolateFlutterConfiguration<Q, FutureOr<R>>(
callback, message, _sendPort, _debugLabel),
errorsAreFatal: true,
onError: _sendPort,
onExit: _sendPort,
debugName: _debugLabel,
paused: true);
} catch (e) {
throw RemoteError('IsolateFlutter cann`t be created.', '');
}

_isolateFlutter._status = IsolateFlutterStatus.Paused;

Expand Down Expand Up @@ -133,7 +111,28 @@ class IsolateFlutter {
resume();
final _result = await _completer.future;

return _result;
if (_result == null) {
throw RemoteError('IsolateFlutter exited with null.', '');
}

if (_result is List<dynamic>) {
final _type = _result.length;
switch (_type) {
case 1:
return _result[0] as R;
case 2:
await Future<Never>.error(
RemoteError(_result[0] as String, _result[1] as String));
case 3:
await Future<Never>.error(
_result[0] as Object, _result[1] as StackTrace);
default:
throw RemoteError(
'IsolateFlutter exited without result or error.', '');
}
} else {
throw RemoteError('IsolateFlutter exited without result or error.', '');
}
}

/// Pause the current isolate
Expand All @@ -154,13 +153,7 @@ class IsolateFlutter {
void stop() {
_isolate?.kill();

_resultPort?.close();
_errorPort?.close();
_exitPort?.close();

_resultPort = null;
_errorPort = null;
_exitPort = null;
_port.close();
_isolate = null;
_status = IsolateFlutterStatus.Stopped;
}
Expand All @@ -172,9 +165,16 @@ class IsolateFlutter {
}

Future<void> _spawn<Q, R>(
IsolateFlutterConfiguration<Q, FutureOr<R>> configuration) async {
final FutureOr<R> applicationResult =
await (configuration.apply() as FutureOr<R>);
final result = await applicationResult;
configuration.resultPort.send(result);
IsolateFlutterConfiguration<Q, R> configuration) async {
late final List<dynamic> _applicationResult;

try {
_applicationResult = List<R>.filled(1, await (configuration.apply()));
} catch (error, stackTrace) {
_applicationResult = List<dynamic>.filled(3, null)
..[0] = error
..[1] = stackTrace;
}

Isolate.exit(configuration.resultPort, _applicationResult);
}
6 changes: 1 addition & 5 deletions isolate_flutter/lib/src/isolate_flutter_configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ class IsolateFlutterConfiguration<Q, R> {
final String? debugLabel;

IsolateFlutterConfiguration(
this.callback,
this.message,
this.resultPort,
this.debugLabel,
);
this.callback, this.message, this.resultPort, this.debugLabel);

FutureOr<R> apply() => callback(message);
}
38 changes: 26 additions & 12 deletions isolate_flutter/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,58 @@ packages:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.2.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
version: "1.16.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.7.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.1.2"
sdks:
dart: ">=2.12.0 <3.0.0"
dart: ">=2.17.0-206.0.dev <3.0.0"
7 changes: 5 additions & 2 deletions isolate_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
name: isolate_flutter
description: IsolateFlutter provides a way to launch 'dart:isolate' library in Flutter (iOS and Android).
version: 2.0.0
version: 3.0.0
homepage: https://github.com/thongdn-it/isolate_flutter/tree/master/isolate_flutter
repository: https://github.com/thongdn-it/isolate_flutter/tree/master/isolate_flutter

environment:
sdk: ">=2.12.0 <3.0.0"
sdk: '>=2.12.0 <3.0.0'

dependencies:
flutter:
sdk: flutter

dev_dependencies:
flutter_lints: ^2.0.0

0 comments on commit dbc82d3

Please sign in to comment.