8a51cb6093
Change-Id: I8fafc8c2788faf848a8a8488b76cb163b7679308 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425330 Commit-Queue: Lasse Nielsen <lrn@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com> Reviewed-by: Lasse Nielsen <lrn@google.com>
187 lines
4.6 KiB
Dart
187 lines
4.6 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.
|
|
|
|
library MintMakerTest;
|
|
|
|
import 'dart:async';
|
|
import 'dart:isolate';
|
|
import 'package:expect/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();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|