Is there currently a way to compute a dart function with webworkers?
Asked Answered
T

1

6

I am currently trying to run a A* seek computation on flutter web

class AStarSeeker extends Seeker {
  @override
  Future<Path> Function() seek(SeekComputationInput input) {
    return () => compute(doComputation, input);
  }
}

Future<Path> doComputation(SeekComputationInput input) async
{
  return Path.empty;
}

But I read that compute() does not currently work on flutter web. Is there a way that I can run my dart function with a webworker? I read that you can run js functions but couldn't find anything about dart functions.

Toast answered 27/1, 2022 at 14:41 Comment(0)
E
4

Sounds like you can use raw Isolates in Dart. Read the official doc about isolates, which are just like threads in other languages.

By the way this link may be helpful: Dart: in browser webworker written in dart and used in dart2js and https://api.dart.dev/stable/2.16.0/dart-html/Worker-class.html

UPDATE

Sounds like isolate does not work in web. Then what about the "Worker" approach I mentioned above. Notice that you can always compile your dart code to a js file, so even if Worker only supports js you can still execute dart there.

This https://dev.to/kyorohiro/isolate-at-flutter-for-web-28lg sounds like a good tutorial.

The core part:

parent.dart

import 'dart:html' as html;

main() async {
  if(html.Worker.supported) {
      var myWorker = new html.Worker("ww.dart.js");
      myWorker.onMessage.listen((event) {
        print("main:receive: ${event.data}");
      });
      myWorker.postMessage("Hello!!");
  } else {
    print('Your browser doesn\'t support web workers.');
  }
}

child.dart

import 'dart:async';
import 'dart:html' as html;

import 'dart:js' as js;
import 'package:js/js.dart' as pjs;
import 'package:js/js_util.dart' as js_util;

@pjs.JS('self')
external dynamic get globalScopeSelf;


Stream<T> callbackToStream<J, T>(String name, T Function(J jsValue) unwrapValue) {
  var controller = StreamController<T>.broadcast(sync: true);
  js_util.setProperty(js.context['self'], name, js.allowInterop((J event) {
    controller.add(unwrapValue(event));
  }));
  return controller.stream;
}

void jsSendMessage( dynamic object, dynamic m) {
  js.context.callMethod('postMessage',[m]);
}

main() {
    callbackToStream('onmessage', (html.MessageEvent e)  {
      return js_util.getProperty(e, 'data');
    }).listen((message) {
      print('>>> ${message}');
      jsSendMessage(js.context, 'callback: ${message}');
    });
}
Evelunn answered 1/2, 2022 at 6:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.