Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / sun4-solaris / Tk / demos / widget_lib / Ball.pm
CommitLineData
86530b38
AT
1
2package Ball;
3
4# Ball.pm, a class module that allows concurrent simulation (canvas) instances.
5#
6# This is simply a class module, nothing fancy like a derived widget or
7# composite widget. It has two virtual methods, new() and move_one_ball().
8# There are two static methods, get_canvas_hash() and move_all_balls().
9#
10# Essentially, move_all_balls() is invoked to move all of the balls in a
11# simulation's @BALLS list once - from their current to their new postion.
12# After moving one ball a call to DoOneEvent() is made to handle pending
13# XEvents. The *user* of this module, in this case bounce.pl, has their
14# own main loop which also calls DoOneEvent() and move_all_balls() to keep
15# the simulation active.
16#
17# Gurusamy Sarathy (gsar@engin.umich.edu)
18# Tidied up by SOL.
19
20use vars qw/$VERSION/;
21$VERSION = '3.009'; # $Id: //depot/Tk8/demos/demos/widget_lib/Ball.pm#9 $
22
23use Tk::Canvas;
24use Tk::Widget;
25use Tk qw/DoOneEvent DONT_WAIT/;
26Construct Tk::Canvas 'Ball';
27use strict;
28
29# Class Ball global variables.
30
31my %BALLS = (); # hold @BALLS list on a per canvas basis
32my (%DEFAULTS) = ( # Ball constructor option defaults
33 -color => 'blue',
34 -size => 20.0,
35 -position => [12.0,12.0],
36 -velocity => [6.0, 9.0],
37 );
38
39sub new { # Ball object constructor
40
41 # Create a new Ball object, which just happens to be a Canvas item.
42 # Fill-in values for defaulted parameters, create the oval item, and
43 # store object-specific information in the ball's hash.
44 #
45 # Finally, update the class global %BALLS hash, indexed by a hashed canvas
46 # reference, with the new ball. Note the special Tk::bind statement that
47 # removes a canvas from the %BALLS hash when the canvas is destroyed, thus
48 # keeping %BALLS trimmed and preventing a very slow memory leak.
49
50 my($class, $canvas, %args) = @_;
51
52 my @missing_args = grep ! defined $args{$_}, keys %DEFAULTS;
53 @args{@missing_args} = @DEFAULTS{@missing_args};
54 my($color, $size, $pos, $vel) = @args{-color, -size, -position, -velocity};
55
56 my $ball = $canvas->create('oval',
57 ($pos->[0] - ($size/2.0)), ($pos->[1] - ($size/2.0)),
58 ($pos->[0] + ($size/2.0)), ($pos->[1] + ($size/2.0)),
59 -fill => $color,
60 );
61 $canvas->Tk::bind(
62 '<Destroy>' => sub {delete $BALLS{Ball->get_canvas_hash($canvas)}}
63 );
64
65 my $ball_obj = {'canvas_ID' => $ball,
66 'canvas' => $canvas,
67 'color' => $color,
68 'size' => $size,
69 'pos' => [@$pos],
70 'vel' => [@$vel],
71 };
72
73 push @{$BALLS{Ball->get_canvas_hash($canvas)}->{'BALLS'}}, $ball_obj;
74 return bless $ball_obj, $class;
75
76} # end new, Ball constructor
77
78sub get_canvas_hash {
79
80 # Hash a canvas reference to a key for indexing into the %BALLS hash.
81 # For now, just use the string-ified widget reference. If this trick
82 # were ever to fail in the future then only this code needs to be fixed
83 # and the Ball class would be up and running in short oder.
84
85 my($class, $canvas) = @_;
86
87 return $canvas
88
89} # end get_canvas_hash
90
91sub move_one_ball {
92
93 # Move one ball, belonging to one simulation, one clock tick.
94
95 my ($ball_obj, $speed_ratio) = @_;
96
97 my($ball, $canv, $minx, $miny, $maxx, $maxy);
98 my($ballx, $bally, $deltax, $deltay);
99
100 $speed_ratio = 1.0 unless defined $speed_ratio;
101 $ball = $ball_obj->{'canvas_ID'};
102 $canv = $ball_obj->{'canvas'};
103 $ballx = $ball_obj->{'pos'}[0];
104 $bally = $ball_obj->{'pos'}[1];
105
106 $minx = $ball_obj->{'size'} / 2.0;
107 $maxx = $ball_obj->{'canvas'}->cget(-width) - $minx;
108
109 $miny = $ball_obj->{'size'} / 2.0;
110 $maxy = $ball_obj->{'canvas'}->cget(-height) - $miny;
111
112 if ($ballx > $maxx || $ballx < $minx) {
113 $ball_obj->{'vel'}[0] = -1.0 * $ball_obj->{'vel'}[0];
114 }
115 if ($bally > $maxy || $bally < $miny) {
116 $ball_obj->{'vel'}[1] = -1.0 * $ball_obj->{'vel'}[1];
117 }
118
119 $deltax = $ball_obj->{'vel'}[0] * $speed_ratio;
120 $deltay = $ball_obj->{'vel'}[1] * $speed_ratio;
121
122 $canv->move($ball, $deltax, $deltay);
123 $ball_obj->{'pos'}[0] = $ballx + $deltax;
124 $ball_obj->{'pos'}[1] = $bally + $deltay;
125
126 return $ball_obj;
127
128} # end move_one_ball
129
130sub move_all_balls {
131
132 # Move all the balls belong to one simulation instance one clock tick.
133
134 my($class, $canvas, $speed_ratio) = @_;
135
136 foreach (@{$BALLS{Ball->get_canvas_hash($canvas)}->{'BALLS'}}) {
137 $_->move_one_ball($speed_ratio);
138 DoOneEvent(DONT_WAIT); # be kind and process XEvents if they arise
139 }
140
141} # end move_all_balls
142
1431;