Some fixes for dart2wasm (flutter/engine#38167)

* A few fixes to get things compiling via dart2wasm.

* Use `futureToPromise`.

* Some more fixes for dart2wasm.

* Allow promises to have nullable objects.
This commit is contained in:
Jackson Gardner
2022-12-13 15:28:45 -08:00
committed by GitHub
parent 65e5a08702
commit 1cd2486423
6 changed files with 44 additions and 35 deletions

View File

@@ -40,30 +40,17 @@ class AppBootstrap {
// This is a convenience method that lets the programmer call "autoStart"
// from JavaScript immediately after the main.dart.js has loaded.
// Returns a promise that resolves to the Flutter app that was started.
autoStart: allowInterop(() {
return Promise<FlutterApp>(allowInterop((
PromiseResolver<FlutterApp> resolve,
PromiseRejecter _,
) async {
await autoStart();
// Return the App that was just started
resolve(_prepareFlutterApp());
}));
}),
autoStart: allowInterop(() => futureToPromise(() async {
await autoStart();
// Return the App that was just started
return _prepareFlutterApp();
}())),
// Calls [_initEngine], and returns a JS Promise that resolves to an
// app runner object.
initializeEngine: allowInterop(([JsFlutterConfiguration? configuration]) {
// `params` coming from Javascript may be used to configure the engine intialization.
// The internal `initEngine` function must accept those params.
return Promise<FlutterAppRunner>(allowInterop((
PromiseResolver<FlutterAppRunner> resolve,
PromiseRejecter _,
) async {
await _initializeEngine(configuration);
// Return an app runner object
resolve(_prepareAppRunner());
}));
}),
initializeEngine: allowInterop(([JsFlutterConfiguration? configuration]) => futureToPromise(() async {
await _initializeEngine(configuration);
return _prepareAppRunner();
}()))
);
}
@@ -77,7 +64,7 @@ class AppBootstrap {
) async {
await _runApp();
// Return the App that was just started
resolve(_prepareFlutterApp());
resolve.resolve(_prepareFlutterApp());
}));
}));
}

View File

@@ -176,9 +176,9 @@ class ColorSpace {}
@staticInterop
class SkWebGLContextOptions {
external factory SkWebGLContextOptions({
required int antialias,
required double antialias,
// WebGL version: 1 or 2.
required int majorVersion,
required double majorVersion,
});
}
@@ -1362,7 +1362,8 @@ final SkFloat32List _sharedSkColor3 = mallocFloat32List(4);
@JS('window.flutterCanvasKit.Path')
@staticInterop
class SkPath {
external factory SkPath([SkPath? other]);
external factory SkPath();
external factory SkPath.from(SkPath other);
}
extension SkPathExtension on SkPath {

View File

@@ -325,7 +325,7 @@ class Surface {
// Default to no anti-aliasing. Paint commands can be explicitly
// anti-aliased by setting their `Paint` object's `antialias` property.
antialias: _kUsingMSAA ? 1 : 0,
majorVersion: webGLVersion,
majorVersion: webGLVersion.toDouble(),
),
).toInt();

View File

@@ -54,7 +54,7 @@ abstract class FlutterEngineInitializer{
/// [JsFlutterConfiguration] comes from `../configuration.dart`. It is the same
/// object that can be used to configure flutter "inline", through the
/// (to be deprecated) `window.flutterConfiguration` object.
typedef InitializeEngineFn = Promise<FlutterAppRunner?> Function([JsFlutterConfiguration?]);
typedef InitializeEngineFn = Promise<FlutterAppRunner> Function([JsFlutterConfiguration?]);
/// Typedef for the `autoStart` function that can be called straight from an engine initializer instance.
/// (Similar to [RunAppFn], but taking no specific "runApp" parameters).

View File

@@ -6,18 +6,39 @@
library js_promise;
import 'package:js/js.dart';
import 'package:js/js_util.dart' as js_util;
@JS()
@staticInterop
class PromiseResolver<T extends Object?> {}
extension PromiseResolverExtension<T extends Object?> on PromiseResolver<T> {
void resolve(T result) => js_util.callMethod(this, 'call', <Object>[this, if (result != null) result]);
}
@JS()
@staticInterop
class PromiseRejecter {}
extension PromiseRejecterExtension on PromiseRejecter {
void reject(Object? error) => js_util.callMethod(this, 'call', <Object>[this, if (error != null) error]);
}
/// Type-safe JS Promises
@JS('Promise')
@staticInterop
abstract class Promise<T> {
abstract class Promise<T extends Object?> {
/// A constructor for a JS promise
external factory Promise(PromiseExecutor<T> executor);
}
/// The type of function that is used to create a Promise<T>
typedef PromiseExecutor<T> = void Function(PromiseResolver<T> resolve, PromiseRejecter reject);
/// The type of function used to resolve a Promise<T>
typedef PromiseResolver<T> = void Function(T result);
/// The type of function used to reject a Promise (of any <T>)
typedef PromiseRejecter = void Function(Object? error);
typedef PromiseExecutor<T extends Object?> = void Function(PromiseResolver<T> resolve, PromiseRejecter reject);
Promise<T> futureToPromise<T extends Object>(Future<T> future) {
return Promise<T>(allowInterop((PromiseResolver<T> resolver, PromiseRejecter rejecter) {
future.then(
(T value) => resolver.resolve(value),
onError: (Object? error) => rejecter.reject(error));
}));
}

View File

@@ -145,7 +145,7 @@ class MultiEntriesBrowserHistory extends BrowserHistory {
if (_hasSerialCount(currentState)) {
final Map<dynamic, dynamic> stateMap =
currentState! as Map<dynamic, dynamic>;
return stateMap['serialCount'] as int;
return (stateMap['serialCount'] as double).toInt();
}
return 0;
}