Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/eXene/examples/bounce/ball.sml
ViewVC logotype

Annotation of /sml/trunk/src/eXene/examples/bounce/ball.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (view) (download)

1 : monnier 2 (* ball.sml
2 :     *
3 :     * COPYRIGHT (c) 1990,1991 by John H. Reppy. See COPYRIGHT file for details.
4 :     *)
5 :    
6 :     structure Ball =
7 :     struct
8 :    
9 :     datatype ball_msg
10 :     = KILL of Geometry.point
11 :     | REDRAW of (int * Geometry.size)
12 :     | KILL_ALL
13 :    
14 :     val updatesPerSec = 10
15 :    
16 :     local
17 :     structure MChan = Multicast
18 :     open Geometry BounceDM
19 :    
20 :     (* clip a point to keep a ball in the window. If we hit a wall, then
21 :     * we adjust the vector. The clipped point should be computed
22 :     * to lie on the vector, but for now we assume small vectors
23 :     * and just truncate the coordinates. *)
24 :     fun clip (ballRadius, SIZE{wid, ht}) = let
25 :     val maxX = wid - ballRadius and maxY = ht - ballRadius
26 :     fun clipCoord (coord : int, delta, minCoord, maxCoord) =
27 :     if (coord <= minCoord)
28 :     then (minCoord, ~delta)
29 :     else if (coord >= maxCoord)
30 :     then (maxCoord, ~delta)
31 :     else (coord, delta)
32 :     fun clip' (PT{x=x0, y=y0}, PT{x=dx0, y=dy0}) = let
33 :     val (x1, dx1) = clipCoord(x0+dx0, dx0, ballRadius, maxX)
34 :     val (y1, dy1) = clipCoord(y0+dy0, dy0, ballRadius, maxY)
35 :     in
36 :     (PT{x=x1, y=y1}, PT{x=dx1, y=dy1})
37 :     end
38 :     in
39 :     clip'
40 :     end
41 :    
42 :     fun mkIconFn win = let
43 :     val ballIcons =
44 :     map (EXeneBase.createTileFromImage (EXeneWin.screenOfWin win))
45 :     Heads.headDataList
46 :     val n = List.length ballIcons
47 :     val ch = CML.channel()
48 :     fun loop i = if (i = n)
49 :     then loop 0
50 :     else (CML.send(ch, List.nth(ballIcons, i)); loop(i+1))
51 :     in
52 :     XDebug.xspawn("newIcon", fn () => loop 0);
53 :     (fn () => CML.recv ch)
54 :     end
55 :    
56 :     val delayEvt =
57 :     CML.timeOutEvt(Time.fromMicroseconds(1000000 div updatesPerSec))
58 :     in
59 :    
60 :     fun mkBallFn (win, mchan, drawCh) = let
61 :     val newIcon = mkIconFn win
62 :     fun newBall (seqn, pos, vec, sz) = let
63 :     val ballIcon = newIcon()
64 :     val ballRadius = let
65 :     val {sz=SIZE{wid, ...}, ...} = EXeneBase.geomOfTile ballIcon
66 :     in
67 :     wid div 2
68 :     end
69 :     val offset = PT{x=ballRadius, y=ballRadius}
70 :     fun drawBall (n, pos) =
71 :     CML.send(drawCh, DrawBall(n, ballIcon, subPt(pos, offset)))
72 :     fun moveBall (n, oldPos, newPos) = (
73 :     drawBall(n, oldPos); drawBall(n, newPos))
74 :     val clipFn = clip (ballRadius, sz)
75 :     fun ball (inEvt, pos, vec, clipFn) = let
76 :     fun loop (seqn, pos, vec, clipFn) = CML.select [
77 :     CML.wrap(delayEvt, fn () => let
78 :     val (newPos, newVec) = clipFn(pos, vec)
79 :     in
80 :     if (pos <> newPos)
81 :     then moveBall(seqn, pos, newPos)
82 :     else ();
83 :     loop(seqn, newPos, newVec, clipFn)
84 :     end),
85 :     CML.wrap(inEvt,
86 :     fn (KILL(PT{x, y})) => let
87 :     val deathZone = RECT{
88 :     x = x-ballRadius, y = y-ballRadius,
89 :     wid = 2*ballRadius, ht = 2*ballRadius}
90 :     in
91 :     if within(pos, deathZone)
92 :     then drawBall(seqn, pos)
93 :     else loop(seqn, pos, vec, clipFn)
94 :     end
95 :     | (REDRAW(seqn', newSz)) => let
96 :     val clipFn = clip (ballRadius, newSz)
97 :     val (newPos, _) = clipFn(pos, PT{x=0, y=0})
98 :     in
99 :     drawBall(seqn', pos);
100 :     loop (seqn', newPos, vec, clipFn)
101 :     end
102 :     | KILL_ALL => drawBall(seqn, pos))
103 :     ]
104 :     in
105 :     drawBall (seqn, pos);
106 :     loop (seqn, pos, vec, clipFn)
107 :     end
108 :     in
109 :     XDebug.xspawn (
110 :     "Ball",
111 :     fn () =>
112 :     ball(MChan.recvEvt(MChan.port mchan), pos, vec, clipFn));
113 :     ()
114 :     end
115 :     in
116 :     newBall
117 :     end
118 :    
119 :     end (* local *)
120 :     end (* Ball *)

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0