1
2 #include <math.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #include <Message.h>
7 #include <MessageQueue.h>
8 #include <MessageRunner.h>
9 #include <Messenger.h>
10 #include <Rect.h>
11 #include <String.h>
12
13 #include "WindowLayer.h"
14
15 #include "ClientLooper.h"
16
17 #define SLOW_DRAWING 0
18
19 #define SPEED 2.0
20
21 // random_number_between
22 static float
random_number_between(float v1,float v2)23 random_number_between(float v1, float v2)
24 {
25 if (v1 < v2)
26 return v1 + fmod(rand() / 1000.0, (v2 - v1));
27 else if (v2 < v1)
28 return v2 + fmod(rand() / 1000.0, (v1 - v2));
29 return v1;
30 }
31
32 // init_polygon
33 static void
init_polygon(const BRect & b,point * polygon)34 init_polygon(const BRect& b, point* polygon)
35 {
36 polygon[0].x = b.left;
37 polygon[0].y = b.top;
38 polygon[0].direction_x = random_number_between(-SPEED, SPEED);
39 polygon[0].direction_y = random_number_between(-SPEED, SPEED);
40 polygon[1].x = b.right;
41 polygon[1].y = b.top;
42 polygon[1].direction_x = random_number_between(-SPEED, SPEED);
43 polygon[1].direction_y = random_number_between(-SPEED, SPEED);
44 polygon[2].x = b.right;
45 polygon[2].y = b.bottom;
46 polygon[2].direction_x = random_number_between(-SPEED, SPEED);
47 polygon[2].direction_y = random_number_between(-SPEED, SPEED);
48 polygon[3].x = b.left;
49 polygon[3].y = b.bottom;
50 polygon[3].direction_x = random_number_between(-SPEED, SPEED);
51 polygon[3].direction_y = random_number_between(-SPEED, SPEED);
52 }
53
54 // morph
55 static inline void
morph(double * value,double * direction,double min,double max)56 morph(double* value, double* direction, double min, double max)
57 {
58 *value += *direction;
59 if (*value < min) {
60 *value = min;
61 *direction = -*direction;
62 } else if (*value > max) {
63 *value = max;
64 *direction = -*direction;
65 }
66 }
67
68 // morph_polygon
69 static inline void
morph_polygon(const BRect & b,point * polygon)70 morph_polygon(const BRect& b, point* polygon)
71 {
72 morph(&polygon[0].x, &polygon[0].direction_x, b.left, b.right);
73 morph(&polygon[1].x, &polygon[1].direction_x, b.left, b.right);
74 morph(&polygon[2].x, &polygon[2].direction_x, b.left, b.right);
75 morph(&polygon[3].x, &polygon[3].direction_x, b.left, b.right);
76 morph(&polygon[0].y, &polygon[0].direction_y, b.top, b.bottom);
77 morph(&polygon[1].y, &polygon[1].direction_y, b.top, b.bottom);
78 morph(&polygon[2].y, &polygon[2].direction_y, b.top, b.bottom);
79 morph(&polygon[3].y, &polygon[3].direction_y, b.top, b.bottom);
80 }
81
82
83
84 // constructor
ClientLooper(const char * name,WindowLayer * serverWindow)85 ClientLooper::ClientLooper(const char* name, WindowLayer* serverWindow)
86 : BLooper("", B_DISPLAY_PRIORITY),
87 fServerWindow(serverWindow),
88 fViewCount(0)
89 {
90 BString clientName(name);
91 clientName << " client";
92 SetName(clientName.String());
93
94 BMessenger messenger(this);
95 fTicker = new BMessageRunner(messenger, new BMessage(MSG_TICK), 40000);
96
97 init_polygon(BRect(0, 0, 100, 100), fPolygon);
98 }
99
100 // destructor
~ClientLooper()101 ClientLooper::~ClientLooper()
102 {
103 delete fTicker;
104 }
105
106 // MessageReceived
107 void
MessageReceived(BMessage * message)108 ClientLooper::MessageReceived(BMessage* message)
109 {
110 switch (message->what) {
111 case MSG_UPDATE:
112
113 fServerWindow->PostMessage(MSG_BEGIN_UPDATE);
114
115 for (int32 i = 0; i < fViewCount; i++) {
116 // the client is slow
117 // snooze(40000L);
118 // send the command to redraw a view
119 if (i == 5) {
120 _DrawAnimatedLayer(i);
121 } else {
122 BMessage command(MSG_DRAWING_COMMAND);
123 command.AddInt32("token", i);
124 fServerWindow->PostMessage(&command);
125 }
126 }
127
128 fServerWindow->PostMessage(MSG_END_UPDATE);
129
130 break;
131 case MSG_VIEWS_ADDED: {
132 int32 count;
133 if (message->FindInt32("count", &count) >= B_OK) {
134 fViewCount += count;
135 }
136 break;
137 }
138 case MSG_VIEWS_REMOVED: {
139 int32 count;
140 if (message->FindInt32("count", &count) >= B_OK)
141 fViewCount -= count;
142 break;
143 }
144
145 case MSG_WINDOW_HIDDEN:
146 // there is no way we're going to accept this
147 // discrimination for longer than 2 seconds!
148 snooze(2000000);
149 fServerWindow->PostMessage(MSG_SHOW);
150 break;
151
152 case MSG_TICK: {
153 BMessage invalidate(MSG_INVALIDATE_VIEW);
154 invalidate.AddInt32("token", 5);
155 fServerWindow->PostMessage(&invalidate);
156
157 morph_polygon(BRect(0, 0, 100, 100), fPolygon);
158 break;
159 }
160
161 default:
162 BLooper::MessageReceived(message);
163 break;
164 }
165 }
166
167 // _DrawAnimatedLayer
168 void
_DrawAnimatedLayer(int32 token)169 ClientLooper::_DrawAnimatedLayer(int32 token)
170 {
171 BMessage message(MSG_DRAW_POLYGON);
172 message.AddInt32("token", token);
173
174 message.AddPoint("point", BPoint(fPolygon[0].x, fPolygon[0].y));
175 message.AddPoint("point", BPoint(fPolygon[1].x, fPolygon[1].y));
176 message.AddPoint("point", BPoint(fPolygon[2].x, fPolygon[2].y));
177 message.AddPoint("point", BPoint(fPolygon[3].x, fPolygon[3].y));
178
179 fServerWindow->PostMessage(&message);
180 }
181
182