6b3abe0a98
Issue b/177800357. TEST=existing test suite Change-Id: Id6b113932ab7014b8fa6c105845c5c490b60f5e8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181320 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
188 lines
4.7 KiB
Dart
188 lines
4.7 KiB
Dart
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit
|
|
// VMOptions=--no-enable-isolate-groups
|
|
|
|
library MintMakerTest;
|
|
|
|
import 'dart:async';
|
|
import 'dart:isolate';
|
|
import 'package:async_helper/async_helper.dart';
|
|
import 'package:expect/expect.dart';
|
|
|
|
class Mint {
|
|
Map<SendPort, Purse> _registry;
|
|
late SendPort port;
|
|
|
|
Mint() : _registry = new Map<SendPort, Purse>() {
|
|
ReceivePort mintPort = new ReceivePort();
|
|
port = mintPort.sendPort;
|
|
serveMint(mintPort);
|
|
}
|
|
|
|
void serveMint(ReceivePort port) {
|
|
port.listen((message) {
|
|
int balance = message[0];
|
|
Purse purse = createPurse(balance);
|
|
message[1].send(purse.port);
|
|
});
|
|
}
|
|
|
|
Purse createPurse(int balance) {
|
|
Purse purse = new Purse(this, balance);
|
|
_registry[purse.port] = purse;
|
|
return purse;
|
|
}
|
|
|
|
Purse lookupPurse(SendPort port) {
|
|
return (_registry[port])!;
|
|
}
|
|
}
|
|
|
|
class MintWrapper {
|
|
SendPort _mint;
|
|
MintWrapper(SendPort this._mint) {}
|
|
|
|
void createPurse(int balance, handlePurse(PurseWrapper purse)) {
|
|
ReceivePort reply = new ReceivePort();
|
|
reply.first.then((purse) {
|
|
handlePurse(new PurseWrapper(purse as SendPort));
|
|
});
|
|
_mint.send([balance, reply.sendPort]);
|
|
}
|
|
}
|
|
|
|
class Purse {
|
|
Mint mint;
|
|
int balance;
|
|
late SendPort port;
|
|
|
|
Purse(this.mint, this.balance) {
|
|
ReceivePort recipient = new ReceivePort();
|
|
port = recipient.sendPort;
|
|
servePurse(recipient);
|
|
}
|
|
|
|
void servePurse(ReceivePort recipient) {
|
|
recipient.listen((message) {
|
|
String command = message[0];
|
|
if (command == "balance") {
|
|
SendPort replyTo = message.last;
|
|
replyTo.send(queryBalance());
|
|
} else if (command == "deposit") {
|
|
Purse source = mint.lookupPurse(message[2]);
|
|
deposit(message[1], source);
|
|
} else if (command == "sprout") {
|
|
SendPort replyTo = message.last;
|
|
Purse result = sproutPurse();
|
|
replyTo.send(result.port);
|
|
} else {
|
|
// TODO: Send an exception back.
|
|
throw new UnsupportedError("Unsupported commend: $command");
|
|
}
|
|
});
|
|
}
|
|
|
|
int queryBalance() {
|
|
return balance;
|
|
}
|
|
|
|
Purse sproutPurse() {
|
|
return mint.createPurse(0);
|
|
}
|
|
|
|
void deposit(int amount, Purse source) {
|
|
// TODO: Throw an exception if the source purse doesn't hold
|
|
// enough dough.
|
|
balance += amount;
|
|
source.balance -= amount;
|
|
}
|
|
}
|
|
|
|
class PurseWrapper {
|
|
SendPort _purse;
|
|
|
|
PurseWrapper(this._purse) {}
|
|
|
|
void _sendReceive<T>(String message, replyHandler(T reply)) {
|
|
ReceivePort reply = new ReceivePort();
|
|
_purse.send([message, reply.sendPort]);
|
|
reply.first.then((a) => replyHandler(a as T));
|
|
}
|
|
|
|
void queryBalance(handleBalance(int balance)) {
|
|
_sendReceive("balance", handleBalance);
|
|
}
|
|
|
|
void sproutPurse(handleSprouted(PurseWrapper sprouted)) {
|
|
_sendReceive("sprout", (SendPort sprouted) {
|
|
handleSprouted(new PurseWrapper(sprouted));
|
|
});
|
|
}
|
|
|
|
void deposit(PurseWrapper source, int amount) {
|
|
_purse.send(["deposit", amount, source._purse]);
|
|
}
|
|
}
|
|
|
|
mintMakerWrapper(SendPort replyPort) {
|
|
ReceivePort receiver = new ReceivePort();
|
|
replyPort.send(receiver.sendPort);
|
|
receiver.listen((replyTo) {
|
|
Mint mint = new Mint();
|
|
(replyTo as SendPort).send(mint.port);
|
|
});
|
|
}
|
|
|
|
class MintMakerWrapper {
|
|
final SendPort _port;
|
|
|
|
static Future<MintMakerWrapper> create() {
|
|
ReceivePort reply = new ReceivePort();
|
|
return Isolate.spawn(mintMakerWrapper, reply.sendPort)
|
|
.then((_) => reply.first.then((port) => new MintMakerWrapper._(port)));
|
|
}
|
|
|
|
MintMakerWrapper._(this._port);
|
|
|
|
void makeMint(handleMint(MintWrapper mint)) {
|
|
ReceivePort reply = new ReceivePort();
|
|
reply.first.then((mint) {
|
|
handleMint(new MintWrapper(mint as SendPort));
|
|
});
|
|
_port.send(reply.sendPort);
|
|
}
|
|
}
|
|
|
|
_checkBalance(PurseWrapper wrapper, expected) {
|
|
wrapper.queryBalance((balance) {
|
|
Expect.equals(balance, expected);
|
|
});
|
|
}
|
|
|
|
void main([args, port]) {
|
|
asyncStart();
|
|
MintMakerWrapper.create().then((mintMaker) {
|
|
mintMaker.makeMint((mint) {
|
|
mint.createPurse(100, (purse) {
|
|
_checkBalance(purse, 100);
|
|
purse.sproutPurse((sprouted) {
|
|
_checkBalance(sprouted, 0);
|
|
_checkBalance(purse, 100);
|
|
|
|
sprouted.deposit(purse, 5);
|
|
_checkBalance(sprouted, 0 + 5);
|
|
_checkBalance(purse, 100 - 5);
|
|
|
|
sprouted.deposit(purse, 42);
|
|
_checkBalance(sprouted, 0 + 5 + 42);
|
|
_checkBalance(purse, 100 - 5 - 42);
|
|
asyncEnd();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|