Dart is isolated as a worker.

Edited to make the question more understandable.

I am trying to work with Isolates (or web workers) in Dart. The only ways to find the connection between the main and isolated threads are to send and call, and then from the main thread. But this is a good way for the main thread to pass some data to isolation.

What if I want isolation to be the one who generates the information? How is a game engine that does all the physics in the workplace and then sends the updated world information to the main stream? In JavaScript, you can send data at any time. Is there an effective way to dart? Or do I still need to wait until the main stream calls me and then passes it to him?

PS Interestingly, he calls and then blocks the flow until the answer is executed or not?

+6
source share
4 answers

WARNING: this code only works in very old versions of Dart. It does not work on Dart 1.0 or later.

As you note, in order to send messages to isolation, you need to have a handle on it sendport.

#import('dart:isolate'); main() { SendPort sendPort = spawnFunction(doWork); sendPort.call("hey 1").then((String res) => print("result was: [$res]")); sendPort.call("hey 2").then((String res) => print("result was: [$res]")); } doWork() { port.receive((msg, reply) { msg = "msg $msg"; reply.send(msg); }); } 

however, since the main Dart stream itself is an isolate, you can send data to it using the global port function:

 #import('dart:isolate'); #import('dart:io'); main() { port.receive((data, reply) { // in here you can access objects created in the main thread print("handle [${data['text']}] for index ${data['index']}"); }); SendPort workPort = spawnFunction(doWork); workPort.send("msg", port.toSendPort()); } doWork() { port.receive((msg, reply) { int i = 0; new Timer.repeating(1000, (Timer timer) { i++; var data = { "text": "$msg $i", "index": i }; print("sending $data"); reply.send(data); }); }); } 

Please note that there are certain restrictions on what can be sent back and forth between isolates, and also currently isolates each other in JS and in the virtual machine. Current restrictions are well described here .

+3
source

As in Dart 1.0, you can use isolates like this:

 import 'dart:isolate'; import 'dart:async'; void doStuff(SendPort sendPort) { print('hi from inside isolate'); ReceivePort receivePort = new ReceivePort(); sendPort.send(receivePort.sendPort); receivePort.listen((msg) { print('Received in isolate: [$msg]'); sendPort.send('ECHO: $msg'); }); } void main() { SendPort sendPort; ReceivePort receive = new ReceivePort(); receive.listen((msg) { if (sendPort == null) { sendPort = msg; } else { print('From isolate: $msg'); } }); int counter = 0; Isolate.spawn(doStuff, receive.sendPort).then((isolate) { new Timer.periodic(const Duration(seconds:1), (t) { sendPort.send('Count is ${counter++}'); }); }); } 
+3
source

Here is an example where a parent creates two isolators, and then two isolators also talk to each other along with the parent process.

Parent code:

 import 'dart:isolate'; import 'dart:html'; import 'dart:async'; main() { querySelector('#output').text = 'Your Dart app is running.'; int counter = 0; // Parent - Child 1 SendPort csendPort1; ReceivePort receivePort1 = new ReceivePort(); // Parent - Child 2 SendPort csendPort2; ReceivePort receivePort2 = new ReceivePort(); // Child1 - Child2 SendPort csendPort11; SendPort csendPort12; // Child 1 receivePort1.listen((msg) { if (csendPort1 == null) { csendPort1 = msg; } else if (csendPort11 == null) { csendPort11 = msg; } else { print('$msg');`enter code here` } }); bool child1 = false; Isolate.spawnUri(Uri.parse('child.dart'), [], receivePort1.sendPort).then((isolate) { print('Child 1 isolate spawned'); new Timer.periodic(const Duration(milliseconds: 500), (t) { if (csendPort11 != null && csendPort12 != null && child1 == false) { child1 = true; csendPort12.send(csendPort11); } else { csendPort1.send('Parent-Child1: ${counter++}'); } }); }); // Child 2 receivePort2.listen((msg) { if (csendPort2 == null) { csendPort2 = msg; } else if (csendPort12 == null) { csendPort12 = msg; } else { print('$msg'); } }); bool child2 = false; Isolate.spawnUri(Uri.parse('child.dart'), [], receivePort2.sendPort).then((isolate) { print('Child 2 isolate spawned'); new Timer.periodic(const Duration(milliseconds: 500), (t) { if (csendPort11 != null && csendPort12 != null && child2 == false) { child2 = true; csendPort11.send(csendPort12); } else { csendPort2.send('Parent-Child2: ${counter++}'); } }); }); } 

Child Code:

 import 'dart:isolate'; import 'dart:async'; int pcounter = 0; int ccounter = 0; SendPort csendPort; void handleTimeout() { csendPort.send("${ccounter++}"); } main(List<String> args, SendPort psendPort) { // Parent Comm ReceivePort creceivePort1 = new ReceivePort(); psendPort.send(creceivePort1.sendPort); creceivePort1.listen((msg) { psendPort.send('Child-Parent: ${pcounter++} - ${msg}'); }); // Child-Child Comm ReceivePort creceivePort2 = new ReceivePort(); psendPort.send(creceivePort2.sendPort); creceivePort2.listen((msg) { if (csendPort == null) { csendPort = msg; csendPort.send("${ccounter++}"); } else { print("Child-Child: $msg"); var duration = const Duration(milliseconds: 2000); new Timer(duration, handleTimeout); } }); } 

HTML code:

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="scaffolded-by" content="https://github.com/google/stagehand"> <title>WebIsolateTest</title> <link rel="stylesheet" href="styles.css"> <script defer src="main.dart" type="application/dart"></script> <script defer src="packages/browser/dart.js"></script> </head> <body> <div id="output"></div> </body> </html> 
+1
source

Now you can use the MessageBox class to communicate differently. This code sends a message from the Isolate code as soon as it receives the end of the Sink MessageBox. The main stream receives messages sent from Isolate and prints it to the Dartium console. After you receive Sink, you can start your game logic and send updates using the received receiver.

 import 'dart:html'; import 'dart:isolate'; void main() { IsolateSink isolateSink = streamSpawnFunction(myIsolateEntryPoint); MessageBox isolateMessageBox = new MessageBox(); isolateSink.add(isolateMessageBox.sink); isolateMessageBox.stream.listen((String data) { print(data); }); } void myIsolateEntryPoint() { stream.listen((IsolateSink messageBoxSink) { messageBoxSink.add("Test"); }); } 
0
source

Source: https://habr.com/ru/post/914055/


All Articles