| 372 | Now suppose that scanning the area takes an inordinate amount of time and blocking until it completes is no longer practical. By using the "send-and-get-later" function, the results can be computed in a new thread and dereferenced later. |
| 373 | |
| 374 | {{{ |
| 375 | client.core=> (defn scan-area2 [quagent radius] |
| 376 | (send-and-get-later quagent :radar :now [radius] |
| 377 | {} |
| 378 | (fn [prev [_ item-type & pos]] |
| 379 | (merge-with concat prev {item-type (list (seq->doubles pos))})))) |
| 380 | #'client.core/scan-area2 |
| 381 | client.core=> (def items (scan-area2 :Bob 8000)) |
| 382 | #'client.core/items |
| 383 | client.core=> (type items) |
| 384 | clojure.core$future_call$reify__5508 |
| 385 | client.core=> (future-done? items) |
| 386 | true |
| 387 | client.core=> @items |
| 388 | {"quagent_item_gold" ([375.085327 56.309933 1.374918] [1019.278626 42.455196 0.505915] ... (output truncated) |
| 389 | client.core=> (pp) |
| 390 | {"quagent_item_gold" |
| 391 | ([375.085327 56.309933 1.374918] |
| 392 | [1019.278626 42.455196 0.505915] |
| 393 | [905.141357 8.130102 0.569713]), |
| 394 | "quagent_item_treasure" |
| 395 | ([572.16864 20.462269 0.901278] [697.711304 63.434952 0.739097]), |
| 396 | "info_player_deathmatch" |
| 397 | ([32.000244 -90.0 0.223811] [0.125 0.0 90.0]), |
| 398 | "player" ([611.700012 90.081947 0.0] [32.0 -90.0 0.0])} |
| 399 | nil |
| 400 | }}} |
| 401 | |
| 402 | (Note that if you try to dereference a future before it completes, it will block the current thread until it does.) |
| 403 | |
| 404 | Now let's suppose that every time the quagent reports finding an item, it should print out the distance that item. This can be accomplished with the "send-and-watch" function. |
| 405 | |
| 406 | {{{ |
| 407 | client.core=> (defn scan-area3 [quagent radius] (send-and-watch quagent :radar :now [radius] nil (fn [prev data] (rest data)) (fn [k r o n] (println "Item:" (first n) "Distance:" (second n))))) |
| 408 | #'client.core/scan-area3 |
| 409 | client.core=> (scan-area3 :Bob 8000) |
| 410 | :watcher311 |
| 411 | Item: player Distance: 611.700012 |
| 412 | Item: player Distance: 32.000000 |
| 413 | Item: info_player_deathmatch Distance: 32.000244 |
| 414 | Item: quagent_item_treasure Distance: 572.168640 |
| 415 | Item: quagent_item_gold Distance: 375.085327 |
| 416 | Item: quagent_item_gold Distance: 1019.278626 |
| 417 | Item: quagent_item_treasure Distance: 697.711304 |
| 418 | Item: quagent_item_gold Distance: 905.141357 |
| 419 | Item: info_player_deathmatch Distance: 0.125000 |
| 420 | }}} |
| 421 | |
| 422 | This function returns a watcher key that can be used to remove the watcher if desired. Note that this example only makes used the (n)ew argument. |