Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: tests/isolate/mint_maker_test.dart

Issue 27215002: Very simple version of Isolates. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tests/isolate/message_test.dart ('k') | tests/isolate/nested_spawn2_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // Things that should be "auto-generated" are between AUTO START and
6 // AUTO END (or just AUTO if it's a single line).
7
8 library MintMakerTest; 5 library MintMakerTest;
9 import 'dart:isolate'; 6 import 'dart:isolate';
10 import '../../pkg/unittest/lib/unittest.dart'; 7 import '../../pkg/unittest/lib/unittest.dart';
11 8
12 class Mint { 9 class Mint {
13 Mint() : registry_ = new Map<SendPort, Purse>() { 10 Map<SendPort, Purse> _registry;
14 // AUTO START 11 SendPort port;
12
13 Mint() : _registry = new Map<SendPort, Purse>() {
15 ReceivePort mintPort = new ReceivePort(); 14 ReceivePort mintPort = new ReceivePort();
16 port = mintPort.toSendPort(); 15 port = mintPort.sendPort;
17 serveMint(mintPort); 16 serveMint(mintPort);
18 // AUTO END
19 } 17 }
20 18
21 // AUTO START
22 void serveMint(ReceivePort port) { 19 void serveMint(ReceivePort port) {
23 port.receive((var message, SendPort replyTo) { 20 port.listen((message) {
24 int balance = message; 21 int balance = message[0];
25 Purse purse = createPurse(balance); 22 Purse purse = createPurse(balance);
26 replyTo.send([ purse.port ], null); 23 message[1].send(purse.port);
27 }); 24 });
28 } 25 }
29 // AUTO END
30 26
31 Purse createPurse(int balance) { 27 Purse createPurse(int balance) {
32 Purse purse = new Purse(this, balance); 28 Purse purse = new Purse(this, balance);
33 registry_[purse.port] = purse; 29 _registry[purse.port] = purse;
34 return purse; 30 return purse;
35 } 31 }
36 32
37 Purse lookupPurse(SendPort port) { 33 Purse lookupPurse(SendPort port) {
38 return registry_[port]; 34 return _registry[port];
39 } 35 }
40
41 Map<SendPort, Purse> registry_;
42 // AUTO
43 SendPort port;
44 } 36 }
45 37
46 38
47 // AUTO START
48 class MintWrapper { 39 class MintWrapper {
49 MintWrapper(SendPort this.mint_) {} 40 SendPort _mint;
41 MintWrapper(SendPort this._mint) {}
50 42
51 void createPurse(int balance, handlePurse(PurseWrapper purse)) { 43 void createPurse(int balance, handlePurse(PurseWrapper purse)) {
52 mint_.call(balance).then((var message) { 44 ReceivePort reply = new ReceivePort();
53 SendPort purse = message[0]; 45 reply.first.then((SendPort purse) {
54 handlePurse(new PurseWrapper(purse)); 46 handlePurse(new PurseWrapper(purse));
55 }); 47 });
48 _mint.send([balance, reply.sendPort]);
56 } 49 }
57 50
58 SendPort mint_;
59 } 51 }
60 // AUTO END
61 52
53 class Purse {
54 Mint mint;
55 int balance;
56 SendPort port;
62 57
63 /* 58 Purse(this.mint, this.balance) {
64 One way this could look without the autogenerated code: 59 ReceivePort recipient = new ReceivePort();
65 60 port = recipient.sendPort;
66 class Mint { 61 servePurse(recipient);
67 Mint() : registry_ = new Map<SendPort, Purse>() {
68 } 62 }
69 63
70 wrap Purse createPurse(int balance) {
71 Purse purse = new Purse(this, balance);
72 registry_[purse.port] = purse;
73 return purse;
74 }
75
76 Purse lookupPurse(SendPort port) {
77 return registry_[port];
78 }
79
80 Map<SendPort, Purse> registry_;
81 }
82
83 The other end of the port would use Wrapper<Mint> as the wrapper, or
84 Future<Mint> as a future for the wrapper.
85 */
86
87
88 class Purse {
89 Purse(Mint this.mint, int this.balance) {
90 // AUTO START
91 ReceivePort recipient = new ReceivePort();
92 port = recipient.toSendPort();
93 servePurse(recipient);
94 // AUTO END
95 }
96
97 // AUTO START
98 void servePurse(ReceivePort recipient) { 64 void servePurse(ReceivePort recipient) {
99 recipient.receive((var message, SendPort replyTo) { 65 recipient.listen((message) {
100 String command = message[0]; 66 String command = message[0];
101 if (command == "balance") { 67 if (command == "balance") {
102 replyTo.send(queryBalance(), null); 68 SendPort replyTo = message.last;
69 replyTo.send(queryBalance());
103 } else if (command == "deposit") { 70 } else if (command == "deposit") {
104 Purse source = mint.lookupPurse(message[2]); 71 Purse source = mint.lookupPurse(message[2]);
105 deposit(message[1], source); 72 deposit(message[1], source);
106 } else if (command == "sprout") { 73 } else if (command == "sprout") {
74 SendPort replyTo = message.last;
107 Purse result = sproutPurse(); 75 Purse result = sproutPurse();
108 replyTo.send([ result.port ], null); 76 replyTo.send(result.port);
109 } else { 77 } else {
110 // TODO: Send an exception back. 78 // TODO: Send an exception back.
111 replyTo.send("Exception: Command not understood", null); 79 throw UnsupportedError("Unsupported commend: $command");
112 } 80 }
113 }); 81 });
114 } 82 }
115 // AUTO END
116 83
117 int queryBalance() { return balance; } 84 int queryBalance() { return balance; }
118 85
119 Purse sproutPurse() { return mint.createPurse(0); } 86 Purse sproutPurse() { return mint.createPurse(0); }
120 87
121 void deposit(int amount, Purse source) { 88 void deposit(int amount, Purse source) {
122 // TODO: Throw an exception if the source purse doesn't hold 89 // TODO: Throw an exception if the source purse doesn't hold
123 // enough dough. 90 // enough dough.
124 balance += amount; 91 balance += amount;
125 source.balance -= amount; 92 source.balance -= amount;
126 } 93 }
127
128 Mint mint;
129 int balance;
130 // AUTO
131 SendPort port;
132 } 94 }
133 95
134 96
135 // AUTO START
136 class PurseWrapper { 97 class PurseWrapper {
137 PurseWrapper(SendPort this.purse_) {} 98 SendPort _purse;
99
100 PurseWrapper(this._purse) {}
101
102 void _sendReceive(message, replyHandler(reply)) {
103 ReceivePort reply = new ReceivePort();
104 _purse.send([message, reply.sendPort]);
105 reply.first.then(replyHandler);
106 }
138 107
139 void queryBalance(handleBalance(int balance)) { 108 void queryBalance(handleBalance(int balance)) {
140 purse_.call([ "balance" ]).then((var message) { 109 _sendReceive("balance", handleBalance);
141 int balance = message;
142 handleBalance(balance);
143 });
144 } 110 }
145 111
146 void sproutPurse(handleSprouted(PurseWrapper sprouted)) { 112 void sproutPurse(handleSprouted(PurseWrapper sprouted)) {
147 purse_.call([ "sprout" ]).then((var message) { 113 _sendReceive("sprout", (SendPort sprouted) {
148 SendPort sprouted = message[0];
149 handleSprouted(new PurseWrapper(sprouted)); 114 handleSprouted(new PurseWrapper(sprouted));
150 }); 115 });
151 } 116 }
152 117
153 void deposit(PurseWrapper source, int amount) { 118 void deposit(PurseWrapper source, int amount) {
154 purse_.send([ "deposit", amount, source.purse_ ], null); 119 _purse.send([ "deposit", amount, source._purse ]);
155 } 120 }
121 }
156 122
157 123 mintMakerWrapper(SendPort replyPort) {
158 SendPort purse_; 124 ReceivePort receiver = new ReceivePort();
159 } 125 replyPort.send(receiver.sendPort);
160 // AUTO END 126 receiver.listen((SendPort replyTo) {
161
162
163 // AUTO STATUS UNCLEAR!
164
165 mintMakerWrapper() {
166 port.receive((var message, SendPort replyTo) {
167 Mint mint = new Mint(); 127 Mint mint = new Mint();
168 replyTo.send([ mint.port ], null); 128 replyTo.send(mint.port);
169 }); 129 });
170 } 130 }
171 131
172 class MintMakerWrapper { 132 class MintMakerWrapper {
173 MintMakerWrapper() { 133 final SendPort _port;
174 port_ = spawnFunction(mintMakerWrapper); 134
135 static Future<MintMakerWrapper> create() {
136 ReceivePort reply = new ReceivePort();
137 return Isolate.spawn(mintMakerWrapper, reply.sendPort).then((_) =>
138 reply.first.then((port) => new MintMakerWrapper._(port)));
175 } 139 }
176 140
141 MintMakerWrapper._(this._port);
142
177 void makeMint(handleMint(MintWrapper mint)) { 143 void makeMint(handleMint(MintWrapper mint)) {
178 port_.call(null).then((var message) { 144 ReceivePort reply = new ReceivePort();
179 SendPort mint = message[0]; 145 reply.first.then((SendPort mint) { handleMint(new MintWrapper(mint)); });
180 handleMint(new MintWrapper(mint)); 146 _port.send(reply.sendPort);
181 });
182 } 147 }
183
184 SendPort port_;
185 } 148 }
186 149
187 _checkBalance(PurseWrapper wrapper, expected) { 150 _checkBalance(PurseWrapper wrapper, expected) {
188 wrapper.queryBalance(expectAsync1((int balance) { 151 wrapper.queryBalance(expectAsync1((int balance) {
189 expect(balance, equals(expected)); 152 expect(balance, equals(expected));
190 })); 153 }));
191 } 154 }
192 155
193 main() { 156 main() {
194 test("creating purse, deposit, and query balance", () { 157 test("creating purse, deposit, and query balance", () {
195 MintMakerWrapper mintMaker = new MintMakerWrapper(); 158 MintMakerWrapper.create().then(expectAsync1((mintMaker) {
196 mintMaker.makeMint(expectAsync1((MintWrapper mint) { 159 mintMaker.makeMint(expectAsync1((MintWrapper mint) {
197 mint.createPurse(100, expectAsync1((PurseWrapper purse) { 160 mint.createPurse(100, expectAsync1((PurseWrapper purse) {
198 _checkBalance(purse, 100);
199 purse.sproutPurse(expectAsync1((PurseWrapper sprouted) {
200 _checkBalance(sprouted, 0);
201 _checkBalance(purse, 100); 161 _checkBalance(purse, 100);
162 purse.sproutPurse(expectAsync1((PurseWrapper sprouted) {
163 _checkBalance(sprouted, 0);
164 _checkBalance(purse, 100);
202 165
203 sprouted.deposit(purse, 5); 166 sprouted.deposit(purse, 5);
204 _checkBalance(sprouted, 0 + 5); 167 _checkBalance(sprouted, 0 + 5);
205 _checkBalance(purse, 100 - 5); 168 _checkBalance(purse, 100 - 5);
206 169
207 sprouted.deposit(purse, 42); 170 sprouted.deposit(purse, 42);
208 _checkBalance(sprouted, 0 + 5 + 42); 171 _checkBalance(sprouted, 0 + 5 + 42);
209 _checkBalance(purse, 100 - 5 - 42); 172 _checkBalance(purse, 100 - 5 - 42);
173 }));
210 })); 174 }));
211 })); 175 }));
212 })); 176 }));
213 }); 177 });
214
215 /* This is an attempt to show how the above code could look like if we had
216 * better language support for asynchronous messages (deferred/asynccall).
217 * The static helper methods like createPurse and queryBalance would also
218 * have to be marked async.
219
220 void run(port) {
221 MintMakerWrapper mintMaker = spawnMintMaker();
222 deferred {
223 MintWrapper mint = asynccall mintMaker.createMint();
224 PurseWrapper purse = asynccall mint.createPurse(100);
225 expect(asynccall purse.queryBalance(), 100);
226
227 PurseWrapper sprouted = asynccall purse.sproutPurse();
228 expect(asynccall sprouted.queryBalance(), 0);
229
230 asynccall sprouted.deposit(purse, 5);
231 expect(asynccall sprouted.queryBalance(), 0 + 5);
232 expect(asynccall purse.queryBalance(), 100 - 5);
233
234 asynccall sprouted.deposit(purse, 42);
235 expect(asynccall sprouted.queryBalance(), 0 + 5 + 42);
236 expect(asynccall purse.queryBalance(), 100 - 5 - 42);
237 }
238 }
239 */
240
241 /* And a version using futures and wrappers.
242
243 void run(port) {
244 Wrapper<MintMaker> mintMaker = spawnMintMaker();
245 Future<Mint> mint = mintMaker...createMint();
246 Future<Purse> purse = mint...createPurse(100);
247 expect(purse.queryBalance(), 100);
248
249 Future<Purse> sprouted = purse...sproutPurse();
250 expect(0, sprouted.queryBalance());
251
252 sprouted...deposit(purse, 5);
253 expect(sprouted.queryBalance(), 0 + 5);
254 expect(purse.queryBalance(), 100 - 5);
255
256 sprouted...deposit(purse, 42);
257 expect(sprouted.queryBalance(), 0 + 5 + 42);
258 expect(purse.queryBalance(), 100 - 5 - 42);
259 }
260 */
261 } 178 }
OLDNEW
« no previous file with comments | « tests/isolate/message_test.dart ('k') | tests/isolate/nested_spawn2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698