| OLD | NEW |
| (Empty) | |
| 1 /* class = Purse (tests/stub-generator/src/MintMakerFullyIsolatedTest.dart/MintM
akerFullyIsolatedTest.dart: 10) */ |
| 2 |
| 3 interface Purse$Proxy { |
| 4 Promise<int> queryBalance(); |
| 5 |
| 6 Purse$Proxy sproutPurse(); |
| 7 |
| 8 Promise<int> deposit(int amount, Purse$Proxy source); |
| 9 } |
| 10 |
| 11 class Purse$ProxyImpl extends Proxy implements Purse$Proxy { |
| 12 Purse$ProxyImpl(Promise<SendPort> port) : super.forReply(port) { } |
| 13 Purse$ProxyImpl.forIsolate(Proxy isolate) : super.forReply(isolate.call([null]
)) { } |
| 14 factory Purse$ProxyImpl.createIsolate() { |
| 15 Proxy isolate = new Proxy.forIsolate(new Purse$Dispatcher$Isolate()); |
| 16 return new Purse$ProxyImpl.forIsolate(isolate); |
| 17 } |
| 18 factory Purse$ProxyImpl.localProxy(Purse obj) { |
| 19 return new Purse$ProxyImpl(new Promise<SendPort>.fromValue(Dispatcher.serve(
new Purse$Dispatcher(obj)))); |
| 20 } |
| 21 |
| 22 Promise<int> queryBalance() { |
| 23 return this.call(["queryBalance"]); |
| 24 } |
| 25 |
| 26 Purse$Proxy sproutPurse() { |
| 27 return new Purse$ProxyImpl(new PromiseProxy<SendPort>(this.call(["sproutPurs
e"]))); |
| 28 } |
| 29 |
| 30 Promise<int> deposit(int amount, Purse$Proxy source) { |
| 31 return new PromiseProxy<int>(this.call(["deposit", amount, source])); |
| 32 } |
| 33 } |
| 34 |
| 35 class Purse$Dispatcher extends Dispatcher<Purse> { |
| 36 Purse$Dispatcher(Purse thing) : super(thing) { } |
| 37 |
| 38 void process(var message, void reply(var response)) { |
| 39 String command = message[0]; |
| 40 if (command == "Purse") { |
| 41 } else if (command == "queryBalance") { |
| 42 int queryBalance = target.queryBalance(); |
| 43 reply(queryBalance); |
| 44 } else if (command == "sproutPurse") { |
| 45 Purse$Proxy sproutPurse = target.sproutPurse(); |
| 46 reply(sproutPurse); |
| 47 } else if (command == "deposit") { |
| 48 int amount = message[1]; |
| 49 List<Promise<SendPort>> promises = new List<Promise<SendPort>>(); |
| 50 promises.add(new PromiseProxy<SendPort>(new Promise<SendPort>.fromValue(me
ssage[2]))); |
| 51 Promise done = new Promise(); |
| 52 done.waitFor(promises, 1); |
| 53 done.addCompleteHandler((_) { |
| 54 Purse$Proxy source = new Purse$ProxyImpl(promises[0]); |
| 55 Promise<int> deposit = target.deposit(amount, source); |
| 56 reply(deposit); |
| 57 }); |
| 58 } else { |
| 59 // TODO(kasperl,benl): Somehow throw an exception instead. |
| 60 reply("Exception: command '" + command + "' not understood by Purse."); |
| 61 } |
| 62 } |
| 63 } |
| 64 |
| 65 class Purse$Dispatcher$Isolate extends Isolate { |
| 66 Purse$Dispatcher$Isolate() : super() { } |
| 67 |
| 68 void main() { |
| 69 this.port.receive(void _(var message, SendPort replyTo) { |
| 70 Purse thing = new Purse(); |
| 71 SendPort port = Dispatcher.serve(new Purse$Dispatcher(thing)); |
| 72 Proxy proxy = new Proxy.forPort(replyTo); |
| 73 proxy.send([port]); |
| 74 }); |
| 75 } |
| 76 } |
| 77 |
| 78 /* class = PowerfulPurse (tests/stub-generator/src/MintMakerFullyIsolatedTest.da
rt/MintMakerFullyIsolatedTest.dart: 19) */ |
| 79 |
| 80 interface PowerfulPurse$Proxy { |
| 81 void init(Mint$Proxy mint, int balance); |
| 82 |
| 83 Promise<int> grab(int amount); |
| 84 |
| 85 Purse$Proxy weak(); |
| 86 } |
| 87 |
| 88 class PowerfulPurse$ProxyImpl extends Proxy implements PowerfulPurse$Proxy { |
| 89 PowerfulPurse$ProxyImpl(Promise<SendPort> port) : super.forReply(port) { } |
| 90 PowerfulPurse$ProxyImpl.forIsolate(Proxy isolate) : super.forReply(isolate.cal
l([null])) { } |
| 91 factory PowerfulPurse$ProxyImpl.createIsolate() { |
| 92 Proxy isolate = new Proxy.forIsolate(new PowerfulPurse$Dispatcher$Isolate())
; |
| 93 return new PowerfulPurse$ProxyImpl.forIsolate(isolate); |
| 94 } |
| 95 factory PowerfulPurse$ProxyImpl.localProxy(PowerfulPurse obj) { |
| 96 return new PowerfulPurse$ProxyImpl(new Promise<SendPort>.fromValue(Dispatche
r.serve(new PowerfulPurse$Dispatcher(obj)))); |
| 97 } |
| 98 |
| 99 void init(Mint$Proxy mint, int balance) { |
| 100 this.send(["init", mint, balance]); |
| 101 } |
| 102 |
| 103 Promise<int> grab(int amount) { |
| 104 return this.call(["grab", amount]); |
| 105 } |
| 106 |
| 107 Purse$Proxy weak() { |
| 108 return new Purse$ProxyImpl(this.call(["weak"])); |
| 109 } |
| 110 } |
| 111 |
| 112 class PowerfulPurse$Dispatcher extends Dispatcher<PowerfulPurse> { |
| 113 PowerfulPurse$Dispatcher(PowerfulPurse thing) : super(thing) { } |
| 114 |
| 115 void process(var message, void reply(var response)) { |
| 116 String command = message[0]; |
| 117 if (command == "PowerfulPurse") { |
| 118 } else if (command == "init") { |
| 119 List<Promise<SendPort>> promises = new List<Promise<SendPort>>(); |
| 120 promises.add(new PromiseProxy<SendPort>(new Promise<SendPort>.fromValue(me
ssage[1]))); |
| 121 int balance = message[2]; |
| 122 Promise done = new Promise(); |
| 123 done.waitFor(promises, 1); |
| 124 done.addCompleteHandler((_) { |
| 125 Mint$Proxy mint = new Mint$ProxyImpl(promises[0]); |
| 126 target.init(mint, balance); |
| 127 }); |
| 128 } else if (command == "grab") { |
| 129 int amount = message[1]; |
| 130 int grab = target.grab(amount); |
| 131 reply(grab); |
| 132 } else if (command == "weak") { |
| 133 Purse weak = target.weak(); |
| 134 SendPort port = Dispatcher.serve(new Purse$Dispatcher(weak)); |
| 135 reply(port); |
| 136 } else { |
| 137 // TODO(kasperl,benl): Somehow throw an exception instead. |
| 138 reply("Exception: command '" + command + "' not understood by PowerfulPurs
e."); |
| 139 } |
| 140 } |
| 141 } |
| 142 |
| 143 class PowerfulPurse$Dispatcher$Isolate extends Isolate { |
| 144 PowerfulPurse$Dispatcher$Isolate() : super() { } |
| 145 |
| 146 void main() { |
| 147 this.port.receive(void _(var message, SendPort replyTo) { |
| 148 PowerfulPurse thing = new PowerfulPurse(); |
| 149 SendPort port = Dispatcher.serve(new PowerfulPurse$Dispatcher(thing)); |
| 150 Proxy proxy = new Proxy.forPort(replyTo); |
| 151 proxy.send([port]); |
| 152 }); |
| 153 } |
| 154 } |
| 155 |
| 156 /* class = Mint (tests/stub-generator/src/MintMakerFullyIsolatedTest.dart/MintMa
kerFullyIsolatedTest.dart: 29) */ |
| 157 |
| 158 interface Mint$Proxy { |
| 159 Purse$Proxy createPurse(int balance); |
| 160 |
| 161 PowerfulPurse$Proxy promote(Purse$Proxy purse); |
| 162 } |
| 163 |
| 164 class Mint$ProxyImpl extends Proxy implements Mint$Proxy { |
| 165 Mint$ProxyImpl(Promise<SendPort> port) : super.forReply(port) { } |
| 166 Mint$ProxyImpl.forIsolate(Proxy isolate) : super.forReply(isolate.call([null])
) { } |
| 167 factory Mint$ProxyImpl.createIsolate() { |
| 168 Proxy isolate = new Proxy.forIsolate(new Mint$Dispatcher$Isolate()); |
| 169 return new Mint$ProxyImpl.forIsolate(isolate); |
| 170 } |
| 171 factory Mint$ProxyImpl.localProxy(Mint obj) { |
| 172 return new Mint$ProxyImpl(new Promise<SendPort>.fromValue(Dispatcher.serve(n
ew Mint$Dispatcher(obj)))); |
| 173 } |
| 174 |
| 175 Purse$Proxy createPurse(int balance) { |
| 176 return new Purse$ProxyImpl(new PromiseProxy<SendPort>(this.call(["createPurs
e", balance]))); |
| 177 } |
| 178 |
| 179 PowerfulPurse$Proxy promote(Purse$Proxy purse) { |
| 180 return new PowerfulPurse$ProxyImpl(new PromiseProxy<SendPort>(this.call(["pr
omote", purse]))); |
| 181 } |
| 182 } |
| 183 |
| 184 class Mint$Dispatcher extends Dispatcher<Mint> { |
| 185 Mint$Dispatcher(Mint thing) : super(thing) { } |
| 186 |
| 187 void process(var message, void reply(var response)) { |
| 188 String command = message[0]; |
| 189 if (command == "Mint") { |
| 190 } else if (command == "createPurse") { |
| 191 int balance = message[1]; |
| 192 Purse$Proxy createPurse = target.createPurse(balance); |
| 193 reply(createPurse); |
| 194 } else if (command == "promote") { |
| 195 List<Promise<SendPort>> promises = new List<Promise<SendPort>>(); |
| 196 promises.add(new PromiseProxy<SendPort>(new Promise<SendPort>.fromValue(me
ssage[1]))); |
| 197 Promise done = new Promise(); |
| 198 done.waitFor(promises, 1); |
| 199 done.addCompleteHandler((_) { |
| 200 Purse$Proxy purse = new Purse$ProxyImpl(promises[0]); |
| 201 PowerfulPurse$Proxy promote = target.promote(purse); |
| 202 reply(promote); |
| 203 }); |
| 204 } else { |
| 205 // TODO(kasperl,benl): Somehow throw an exception instead. |
| 206 reply("Exception: command '" + command + "' not understood by Mint."); |
| 207 } |
| 208 } |
| 209 } |
| 210 |
| 211 class Mint$Dispatcher$Isolate extends Isolate { |
| 212 Mint$Dispatcher$Isolate() : super() { } |
| 213 |
| 214 void main() { |
| 215 this.port.receive(void _(var message, SendPort replyTo) { |
| 216 Mint thing = new Mint(); |
| 217 SendPort port = Dispatcher.serve(new Mint$Dispatcher(thing)); |
| 218 Proxy proxy = new Proxy.forPort(replyTo); |
| 219 proxy.send([port]); |
| 220 }); |
| 221 } |
| 222 } |
| 223 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 224 // for details. All rights reserved. Use of this source code is governed by a |
| 225 // BSD-style license that can be found in the LICENSE file. |
| 226 |
| 227 // IsolateStubs=MintMakerFullyIsolatedTest.dart:Mint,Purse,PowerfulPurse |
| 228 |
| 229 //#library("MintMakerFullyIsolatedTest"); |
| 230 //#import("../../isolate/src/TestFramework.dart"); |
| 231 |
| 232 interface Purse { |
| 233 Purse(); |
| 234 int queryBalance(); |
| 235 Purse$Proxy sproutPurse(); |
| 236 // The deposit has not completed until the promise completes. If we |
| 237 // supported Promise<void> then this could use that. |
| 238 Promise<int> deposit(int amount, Purse$Proxy source); |
| 239 } |
| 240 |
| 241 interface PowerfulPurse extends Purse factory PurseImpl { |
| 242 PowerfulPurse(); |
| 243 |
| 244 void init(Mint$Proxy mint, int balance); |
| 245 // Return an int so we can wait for it to complete. Shame we can't |
| 246 // have a Promise<void>. |
| 247 int grab(int amount); |
| 248 Purse weak(); |
| 249 } |
| 250 |
| 251 interface Mint factory MintImpl { |
| 252 Mint(); |
| 253 |
| 254 Purse$Proxy createPurse(int balance); |
| 255 PowerfulPurse$Proxy promote(Purse$Proxy purse); |
| 256 } |
| 257 |
| 258 // Because promises can't be used as keys in maps until they have |
| 259 // completed, provide a wrapper. Note that if any key promise fails to |
| 260 // resolve, then get()'s return may also fail to resolve. Also, |
| 261 // although the logic is fine, this can't be used for a |
| 262 // ProxyMap. Perhaps both Proxy and Promise should inherit from |
| 263 // Completable? |
| 264 // NB: not tested and known to be buggy. Will fix in a future change. |
| 265 class PromiseMap<S extends Promise, T> { |
| 266 |
| 267 PromiseMap() { |
| 268 _map = new Map<S, T>(); |
| 269 _incomplete = new Set<S>(); |
| 270 } |
| 271 |
| 272 T add(S s, T t) { |
| 273 _incomplete.add(s); |
| 274 s.addCompleteHandler((_) { |
| 275 _map[s] = t; |
| 276 _incomplete.remove(s); |
| 277 }); |
| 278 return t; |
| 279 } |
| 280 |
| 281 Promise<T> find(S s) { |
| 282 T t = _map[s]; |
| 283 if (t != null) |
| 284 return new Promise<T>.fromValue(t); |
| 285 Promise<T> p = new Promise<T>(); |
| 286 int counter = _incomplete.length; |
| 287 p.join(_incomplete, bool (S completed) { |
| 288 if (completed != s) { |
| 289 if (--counter == 0) { |
| 290 p.complete(null); |
| 291 return true; |
| 292 } |
| 293 return false; |
| 294 } |
| 295 p.complete(_map[s]); |
| 296 return true; |
| 297 }); |
| 298 return p; |
| 299 } |
| 300 |
| 301 Set<S> _incomplete; |
| 302 Map<S, T> _map; |
| 303 |
| 304 } |
| 305 |
| 306 class MintImpl implements Mint { |
| 307 |
| 308 MintImpl() { |
| 309 //print('mint'); |
| 310 if (_power == null) |
| 311 _power = new Map<Purse$Proxy, PowerfulPurse$Proxy>(); |
| 312 } |
| 313 |
| 314 Purse$Proxy createPurse(int balance) { |
| 315 //print('createPurse'); |
| 316 PowerfulPurse$ProxyImpl purse = |
| 317 new PowerfulPurse$ProxyImpl.createIsolate(); |
| 318 Mint$Proxy thisProxy = new Mint$ProxyImpl.localProxy(this); |
| 319 purse.init(thisProxy, balance); |
| 320 |
| 321 Purse$Proxy weakPurse = purse.weak(); |
| 322 weakPurse.addCompleteHandler(() { |
| 323 //print('cP1'); |
| 324 _power[weakPurse] = purse; |
| 325 //print('cP2'); |
| 326 }); |
| 327 return weakPurse; |
| 328 } |
| 329 |
| 330 PowerfulPurse$Proxy promote(Purse$Proxy purse) { |
| 331 // FIXME(benl): we should be using a PromiseMap here. But we get |
| 332 // away with it in this test for now. |
| 333 //print('promote $purse/${_power[purse]}'); |
| 334 return _power[purse]; |
| 335 } |
| 336 |
| 337 static Map<Purse$Proxy, PowerfulPurse$Proxy> _power; |
| 338 } |
| 339 |
| 340 class PurseImpl implements PowerfulPurse { |
| 341 |
| 342 // FIXME(benl): autogenerate constructor, get rid of init(...). |
| 343 // Note that this constructor should not exist in the public interface |
| 344 // PurseImpl(this._mint, this._balance) { } |
| 345 PurseImpl() { } |
| 346 |
| 347 init(Mint$Proxy mint, int balance) { |
| 348 this._mint = mint; |
| 349 this._balance = balance; |
| 350 } |
| 351 |
| 352 int queryBalance() { |
| 353 return _balance; |
| 354 } |
| 355 |
| 356 Purse$Proxy sproutPurse() { |
| 357 //print('sprout'); |
| 358 return _mint.createPurse(0); |
| 359 } |
| 360 |
| 361 Promise<int> deposit(int amount, Purse$Proxy proxy) { |
| 362 //print('deposit'); |
| 363 Promise<int> grabbed = _mint.promote(proxy).grab(amount); |
| 364 Promise<int> done = new Promise<int>(); |
| 365 grabbed.then((int) { |
| 366 //print("deposit done"); |
| 367 _balance += amount; |
| 368 done.complete(_balance); |
| 369 }); |
| 370 return done; |
| 371 } |
| 372 |
| 373 int grab(int amount) { |
| 374 //print("grab"); |
| 375 if (_balance < amount) throw "Not enough dough."; |
| 376 _balance -= amount; |
| 377 return amount; |
| 378 } |
| 379 |
| 380 Purse weak() { |
| 381 return this; |
| 382 } |
| 383 |
| 384 Mint$Proxy _mint; |
| 385 int _balance; |
| 386 |
| 387 } |
| 388 |
| 389 class MintMakerFullyIsolatedTest { |
| 390 |
| 391 static void testMain() { |
| 392 Mint$Proxy mint = new Mint$ProxyImpl.createIsolate(); |
| 393 Purse$Proxy purse = mint.createPurse(100); |
| 394 // FIXME(benl): how do I write this? |
| 395 //PowerfulPurse$Proxy power = (PowerfulPurse$Proxy)purse; |
| 396 //expectEqualsStr("xxx", power.grab()); |
| 397 expectEquals(100, purse.queryBalance()); |
| 398 |
| 399 Purse$Proxy sprouted = purse.sproutPurse(); |
| 400 expectEquals(0, sprouted.queryBalance()); |
| 401 |
| 402 Promise<int> done = sprouted.deposit(5, purse); |
| 403 // FIXME(benl): it should not be necessary to wait here, I think, |
| 404 // but without this, the tests seem to execute prematurely. |
| 405 expectEquals(5, done); |
| 406 done.then((int) { |
| 407 expectEquals(0 + 5, sprouted.queryBalance()); |
| 408 expectEquals(100 - 5, purse.queryBalance()); |
| 409 |
| 410 done = sprouted.deposit(42, purse); |
| 411 expectEquals(5 + 42, done); |
| 412 done.then((int) { |
| 413 expectEquals(0 + 5 + 42, sprouted.queryBalance()); |
| 414 expectEquals(100 - 5 - 42, purse.queryBalance()); |
| 415 |
| 416 expectDone(8); |
| 417 }); |
| 418 }); |
| 419 } |
| 420 |
| 421 static List<Promise> results; |
| 422 |
| 423 static void expectEqualsStr(String expected, Promise<String> promise) { |
| 424 if (results === null) { |
| 425 results = new List<Promise>(); |
| 426 } |
| 427 results.add(promise.then((String actual) { |
| 428 //print('done ' + expected + '/' + actual); |
| 429 Expect.equals(expected, actual); |
| 430 })); |
| 431 } |
| 432 |
| 433 static void expectEquals(int expected, Promise<int> promise) { |
| 434 if (results === null) { |
| 435 results = new List<Promise>(); |
| 436 } |
| 437 results.add(promise.then((int actual) { |
| 438 //print('done ' + expected + '/' + actual); |
| 439 Expect.equals(expected, actual); |
| 440 })); |
| 441 } |
| 442 |
| 443 static void expectDone(int n) { |
| 444 if (results === null) { |
| 445 Expect.equals(0, n); |
| 446 print('##DONE##'); |
| 447 } else { |
| 448 Promise done = new Promise(); |
| 449 done.waitFor(results, results.length); |
| 450 done.then((ignored) { |
| 451 //print('done all ' + n + '/' + results.length); |
| 452 Expect.equals(n, results.length); |
| 453 print('##DONE##'); |
| 454 }); |
| 455 } |
| 456 } |
| 457 |
| 458 } |
| 459 |
| 460 main() { |
| 461 MintMakerFullyIsolatedTest.testMain(); |
| 462 //runTests([MintMakerFullyIsolatedTest.testMain]); |
| 463 } |
| OLD | NEW |