From 0b4a67fc216b1d20547e8b1ca79ea266736d965c Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 12 Jan 2009 22:10:39 +0000 Subject: [PATCH] svn: r13076 --- .../2htdp/scribblings/universe.scrbl | 130 +++++++--- collects/teachpack/balls.ss | 59 +++++ collects/teachpack/door.ss | 59 +++++ collects/teachpack/nuworld.ss | 119 +++++++++ collects/teachpack/server.ss | 228 ++++++++++++++++++ collects/teachpack/server2.png | Bin 17544 -> 0 bytes collects/teachpack/universe2.png | Bin 19411 -> 0 bytes collects/teachpack/world.png | Bin 28263 -> 15606 bytes collects/teachpack/world.ss | 200 +++++++++++++++ 9 files changed, 758 insertions(+), 37 deletions(-) create mode 100644 collects/teachpack/balls.ss create mode 100644 collects/teachpack/door.ss create mode 100644 collects/teachpack/nuworld.ss create mode 100644 collects/teachpack/server.ss delete mode 100644 collects/teachpack/server2.png delete mode 100644 collects/teachpack/universe2.png create mode 100644 collects/teachpack/world.ss diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index d16ed79e53..3547e2a548 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -1146,7 +1146,7 @@ From the perspective of the @tech{universe}, the design of a protocol is about the design of data representations for tracking universe information in the server and the participating worlds and the design of a data representation for messages. As for the latter, we know that they must be - @tech{S-expression}s, but of course @tech{world} programs don't send all + @tech{S-expression}s, but usually @tech{world} programs don't send all kinds of @tech{S-expression}s. The data definitions for messages must therefore select a subset of suitable @tech{S-expression}s. As for the state of the server and the worlds, they must reflect how they currently @@ -1164,8 +1164,8 @@ server tracks, call it @tech{UniverseState};} to the universe;} @item{data definitions for the messages that are sent from the server to -the worlds and vice versa. Let's call them @deftech{MsgS2W} for messages -from the server to the worlds and @deftech{MsgW2S} for the other direction; +the worlds and vice versa. Let's call them @deftech{S2W} for messages +from the server to the worlds and @deftech{W2S} for the other direction; in the most general case you may need one pair per world.} ] @@ -1185,7 +1185,22 @@ The second step of a protocol design is to figure out which major state of the world. A good tool for writing down these agreements is an interaction diagram. -(interaction diagrams: tbd) + +@verbatim{ + + Server World1 World2 + | | | + | 'go | | + |<------------------| | + | 'go | | + |------------------------------------------>| + | | | + | | | +} + + Each vertical line is the life line of a @tech{world} program or the + @tech{server}. Each horizontal arrow denotes a message sent from one + @tech{universe} participant to another. The design of the protocol, especially the data definitions, have direct implications for the design of event handling functions. For example, in @@ -1196,19 +1211,20 @@ translates into the design of two functions with the following headers, @(begin #reader scribble/comment-reader (schemeblock -;; @tech{UniverseState} world? -> (make-bundle [Listof world?] @tech{UniverseState} [Listof mail?]) -;; create new @tech{UniverseState} when world w is joining the universe, -;; which is in state s; also send mails as needed +;; Bundle is +;; (make-bundle [Listof world?] UniverseState [Listof mail?]) + +;; [Listof world?] UniverseState world? -> Bundle +;; compute next list of worlds and new @tech{UniverseState} +;; when world w is joining the universe, which is in state s; (define (add-world s w) ...) -;; @tech{UniverseState} world? MsgW2U -> (make-bundle [Listof world?] @tech{UniverseState} [Listof mail?]) -;; create new @tech{UniverseState} when world w is sending message m -;; to universe in state s; also send mails as needed +;; [Listof world?] UniverseState world? W2U -> Bundle +;; compute next list of worlds and new @tech{UniverseState} +;; when world w is sending message m to universe in state s (define (process s p m) ...) )) -Note how both functions return a @emph{bundle}. - Finally, we must also decide how the messages affect the states of the worlds; which of their callback may send messages and when; and what to do with the messages a world receives. Because this step is difficult to @@ -1228,10 +1244,14 @@ As for the server's state, it must obviously keep track of all @tech{world}s tha are passive. Of course, initially the @tech{universe} is empty, i.e., there are no @tech{world}s and, at that point, the server has nothing to track. -While there are many different useful ways of representing such a @tech{universe}, - we choose to introduce @tech{UniverseState} as a list of @tech{world}s, and we - interpret non-empty lists as those where the first @tech{world} is active and the - remainder are the passive @tech{world}s. As for the two possible events, +While there are many different useful ways of representing such a + @tech{universe}, we just use the list of @emph{worlds} that is handed to + each handler and that handlers return via their bundles. The + @tech{UniverseState} itself is useless for this trivial example. We + interpret non-empty lists as those where the first @tech{world} is active + and the remainder are the passive @tech{world}s. As for the two possible + events, + @itemize[ @item{it is natural to add new @tech{world}s to the end of the list; and} @@ -1263,6 +1283,34 @@ for this part of a @tech{world}'s state until we design its ``local'' behavior.} which it may ignore. When it is done with its turn, it will send a message. +@verbatim{ + Server + | World1 + |<==================| + | 'it-is-your-turn | + |------------------>| + | | World2 + |<==========================================| + | 'done | | + |<------------------| | + | 'it-is-your-turn | | + |------------------------------------------>| + | | | + | | | + | 'done | | + |<------------------------------------------| + | 'it-is-your-turn | | + |------------------>| | + | | | + | | | +} + +Here the double-lines (horizontal) denote the registration step, the others + are message exchanges. The diagram thus shows how the @tech{server} + decides to make the first registered world the active one and to enlist + all others as they join. + + @; ----------------------------------------------------------------------------- @subsection{Designing the Ball Server} @@ -1273,7 +1321,7 @@ The preceding subsection dictates that our server program starts like this: [schemeblock ;; teachpack: universe.ss -;; UniverseState is [Listof world?] +;; UniverseState is '* ;; StopMessage is 'done. ;; GoMessage is 'it-is-your-turn. ]) @@ -1289,24 +1337,22 @@ The preceding subsection dictates that our server program starts like this: #reader scribble/comment-reader [schemeblock ;; Result is -;; (make-bundle [Listof world?] UniverseState (list (make-mail world? GoMessage))) +;; (make-bundle [Listof world?] '* (list (make-mail world? GoMessage))) -;; UniverseState world? -> Result +;; [Listof world?] UniverseState world? -> Result ;; add world w to the universe, when server is in state u (define (add-world u w) ...) -;; UniverseState world? StopMessage -> Result +;; [Listof world?] UniverseState world? StopMessage -> Result ;; world w sent message m when server is in state u (define (switch u w m) ...) ]) Although we could have re-used the generic contracts from this documentation, we also know from our protocol that our server sends a -message to exactly one world. For this reason, both functions return the -same kind of result: a bundle that contains the new state of the server -(@tech{UniverseState}) and a list that contains a single mail. These contracts -are just refinements of the generic ones. (A type-oriented programmer would -say that the contracts here are subtypes of the generic ones.) +message to exactly one world. Note how these contracts are just refinements +of the generic ones. (A type-oriented programmer would say that the +contracts here are subtypes of the generic ones.) The second step of the design recipe calls for functional examples: @@ -1316,13 +1362,15 @@ The second step of the design recipe calls for functional examples: ;; an obvious example for adding a world: (check-expect (add-world '() '* world1) - (make-bundle (list world1) '* + (make-bundle (list world1) + '* (list (make-mail world1 'it-is-your-turn)))) ;; an example for receiving a message from the active world: (check-expect (switch (list world1 world2) '* world1 'it-is-your-turn) - (make-bundle (list world2 world1) '* + (make-bundle (list world2 world1) + '* (list (make-mail world2 'it-is-your-turn)))) ]) @@ -1335,23 +1383,24 @@ Exercise: Create additional examples for the two functions based on our protocol. The protocol tells us that @emph{add-world} just adds the given -@emph{world} structure---recall that this a data representation of the -actual @tech{world} program---to the @tech{UniverseState} and then sends a -message to the first world on this list to get things going: + @emph{world} structure---recall that this a data representation of the + actual @tech{world} program---to the given list of worlds. It then sends a + message to the first world on this list to get things going: @(begin #reader scribble/comment-reader [schemeblock -(define (add-world univ wrld) +(define (add-world univ state wrld) (local ((define univ* (append univ (list wrld)))) - (make-bundle univ* '* + (make-bundle univ* + '* (list (make-mail (first univ*) 'it-is-your-turn))))) ]) Because @emph{univ*} contains at least @emph{wrld}, it is acceptable to create a mail to @scheme[(first univ*)]. Of course, this same reasoning also implies that if @emph{univ} isn't empty, its first element is an -active world and has already received such a message. +active world and is about to receive a second @scheme['it-is-your-turn] message. Similarly, the protocol says that when @emph{switch} is invoked because a @tech{world} program sends a message, the data representation of the @@ -1361,15 +1410,16 @@ Similarly, the protocol says that when @emph{switch} is invoked because a @(begin #reader scribble/comment-reader [schemeblock -(define (switch univ wrld m) +(define (switch univ state wrld m) (local ((define univ* (append (rest univ) (list (first univ))))) - (make-bundle univ* '* + (make-bundle univ* + '* (list (make-mail (first univ*) 'it-is-your-turn))))) ]) As before, appending the first world to the end of the list guarantees - that there is at least this one world on the next @tech{UniverseState} - (state). It is therefore acceptable to create a mail for this world. + that there is at least this one world on this list. It is therefore + acceptable to create a mail for this world. Exercise: The function definition simply assumes that @emph{wrld} is @scheme[world=?] to @scheme[(first univ)] and that the received message @@ -1382,6 +1432,12 @@ Exercise: The function definition simply assumes that @emph{wrld} is depends on the context. For now, stop the @tech{universe} at this point, but consider alternative solutions, too.) +Exercise: An alternative state representation would equate + @tech{UniverseState} with @emph{world} structures, keeping track of the + active world. The list of world in the server would track the passive + worlds only. Design appropriate @scheme[add-world] and @scheme[switch] + functions. + @; ----------------------------------------------------------------------------- @subsection{Designing the Ball World} diff --git a/collects/teachpack/balls.ss b/collects/teachpack/balls.ss new file mode 100644 index 0000000000..a0e3bda180 --- /dev/null +++ b/collects/teachpack/balls.ss @@ -0,0 +1,59 @@ +;; The first three lines of this file were inserted by DrScheme. They record metadata +;; about the language level of this file in a form that our tools can easily process. +#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname balls) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) +(require (lib "world.ss" "htdp")) + +;; constants +(define height 50) +(define delta 80) +(define width (+ delta (* 2 height))) + +(define left (quotient height 2)) +(define right (+ height delta left)) + +;; World = (make-posn left Number) | (make-posn right Number) + +(define server (text "server" 11 'black)) +(define server* (overlay server (nw:rectangle (image-width server) (image-height server) 'outline 'black))) + +;; visual constants +(define bg + (place-image + (text "universe" 11 'green) + 60 0 + (place-image + server* + (+ height 15) 20 + (place-image + (text "left" 11 'blue) + 10 10 + (place-image + (text "right" 11 'red) + (+ height delta 10) 10 + (place-image + (nw:rectangle delta height 'solid 'white) + height 0 + (place-image + (nw:rectangle width height 'solid 'gray) + 0 0 + (empty-scene width height)))))))) + +(define ball (circle 3 'solid 'red)) + +;; World -> Scene +(define (draw w) + (place-image ball (posn-x w) (posn-y w) bg)) + + +;; World -> World +(define (tick w) + (local ((define y (posn-y w)) + (define x (posn-x w))) + (cond + [(> y 0) (make-posn x (- y 1))] + [(= x left) (make-posn right height)] + [(= x right) (make-posn left height)]))) + +(big-bang width height 1/66 (make-posn left height) true) +(on-redraw draw) +(on-tick-event tick) diff --git a/collects/teachpack/door.ss b/collects/teachpack/door.ss new file mode 100644 index 0000000000..6fd029e6a5 --- /dev/null +++ b/collects/teachpack/door.ss @@ -0,0 +1,59 @@ +#lang slideshow + +(require slideshow/pict) + +(define DELTA 40) +(define FT 12) + +; (fsa "unlock" "lock" "push" "tick") +(define (fsa L C O unlock lock push tick) + (define (make-state txt) + (define t (text txt '() FT)) + (define e (rounded-rectangle (+ 10 (pict-width t)) (+ 10 (pict-height t)))) + (cc-superimpose t e)) + + (define locked (make-state L)) + (define closed (make-state C)) + (define open (make-state O)) + + (define bg (rectangle (+ (pict-width locked) (* 2 DELTA)) + (+ (pict-height locked) + (pict-height closed) + (pict-height open) + (* 3 DELTA)))) + + (define width (pict-width bg)) + + (define (center base state y) + (define w (pict-width state)) + (define d (quotient (- width w) 2)) + (pin-over base d y state)) + + (define nx + (center + (center + (center + bg locked (/ DELTA 2)) + closed + (+ (/ DELTA 2) (pict-height locked) DELTA)) + open + (+ (/ DELTA 2) DELTA (pict-height locked) DELTA (pict-height closed)))) + + (define (add-labeled-arrow nx locked lb-find closed lt-find txt) + (define-values (x0 y0) (lb-find nx locked)) + (define-values (x1 y1) (lt-find nx closed)) + (define lbl (text txt '() (- FT 2))) + (define wlbl (pict-width lbl)) + (define hlbl (pict-height lbl)) + (define x (- x0 (/ wlbl 2))) + (define y (+ y0 (/ ( - y1 y0 hlbl) 2))) + (pin-over (pin-arrow-line 4.0 nx locked lb-find closed lt-find) x y lbl)) + + (define l1 (add-labeled-arrow nx locked lb-find closed lt-find unlock)) + (define l2 (add-labeled-arrow l1 closed lb-find open lt-find push)) + (define l3 (add-labeled-arrow l2 open rt-find closed rb-find tick)) + (define l4 (add-labeled-arrow l3 closed rt-find locked rb-find lock)) + l4) + +(fsa "locked" "closed" "open" "unlock" "lock" "push" "time") +(fsa "'locked" "'closed" "'open" "#\\u" "#\\l" "#\\space" "tick") \ No newline at end of file diff --git a/collects/teachpack/nuworld.ss b/collects/teachpack/nuworld.ss new file mode 100644 index 0000000000..cbda2823b6 --- /dev/null +++ b/collects/teachpack/nuworld.ss @@ -0,0 +1,119 @@ +#lang slideshow + +(require slideshow/pict mred/mred) + +(define DELTA 80) +(define FT 12) + +(define txt + '("(big-bang World_0" + " (on-draw render WIDTH HEIGHT)" + " (on-tick tock RATE)" + " (on-mouse click)" + " (on-key react))" + )) + +(define program + (apply vl-append (map (lambda (t) (text t '() (- FT 2))) txt))) + +(define Program + (cc-superimpose + (rectangle (+ 5 (pict-width program)) (+ 5 (pict-height program))) + program)) + +(define (make-state txt) + (define t (text txt '() FT)) + (define e (rounded-rectangle (+ 10 (pict-width t)) (+ DELTA (pict-height t)))) + (cc-superimpose t e)) + +(define False (text "FALSE" '() FT)) +(define True (text "TRUE" '() FT)) +(define BOOL (rectangle (+ 5 (pict-width False)) (+ 5 (pict-height False)))) + +;; String Boolean -> Pict +(define (make-state0 txt b) + ;; create the basic state + (define t (text txt '() FT)) + (define s (if b + (cc-superimpose + (rounded-rectangle (+ 5 (pict-width t)) (+ (- DELTA 5) (pict-height t))) + t) + t)) + (define w + (cc-superimpose + s + (rounded-rectangle (+ 10 (pict-width t)) (+ DELTA (pict-height t))))) + ;; add the boolean + (define bb (cc-superimpose (if b True False) BOOL)) + (define ar (add-labeled-arrow (vc-append DELTA bb w) w ct-find bb cb-find "done")) + (define scene (text "Scene" '() FT)) + (define sc (cc-superimpose scene (rectangle (+ 20 (pict-width scene)) (+ 30 (pict-height scene))))) + (define br (add-labeled-arrow (vc-append DELTA ar sc) ar cb-find sc ct-find "render")) + br) + +(define (add-labeled-arrow nx locked lb-find closed lt-find txt) + (define-values (x0 y0) (lb-find nx locked)) + (define-values (x1 y1) (lt-find nx closed)) + (define lbl (text txt '() (- FT 2))) + (define wlbl (pict-width lbl)) + (define hlbl (pict-height lbl)) + (define x (- x0 (/ wlbl 2))) + (define y (+ y0 (/ ( - y1 y0 hlbl) 2))) + (pin-over (pin-arrow-line 4.0 nx locked lb-find closed lt-find) x y lbl)) + +(define (h-labeled-arrow t) + (define tock (text t '() (- FT 2))) + (define blk (blank (+ DELTA 4) 2)) + (vc-append tock (pin-arrow-line 4.0 blk blk lc-find blk rc-find))) + +(define arrows + (vc-append (h-labeled-arrow "tock") + (h-labeled-arrow "click") + (h-labeled-arrow "react"))) + +(define state0 (make-state0 "World_0" #f)) +(define state1 (make-state0 "World_1" #f)) +(define dots (cc-superimpose (blank (pict-width state1) (pict-height state1)) (text "..." '() FT))) +(define state2 (make-state0 "World_N-1" #f)) +(define stateN (make-state0 "World_N" #t)) +(define states (list state0 arrows state1 arrows dots arrows state2 arrows stateN)) + +(define bg (blank (+ (apply + (map pict-width states)) + DELTA #;(* (length states) DELTA)) + (+ (pict-height state0) DELTA))) + +(define (center base state x) + (define w (pict-height state)) + (define d (quotient (- width w) 2)) + (pin-over base x d state)) + +(define width (pict-height bg)) + +(define x (* 1/2 DELTA)) +(define xx + (foldl (lambda (f ls s) + (define y (center s f x)) + (set! x (+ x ls)) + y) + bg + states + (map (lambda (x) (+ (pict-width x) #;(* 1/1 DELTA))) states))) + +(define the-image (ct-superimpose xx Program)) + +(define image-bm + (make-object bitmap% + (inexact->exact (round (pict-width the-image))) + (inexact->exact (round (pict-height the-image))))) + +(send image-bm ok?) + +(define image-dc + (new bitmap-dc% [bitmap image-bm])) +(send image-dc clear) + +(draw-pict the-image image-dc 0.0 0.0) + +(send image-bm save-file "world.png" 'png) + +the-image diff --git a/collects/teachpack/server.ss b/collects/teachpack/server.ss new file mode 100644 index 0000000000..b8d3d790e4 --- /dev/null +++ b/collects/teachpack/server.ss @@ -0,0 +1,228 @@ +#lang slideshow + +(require slideshow/pict) + +(define DELTA 80) +(define FT 12) + +(define prgm + '("(universe UniState_0" + " (on-new register)" + " (on-msg process)" + " (on-dis disconnect)" + " (on-tick tock)" + " (to-string render))")) + +(define program + (apply vl-append (map (lambda (t) (text t '() (- FT 2))) prgm))) + +(define Program + (cc-superimpose + (rectangle (+ 5 (pict-width program)) (+ 5 (pict-height program))) + program)) + +(define (make-state txt) + (define t (text txt '() FT)) + (define e (rounded-rectangle (+ 10 (pict-width t)) (+ DELTA (pict-height t)))) + (cc-superimpose t e)) + +(define False (text "FALSE" '() FT)) +(define True (text "TRUE" '() FT)) +(define BOOL (rectangle (+ 5 (pict-width False)) (+ 5 (pict-height False)))) + +;; String Boolean -> Pict +(define (make-state0 txt b) + ;; create the basic state + (define t (text txt '() FT)) + (define s (if b + (cc-superimpose + (rounded-rectangle (+ 5 (pict-width t)) (+ (- DELTA 5) (pict-height t))) + t) + t)) + (define w + (cc-superimpose + s + (rounded-rectangle (+ 10 (pict-width t)) (+ DELTA (pict-height t))))) + ;; add the boolean + (define bb (cc-superimpose (if b True False) BOOL)) + (define ar0 (add-labeled-arrow (vc-append DELTA bb w) w ct-find bb cb-find "done")) + ;; HIDE the arrow and done + (define ar (cb-superimpose w (blank (pict-width ar0) (pict-height ar0)))) + (define scene (text "string" '() FT)) + (define sc (cc-superimpose scene (rectangle (+ 20 (pict-width scene)) (+ 30 (pict-height scene))))) + (define br (add-labeled-arrow (vc-append DELTA ar sc) ar cb-find sc ct-find "render")) + br) + +(define (add-labeled-arrow nx locked lb-find closed lt-find txt) + (define-values (x0 y0) (lb-find nx locked)) + (define-values (x1 y1) (lt-find nx closed)) + (define lbl (text txt '() (- FT 2))) + (define wlbl (pict-width lbl)) + (define hlbl (pict-height lbl)) + (define x (- x0 (/ wlbl 2))) + (define y (+ y0 (/ ( - y1 y0 hlbl) 2))) + (pin-over (pin-arrow-line 4.0 nx locked lb-find closed lt-find) x y lbl)) + +(define (h-labeled-arrow t) + (define tock (text t '() (- FT 2))) + (define blk (blank (+ DELTA 4) 2)) + (vc-append tock (pin-arrow-line 4.0 blk blk lc-find blk rc-find))) + +(define message (text "Message" '() FT)) +(define (make-Message) + (cc-superimpose message (rectangle (+ 20 (pict-width message)) (+ 30 (pict-height message))))) + +(define Message (vc-append (make-Message) (arrowhead 4 (* 1/2 pi)))) +(define MessageK (vc-append (arrowhead 4 (* 3/2 pi)) (make-Message))) + +(define M (rb-superimpose Message (blank DELTA DELTA))) +(define K (rb-superimpose MessageK (blank DELTA DELTA))) + +(define (make-arrows M) + (define Tock (h-labeled-arrow "register")) + (define Click (h-labeled-arrow "tock")) + (define Clack (h-labeled-arrow "disconnect")) + (define Receive (h-labeled-arrow "process")) + (values Tock Click Clack Receive (vc-append (blank DELTA (/ DELTA 2)) Tock Click Clack Receive M))) + +(define-values (TockM ClickM ClackM ReceiveM arrowsR) (make-arrows M)) +(define-values (TockK ClickK ClackK ReceiveK arrowsL) (make-arrows K)) + +(define state0 (make-state0 "UniState_0" #f)) +(define state1 (make-state0 "UniState_1" #f)) +(define Server (hc-append (arrowhead 4 0) (cc-superimpose (cloud 160 80) (text "UNIVERSE" '() FT )))) +(define world (cc-superimpose (cloud 80 40) (text "world" '() FT ))) +(define dots (vc-append + (cc-superimpose (blank (pict-width state1) (pict-height state1)) (text "..." '() FT)) + world + Server)) +(define state2 (make-state0 "UniState_N-1" #f)) +(define stateN (make-state0 "UniState_N" #t)) +(define states (list state1 arrowsL dots arrowsR state2)) + +(define bg (blank (+ (apply + (map pict-width states)) DELTA) + (+ (pict-height state0) DELTA))) + +(define (center base state x) + (define w (pict-height state)) + (define d (quotient (- width w) 2)) + (pin-over base x d state)) + +(define width (pict-height bg)) + +(define x (* 1/2 DELTA)) +(define xx + (foldl (lambda (f ls s) + (define y (center s f x)) + (set! x (+ x ls)) + y) + bg + states + (map (lambda (x) (+ (pict-width x) #;(* 1/1 DELTA))) states))) + +(define zz xx) + +(require mred/mred) + +(define the-image + (ct-superimpose Program + (lt-superimpose + (dc (lambda (dc x y) + (define-values (mx my) (cb-find zz MessageK)) + (define-values (tx ty) (ct-find zz MessageK)) + (define-values (sx sy) (lc-find zz Server)) + (define-values (tockx tocky) (lb-find zz TockK)) + (define-values (clickx clicky) (lb-find zz ClickK)) + (define-values (clackx clacky) (lb-find zz ClackK)) + (define-values (rx ry) (lb-find zz ReceiveK)) + (define (add-curve rx ry) + (set! dcp (make-object dc-path%)) + (set! cx (max rx tx)) + (set! cy (min ry ty)) + (send dcp move-to tx ty) + (send dcp curve-to tx ty cx cy rx ry) + (send dc draw-path dcp)) + (define dcp (make-object dc-path%)) + ;; --- draw arc from Message to Server + (define cx (min sx mx)) + (define cy (max sy my)) + (send dc set-smoothing 'aligned) + (send dcp move-to mx my) + (send dcp curve-to mx my cx cy sx sy) + (send dc draw-path dcp) + ;; --- draw arc from Message to Receiver + (add-curve tockx tocky) + (add-curve clickx clicky) + (add-curve clackx clacky) + (add-curve rx ry) + ;; --- + dc) + (pict-width zz) (pict-height zz)) + (lt-superimpose + (lt-superimpose + zz + (dc (lambda (dc x y) + (define-values (mx my) (cb-find zz world)) + (define-values (tx ty) (ct-find zz world)) + (define-values (sx sy) (rc-find zz Server)) + (define-values (rx ry) (rb-find zz ReceiveM)) + (define dcp (make-object dc-path%)) + ;; --- draw arc from Message to Server + (define cx (max sx mx)) + (define cy (max sy my)) +#| + (send dc set-smoothing 'aligned) + (send dcp move-to mx my) + (send dcp curve-to mx my cx cy sx sy) + (send dc draw-path dcp) +|# + ;; --- draw arc from Message to Receiver + (set! dcp (make-object dc-path%)) + (set! cx (min rx tx)) + (set! cy (min ry ty)) + (send dcp move-to tx ty) + (send dcp curve-to tx ty cx cy rx ry) + (send dc draw-path dcp) + ;; --- + dc) + (pict-width zz) (pict-height zz))) + (dc (lambda (dc x y) + (define-values (mx my) (cb-find zz Message)) + (define-values (tx ty) (ct-find zz Message)) + (define-values (sx sy) (rc-find zz Server)) + (define-values (rx ry) (rb-find zz ReceiveM)) + (define dcp (make-object dc-path%)) + ;; --- draw arc from Message to Server + (define cx (max sx mx)) + (define cy (max sy my)) + (send dc set-smoothing 'aligned) + (send dcp move-to mx my) + (send dcp curve-to mx my cx cy sx sy) + (send dc draw-path dcp) + ;; --- draw arc from Message to Receiver + (set! dcp (make-object dc-path%)) + (set! cx (min rx tx)) + (set! cy (min ry ty)) + (send dcp move-to tx ty) + (send dcp curve-to tx ty cx cy rx ry) + (send dc draw-path dcp) + ;; --- + dc) + (pict-width zz) (pict-height zz)))))) + +(define image-bm + (make-object bitmap% + (inexact->exact (round (pict-width the-image))) + (inexact->exact (round (pict-height the-image))))) + +(send image-bm ok?) + +(define image-dc + (new bitmap-dc% [bitmap image-bm])) +(send image-dc clear) + +(draw-pict the-image image-dc 0.0 0.0) + +(send image-bm save-file "server.png" 'png) + +the-image diff --git a/collects/teachpack/server2.png b/collects/teachpack/server2.png deleted file mode 100644 index 99f02cea21628645569df1d6db48de7ce89b3774..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17544 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 KY?{pV`~L&xx4gap diff --git a/collects/teachpack/universe2.png b/collects/teachpack/universe2.png deleted file mode 100644 index 875756366493ec9ed26d02d3c36bae1d5742bbff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19411 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 diff --git a/collects/teachpack/world.png b/collects/teachpack/world.png index 81cb2ef2dbcd442e4f7a3ad083fdc2f934622372..2b215663af7eec24a24618fc866879ec02c4e92b 100644 GIT binary patch literal 15606 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 diff --git a/collects/teachpack/world.ss b/collects/teachpack/world.ss new file mode 100644 index 0000000000..f9c397e534 --- /dev/null +++ b/collects/teachpack/world.ss @@ -0,0 +1,200 @@ +#lang slideshow + +(require slideshow/pict) + +(define DELTA 80) +(define FT 12) + +(define prgm + '("(big-bang World_0" + " (on-draw render WIDTH HEIGHT)" + " (on-tick tock RATE)" + " (on-mouse click)" + " (on-key react)" + " (on-receive receive)" + " (register LOCALHOST 'jimbob))")) + + +(define program + (apply vl-append (map (lambda (t) (text t '() (- FT 2))) prgm))) + +(define Program + (cc-superimpose + (rectangle (+ 5 (pict-width program)) (+ 5 (pict-height program))) + program)) + +(define (make-state txt) + (define t (text txt '() FT)) + (define e (rounded-rectangle (+ 10 (pict-width t)) (+ DELTA (pict-height t)))) + (cc-superimpose t e)) + +(define False (text "FALSE" '() FT)) +(define True (text "TRUE" '() FT)) +(define BOOL (rectangle (+ 5 (pict-width False)) (+ 5 (pict-height False)))) + +;; String Boolean -> Pict +(define (make-state0 txt b) + ;; create the basic state + (define t (text txt '() FT)) + (define s (if b + (cc-superimpose + (rounded-rectangle (+ 5 (pict-width t)) (+ (- DELTA 5) (pict-height t))) + t) + t)) + (define w + (cc-superimpose + s + (rounded-rectangle (+ 10 (pict-width t)) (+ DELTA (pict-height t))))) + ;; add the boolean + (define bb (cc-superimpose (if b True False) BOOL)) + (define ar (add-labeled-arrow (vc-append DELTA bb w) w ct-find bb cb-find "done")) + (define scene (text "Scene" '() FT)) + (define sc (cc-superimpose scene (rectangle (+ 20 (pict-width scene)) (+ 30 (pict-height scene))))) + (define br (add-labeled-arrow (vc-append DELTA ar sc) ar cb-find sc ct-find "render")) + br) + +(define (add-labeled-arrow nx locked lb-find closed lt-find txt) + (define-values (x0 y0) (lb-find nx locked)) + (define-values (x1 y1) (lt-find nx closed)) + (define lbl (text txt '() (- FT 2))) + (define wlbl (pict-width lbl)) + (define hlbl (pict-height lbl)) + (define x (- x0 (/ wlbl 2))) + (define y (+ y0 (/ ( - y1 y0 hlbl) 2))) + (pin-over (pin-arrow-line 4.0 nx locked lb-find closed lt-find) x y lbl)) + +(define (h-labeled-arrow t) + (define tock (text t '() (- FT 2))) + (define blk (blank (+ DELTA 4) 2)) + (vc-append tock (pin-arrow-line 4.0 blk blk lc-find blk rc-find))) + +(define message (text "Message" '() FT)) +(define (make-Message) + (cc-superimpose message (rectangle (+ 20 (pict-width message)) (+ 30 (pict-height message))))) + +(define Message (vc-append (make-Message) (arrowhead 4 (* 1/2 pi)))) +(define MessageK (vc-append (arrowhead 4 (* 3/2 pi)) (make-Message))) + +(define M (rb-superimpose Message (blank DELTA DELTA))) +(define K (rb-superimpose MessageK (blank DELTA DELTA))) + +(define (make-arrows M) + (define Tock (h-labeled-arrow "tock")) + (define Click (h-labeled-arrow "click")) + (define Clack (h-labeled-arrow "react")) + (define Receive (h-labeled-arrow "receive")) + (values Tock Click Clack Receive (vc-append (blank DELTA (/ DELTA 2)) Tock Click Clack Receive M))) + +(define-values (TockM ClickM ClackM ReceiveM arrowsR) (make-arrows M)) +(define-values (TockK ClickK ClackK ReceiveK arrowsL) (make-arrows K)) + +(define state0 (make-state0 "World_0" #f)) +(define state1 (make-state0 "World_1" #f)) +(define Server (hc-append (arrowhead 4 0) (cc-superimpose (cloud 160 80) (text "SERVER" '() FT )))) +(define dots (vc-append + (cc-superimpose (blank (pict-width state1) (pict-height state1)) (text "..." '() FT)) + Server)) +(define state2 (make-state0 "World_N-1" #f)) +(define stateN (make-state0 "World_N" #t)) +(define states (list state1 arrowsL dots arrowsR state2)) + +(define bg (blank (+ (apply + (map pict-width states)) DELTA) + (+ (pict-height state0) DELTA))) + +(define (center base state x) + (define w (pict-height state)) + (define d (quotient (- width w) 2)) + (pin-over base x d state)) + +(define width (pict-height bg)) + +(define x (* 1/2 DELTA)) +(define xx + (foldl (lambda (f ls s) + (define y (center s f x)) + (set! x (+ x ls)) + y) + bg + states + (map (lambda (x) (+ (pict-width x) #;(* 1/1 DELTA))) states))) + +(define zz xx) + +(require mred/mred) + +(define the-image + (ct-superimpose Program + (lt-superimpose + (dc (lambda (dc x y) + (define-values (mx my) (cb-find zz MessageK)) + (define-values (tx ty) (ct-find zz MessageK)) + (define-values (sx sy) (lc-find zz Server)) + (define-values (tockx tocky) (lb-find zz TockK)) + (define-values (clickx clicky) (lb-find zz ClickK)) + (define-values (clackx clacky) (lb-find zz ClackK)) + (define-values (rx ry) (lb-find zz ReceiveK)) + (define (add-curve rx ry) + (set! dcp (make-object dc-path%)) + (set! cx (max rx tx)) + (set! cy (min ry ty)) + (send dcp move-to tx ty) + (send dcp curve-to tx ty cx cy rx ry) + (send dc draw-path dcp)) + (define dcp (make-object dc-path%)) + ;; --- draw arc from Message to Server + (define cx (min sx mx)) + (define cy (max sy my)) + (send dc set-smoothing 'aligned) + (send dcp move-to mx my) + (send dcp curve-to mx my cx cy sx sy) + (send dc draw-path dcp) + ;; --- draw arc from Message to Receiver + (add-curve tockx tocky) + (add-curve clickx clicky) + (add-curve clackx clacky) + (add-curve rx ry) + ;; --- + dc) + (pict-width zz) (pict-height zz)) + (lt-superimpose + zz + (dc (lambda (dc x y) + (define-values (mx my) (cb-find zz Message)) + (define-values (tx ty) (ct-find zz Message)) + (define-values (sx sy) (rc-find zz Server)) + (define-values (rx ry) (rb-find zz ReceiveM)) + (define dcp (make-object dc-path%)) + ;; --- draw arc from Message to Server + (define cx (max sx mx)) + (define cy (max sy my)) + (send dc set-smoothing 'aligned) + (send dcp move-to mx my) + (send dcp curve-to mx my cx cy sx sy) + (send dc draw-path dcp) + ;; --- draw arc from Message to Receiver + (set! dcp (make-object dc-path%)) + (set! cx (min rx tx)) + (set! cy (min ry ty)) + (send dcp move-to tx ty) + (send dcp curve-to tx ty cx cy rx ry) + (send dc draw-path dcp) + ;; --- + dc) + (pict-width zz) (pict-height zz)))))) + +(define image-bm + (make-object bitmap% + (inexact->exact (round (pict-width the-image))) + (inexact->exact (round (pict-height the-image))))) + +(send image-bm ok?) + +(define image-dc + (new bitmap-dc% [bitmap image-bm])) +(send image-dc clear) + +(draw-pict the-image image-dc 0.0 0.0) + +(send image-bm save-file "universe.png" 'png) + +the-image