Skip to content

Commit

Permalink
Merge pull request #2064 from fzyzcjy/feat/12204
Browse files Browse the repository at this point in the history
Refactor internal code
  • Loading branch information
fzyzcjy authored Jun 13, 2024
2 parents 89ff866 + ed2d596 commit 2287e3c
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 287 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use crate::codegen::ir::mir::ty::primitive::MirTypePrimitive;
impl<'a> WireDartCodecDcoGeneratorDecoderTrait for PrimitiveListWireDartCodecDcoGenerator<'a> {
fn generate_impl_decode_body(&self) -> String {
match &self.mir.primitive {
MirTypePrimitive::I64 => "return Int64List.from(raw);".into(),
MirTypePrimitive::U64 => "return Uint64List.from(raw);".into(),
MirTypePrimitive::I64 => "return dcoDecodeInt64List(raw);".into(),
MirTypePrimitive::U64 => "return dcoDecodeUint64List(raw);".into(),
_ => gen_decode_simple_type_cast(self.mir.clone().into(), self.context),
}
}
Expand Down
137 changes: 62 additions & 75 deletions frb_dart/lib/src/generalized_isolate/_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@ import 'dart:html' as html;
import 'dart:html' hide MessagePort;

import 'package:flutter_rust_bridge/src/platform_types/_web.dart';
import 'package:flutter_rust_bridge/src/platform_utils/_web.dart';

/// {@macro flutter_rust_bridge.internal}
String serializeNativePort(NativePortType port) => port.name;

/// {@macro flutter_rust_bridge.only_for_generated_code}
typedef MessagePort = _PortLike;

/// {@macro flutter_rust_bridge.only_for_generated_code}
typedef SendPort = _PortLike;
/// {@macro flutter_rust_bridge.internal}
ReceivePort broadcastPort(String channelName) => ReceivePort._raw(
RawReceivePort._raw(_WebChannel.broadcastChannel(channelName)));

/// Web implementation of the `dart:isolate`'s ReceivePort.
/// {@template flutter_rust_bridge.same_as_native}
/// Web implementation of the one with same name in native.
/// {@endtemplate}
class ReceivePort extends Stream<dynamic> {
/// The receive port.
final RawReceivePort _rawReceivePort;

/// Create a new receive port from an optional [RawReceivePort].
/// {@macro flutter_rust_bridge.same_as_native}
factory ReceivePort() => ReceivePort._raw();

ReceivePort._raw([RawReceivePort? rawReceivePort])
Expand All @@ -35,7 +33,7 @@ class ReceivePort extends Stream<dynamic> {
void Function()? onDone,
bool? cancelOnError,
}) {
return _rawReceivePort._receivePort.onMessage.map(_extractData).listen(
return _rawReceivePort._webReceivePort._onMessage.map(_extractData).listen(
onData,
onError: onError,
onDone: onDone,
Expand All @@ -45,131 +43,120 @@ class ReceivePort extends Stream<dynamic> {

static dynamic _extractData(MessageEvent event) => event.data;

/// The send port.
/// {@macro flutter_rust_bridge.same_as_native}
SendPort get sendPort => _rawReceivePort.sendPort;

/// Close the receive port, ignoring any further messages.
/// {@macro flutter_rust_bridge.same_as_native}
void close() => _rawReceivePort.close();
}

/// Wrapper around a [MessageChannel].
/// {@macro flutter_rust_bridge.same_as_native}
class RawReceivePort {
/// The underlying message channel.
final _Channel _channel;
final _WebChannel _webChannel;

/// {@macro flutter_rust_bridge.only_for_generated_code}
/// {@macro flutter_rust_bridge.same_as_native}
factory RawReceivePort() => RawReceivePort._raw();

RawReceivePort._raw([_Channel? channel])
: _channel = channel ?? _Channel.messageChannel();
RawReceivePort._raw([_WebChannel? channel])
: _webChannel = channel ?? _WebChannel.messageChannel();

/// {@macro flutter_rust_bridge.same_as_native}
set handler(Function(dynamic) handler) {
_receivePort.onMessage.listen((event) => handler(event.data));
_webReceivePort._onMessage.listen((event) => handler(event.data));
}

/// Close the receive port.
void close() => _channel.receivePort.close();
/// {@macro flutter_rust_bridge.same_as_native}
void close() => _webReceivePort._close();

/// The port to be used by other workers.
SendPort get sendPort => _channel.sendPort;
/// {@macro flutter_rust_bridge.same_as_native}
SendPort get sendPort => _webChannel._sendPort;

SendPort get _receivePort => _channel.receivePort;
_WebPortLike get _webReceivePort => _webChannel._receivePort;
}

/// {@macro flutter_rust_bridge.internal}
ReceivePort broadcastPort(String channelName) => ReceivePort._raw(
RawReceivePort._raw(_Channel.broadcastChannel(channelName)));
/// {@macro flutter_rust_bridge.same_as_native}
class SendPort {
/// {@macro flutter_rust_bridge.same_as_native}
final html.EventTarget nativePort;

abstract class _Channel {
SendPort get sendPort;
const SendPort._(this.nativePort);
}

SendPort get receivePort;
abstract class _WebChannel {
SendPort get _sendPort;

const _Channel();
_WebPortLike get _receivePort;

factory _Channel.messageChannel() = _MessageChannelWrapper;
factory _WebChannel.messageChannel() = _WebMessageChannel;

factory _Channel.broadcastChannel(String channelName) =
_BroadcastChannelWrapper;
factory _WebChannel.broadcastChannel(String channelName) =
_WebBroadcastChannel;
}

class _MessageChannelWrapper implements _Channel {
final channel = MessageChannel();
class _WebMessageChannel implements _WebChannel {
final _channel = MessageChannel();

@override
SendPort get sendPort => _PortLike.messagePort(channel.port2);
SendPort get _sendPort => SendPort._(_channel.port2);

@override
SendPort get receivePort => _PortLike.messagePort(channel.port1);
_WebPortLike get _receivePort => _WebPortLike._messagePort(_channel.port1);
}

class _BroadcastChannelWrapper implements _Channel {
class _WebBroadcastChannel implements _WebChannel {
final BroadcastChannel _sendChannel;
final BroadcastChannel _receiveChannel;

_BroadcastChannelWrapper(String channelName)
_WebBroadcastChannel(String channelName)
// Note: It is *wrong* to reuse the same HTML BroadcastChannel object,
// because HTML BroadcastChannel spec says that, the event will not be fired
// at the object which sends it. Therefore, we need two different objects.
: _sendChannel = BroadcastChannel(channelName),
_receiveChannel = BroadcastChannel(channelName);

@override
SendPort get sendPort => _PortLike.broadcastChannel(_sendChannel);
SendPort get _sendPort => SendPort._(_sendChannel);

@override
SendPort get receivePort => _PortLike.broadcastChannel(_receiveChannel);
_WebPortLike get _receivePort =>
_WebPortLike._broadcastChannel(_receiveChannel);
}

/// [html.MessagePort]'s interface.
abstract class _PortLike {
const _PortLike._();
/// {@macro flutter_rust_bridge.same_as_native}
abstract class _WebPortLike {
const _WebPortLike._();

factory _PortLike.messagePort(html.MessagePort port) = _MessagePortWrapper;
factory _WebPortLike._messagePort(html.MessagePort port) = _WebMessagePort;

factory _PortLike.broadcastChannel(BroadcastChannel channel) =
_BroadcastPortWrapper;
factory _WebPortLike._broadcastChannel(BroadcastChannel channel) =
_WebBroadcastPort;

void postMessage(Object? value);
void _close();

void close();
/// {@macro flutter_rust_bridge.same_as_native}
html.EventTarget get _nativePort;

html.EventTarget get nativePort;

Stream<MessageEvent> get onMessage => _kMessageEvent.forTarget(nativePort);
Stream<MessageEvent> get _onMessage => _kMessageEvent.forTarget(_nativePort);
static const _kMessageEvent = EventStreamProvider<MessageEvent>('message');
}

class _MessagePortWrapper extends _PortLike {
class _WebMessagePort extends _WebPortLike {
@override
final html.MessagePort nativePort;

_MessagePortWrapper(this.nativePort) : super._();
final html.MessagePort _nativePort;

@override
void postMessage(message, [List<Object>? transfer]) =>
nativePort.postMessage(message, transfer);
_WebMessagePort(this._nativePort) : super._();

@override
void close() => nativePort.close();
void _close() => _nativePort.close();
}

class _BroadcastPortWrapper extends _PortLike {
// Indeed a BroadcastChannel, not a Broadcast "Port"
class _WebBroadcastPort extends _WebPortLike {
@override
final html.BroadcastChannel nativePort;
final html.BroadcastChannel _nativePort;

_BroadcastPortWrapper(this.nativePort) : super._();

/// This presents a limitation of BroadcastChannel,
/// i.e. it cannot carry transferables and will unconditionally clone the items.
@override
void postMessage(message, [List<Object>? transfer]) {
if (transfer != null && transfer.isNotEmpty) {
jsConsoleWarn("Ignoring transferables for BroadcastPort:", transfer);
}
nativePort.postMessage(message ?? false);
}
_WebBroadcastPort(this._nativePort) : super._();

@override
void close() => nativePort.close();
void _close() => _nativePort.close();
}
55 changes: 15 additions & 40 deletions frb_dart/lib/src/generalized_typed_data/_io.dart
Original file line number Diff line number Diff line change
@@ -1,44 +1,19 @@
import 'dart:collection';
import 'dart:typed_data' as $data;

import 'package:flutter_rust_bridge/src/exceptions.dart';

abstract class _TypedList<T> extends ListMixin<T> {
List<int> get inner;

@override
_TypedList<T> operator +(Object other);

T _raw2dart(int value);

int _dart2raw(Object? value);

@override
T operator [](int index) => _raw2dart(inner[index]);

@override
void operator []=(int index, Object? value) =>
inner[index] = _dart2raw(value);

@override
int get length => inner.length;

@override
set length(int newLength) => throw const UnmodifiableTypedListException();
}
import 'package:flutter_rust_bridge/src/generalized_typed_data/common.dart';

/// A strict version of [$data.Int64List] which always returns a [BigInt].
class Int64List extends _TypedList<BigInt> {
class Int64List extends TypedList<BigInt, int> {
@override
final $data.Int64List inner;

/// Construct a list from normal Int64List
Int64List.from(this.inner);
/// {@macro flutter_rust_bridge.only_for_generated_code}
Int64List.raw(this.inner);

/// Construct a list of the [length].
factory Int64List(int length) => Int64List.from($data.Int64List(length));
factory Int64List(int length) => Int64List.raw($data.Int64List(length));

/// Construct a list from `List<int>`.
/// Construct a list raw `List<int>`.
Int64List.fromList(List<int> ints) : inner = $data.Int64List.fromList(ints);

/// Construct a list view
Expand All @@ -50,14 +25,14 @@ class Int64List extends _TypedList<BigInt> {
: inner = $data.Int64List.sublistView(data, start, end);

@override
int _dart2raw(Object? value) {
int outer2inner(Object? value) {
if (value is BigInt) return value.toInt();
if (value is int) return value;
throw ArgumentError.value(value);
}

@override
BigInt _raw2dart(int value) => BigInt.from(value);
BigInt inner2outer(int value) => BigInt.from(value);

@override
Int64List operator +(Object other) {
Expand All @@ -72,17 +47,17 @@ class Int64List extends _TypedList<BigInt> {
}

/// A strict version of [$data.Uint64List] which always returns a [BigInt].
class Uint64List extends _TypedList<BigInt> {
class Uint64List extends TypedList<BigInt, int> {
@override
final $data.Uint64List inner;

/// Construct a list from normal Int64List
Uint64List.from(this.inner);
/// {@macro flutter_rust_bridge.only_for_generated_code}
Uint64List.raw(this.inner);

/// Construct a list of the [length].
factory Uint64List(int length) => Uint64List.from($data.Uint64List(length));
factory Uint64List(int length) => Uint64List.raw($data.Uint64List(length));

/// Construct a list from `List<int>`.
/// Construct a list raw `List<int>`.
Uint64List.fromList(List<int> ints) : inner = $data.Uint64List.fromList(ints);

/// Construct a list view
Expand All @@ -97,7 +72,7 @@ class Uint64List extends _TypedList<BigInt> {
static const _minI64 = 0x8000000000000000;

@override
BigInt _raw2dart(int value) {
BigInt inner2outer(int value) {
if (value < 0) {
// two's complement signed integer to unsigned bigint
return _maxI64b + BigInt.from(value - _minI64) + BigInt.one;
Expand All @@ -106,7 +81,7 @@ class Uint64List extends _TypedList<BigInt> {
}

@override
int _dart2raw(Object? value) {
int outer2inner(Object? value) {
if (value is int) return value;
if (value is BigInt) {
if (value > _maxI64b) {
Expand Down
Loading

0 comments on commit 2287e3c

Please sign in to comment.