| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 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"); | |
| 9 #import("dart:isolate"); | |
| 10 #import('../../../lib/unittest/unittest.dart'); | |
| 11 | |
| 12 class Mint { | |
| 13 Mint() : registry_ = new Map<SendPort, Purse>() { | |
| 14 // AUTO START | |
| 15 ReceivePort mintPort = new ReceivePort(); | |
| 16 port = mintPort.toSendPort(); | |
| 17 serveMint(mintPort); | |
| 18 // AUTO END | |
| 19 } | |
| 20 | |
| 21 // AUTO START | |
| 22 void serveMint(ReceivePort port) { | |
| 23 port.receive((var message, SendPort replyTo) { | |
| 24 int balance = message; | |
| 25 Purse purse = createPurse(balance); | |
| 26 replyTo.send([ purse.port ], null); | |
| 27 }); | |
| 28 } | |
| 29 // AUTO END | |
| 30 | |
| 31 Purse createPurse(int balance) { | |
| 32 Purse purse = new Purse(this, balance); | |
| 33 registry_[purse.port] = purse; | |
| 34 return purse; | |
| 35 } | |
| 36 | |
| 37 Purse lookupPurse(SendPort port) { | |
| 38 return registry_[port]; | |
| 39 } | |
| 40 | |
| 41 Map<SendPort, Purse> registry_; | |
| 42 // AUTO | |
| 43 SendPort port; | |
| 44 } | |
| 45 | |
| 46 | |
| 47 // AUTO START | |
| 48 class MintWrapper { | |
| 49 MintWrapper(SendPort this.mint_) {} | |
| 50 | |
| 51 void createPurse(int balance, handlePurse(PurseWrapper purse)) { | |
| 52 mint_.call(balance).then((var message) { | |
| 53 SendPort purse = message[0]; | |
| 54 handlePurse(new PurseWrapper(purse)); | |
| 55 }); | |
| 56 } | |
| 57 | |
| 58 SendPort mint_; | |
| 59 } | |
| 60 // AUTO END | |
| 61 | |
| 62 | |
| 63 /* | |
| 64 One way this could look without the autogenerated code: | |
| 65 | |
| 66 class Mint { | |
| 67 Mint() : registry_ = new Map<SendPort, Purse>() { | |
| 68 } | |
| 69 | |
| 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) { | |
| 99 recipient.receive((var message, SendPort replyTo) { | |
| 100 String command = message[0]; | |
| 101 if (command == "balance") { | |
| 102 replyTo.send(queryBalance(), null); | |
| 103 } else if (command == "deposit") { | |
| 104 Purse source = mint.lookupPurse(message[2]); | |
| 105 deposit(message[1], source); | |
| 106 } else if (command == "sprout") { | |
| 107 Purse result = sproutPurse(); | |
| 108 replyTo.send([ result.port ], null); | |
| 109 } else { | |
| 110 // TODO: Send an exception back. | |
| 111 replyTo.send("Exception: Command not understood", null); | |
| 112 } | |
| 113 }); | |
| 114 } | |
| 115 // AUTO END | |
| 116 | |
| 117 int queryBalance() { return balance; } | |
| 118 | |
| 119 Purse sproutPurse() { return mint.createPurse(0); } | |
| 120 | |
| 121 void deposit(int amount, Purse source) { | |
| 122 // TODO: Throw an exception if the source purse doesn't hold | |
| 123 // enough dough. | |
| 124 balance += amount; | |
| 125 source.balance -= amount; | |
| 126 } | |
| 127 | |
| 128 Mint mint; | |
| 129 int balance; | |
| 130 // AUTO | |
| 131 SendPort port; | |
| 132 } | |
| 133 | |
| 134 | |
| 135 // AUTO START | |
| 136 class PurseWrapper { | |
| 137 PurseWrapper(SendPort this.purse_) {} | |
| 138 | |
| 139 void queryBalance(handleBalance(int balance)) { | |
| 140 purse_.call([ "balance" ]).then((var message) { | |
| 141 int balance = message; | |
| 142 handleBalance(balance); | |
| 143 }); | |
| 144 } | |
| 145 | |
| 146 void sproutPurse(handleSprouted(PurseWrapper sprouted)) { | |
| 147 purse_.call([ "sprout" ]).then((var message) { | |
| 148 SendPort sprouted = message[0]; | |
| 149 handleSprouted(new PurseWrapper(sprouted)); | |
| 150 }); | |
| 151 } | |
| 152 | |
| 153 void deposit(PurseWrapper source, int amount) { | |
| 154 purse_.send([ "deposit", amount, source.purse_ ], null); | |
| 155 } | |
| 156 | |
| 157 | |
| 158 SendPort purse_; | |
| 159 } | |
| 160 // AUTO END | |
| 161 | |
| 162 | |
| 163 // AUTO STATUS UNCLEAR! | |
| 164 | |
| 165 class MintMakerWrapperIsolate extends Isolate { | |
| 166 MintMakerWrapperIsolate() : super() { } | |
| 167 void main() { | |
| 168 this.port.receive((var message, SendPort replyTo) { | |
| 169 Mint mint = new Mint(); | |
| 170 replyTo.send([ mint.port ], null); | |
| 171 }); | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 class MintMakerWrapper { | |
| 176 MintMakerWrapper() { | |
| 177 port_ = new MintMakerWrapperIsolate().spawn(); | |
| 178 } | |
| 179 | |
| 180 void makeMint(handleMint(MintWrapper mint)) { | |
| 181 port_.then((SendPort port) { | |
| 182 port.call(null).then((var message) { | |
| 183 SendPort mint = message[0]; | |
| 184 handleMint(new MintWrapper(mint)); | |
| 185 }); | |
| 186 }); | |
| 187 } | |
| 188 | |
| 189 Future<SendPort> port_; | |
| 190 } | |
| 191 | |
| 192 _checkBalance(PurseWrapper wrapper, expected) { | |
| 193 wrapper.queryBalance(expectAsync1((int balance) { | |
| 194 expect(balance).equals(expected); | |
| 195 })); | |
| 196 } | |
| 197 | |
| 198 main() { | |
| 199 test("creating purse, deposit, and query balance", () { | |
| 200 MintMakerWrapper mintMaker = new MintMakerWrapper(); | |
| 201 mintMaker.makeMint(expectAsync1((MintWrapper mint) { | |
| 202 mint.createPurse(100, expectAsync1((PurseWrapper purse) { | |
| 203 _checkBalance(purse, 100); | |
| 204 purse.sproutPurse(expectAsync1((PurseWrapper sprouted) { | |
| 205 _checkBalance(sprouted, 0); | |
| 206 _checkBalance(purse, 100); | |
| 207 | |
| 208 sprouted.deposit(purse, 5); | |
| 209 _checkBalance(sprouted, 0 + 5); | |
| 210 _checkBalance(purse, 100 - 5); | |
| 211 | |
| 212 sprouted.deposit(purse, 42); | |
| 213 _checkBalance(sprouted, 0 + 5 + 42); | |
| 214 _checkBalance(purse, 100 - 5 - 42); | |
| 215 })); | |
| 216 })); | |
| 217 })); | |
| 218 }); | |
| 219 | |
| 220 /* This is an attempt to show how the above code could look like if we had | |
| 221 * better language support for asynchronous messages (deferred/asynccall). | |
| 222 * The static helper methods like createPurse and queryBalance would also | |
| 223 * have to be marked async. | |
| 224 | |
| 225 void run(port) { | |
| 226 MintMakerWrapper mintMaker = spawnMintMaker(); | |
| 227 deferred { | |
| 228 MintWrapper mint = asynccall mintMaker.createMint(); | |
| 229 PurseWrapper purse = asynccall mint.createPurse(100); | |
| 230 Expect.equals(100, asynccall purse.queryBalance()); | |
| 231 | |
| 232 PurseWrapper sprouted = asynccall purse.sproutPurse(); | |
| 233 Expect.equals(0, asynccall sprouted.queryBalance()); | |
| 234 | |
| 235 asynccall sprouted.deposit(purse, 5); | |
| 236 Expect.equals(0 + 5, asynccall sprouted.queryBalance()); | |
| 237 Expect.equals(100 - 5, asynccall purse.queryBalance()); | |
| 238 | |
| 239 asynccall sprouted.deposit(purse, 42); | |
| 240 Expect.equals(0 + 5 + 42, asynccall sprouted.queryBalance()); | |
| 241 Expect.equals(100 - 5 - 42, asynccall purse.queryBalance()); | |
| 242 } | |
| 243 } | |
| 244 */ | |
| 245 | |
| 246 /* And a version using futures and wrappers. | |
| 247 | |
| 248 void run(port) { | |
| 249 Wrapper<MintMaker> mintMaker = spawnMintMaker(); | |
| 250 Future<Mint> mint = mintMaker...createMint(); | |
| 251 Future<Purse> purse = mint...createPurse(100); | |
| 252 Expect.equals(100, purse.queryBalance()); | |
| 253 | |
| 254 Future<Purse> sprouted = purse...sproutPurse(); | |
| 255 Expect.equals(0, sprouted.queryBalance()); | |
| 256 | |
| 257 sprouted...deposit(purse, 5); | |
| 258 Expect.equals(0 + 5, sprouted.queryBalance()); | |
| 259 Expect.equals(100 - 5, purse.queryBalance()); | |
| 260 | |
| 261 sprouted...deposit(purse, 42); | |
| 262 Expect.equals(0 + 5 + 42, sprouted.queryBalance()); | |
| 263 Expect.equals(100 - 5 - 42, purse.queryBalance()); | |
| 264 } | |
| 265 */ | |
| 266 } | |
| OLD | NEW |