xref: /haiku/src/tests/servers/app/newerClipping/ClientLooper.cpp (revision 83b1a68c52ba3e0e8796282759f694b7fdddf06d)
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
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
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
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
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
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
101 ClientLooper::~ClientLooper()
102 {
103 	delete fTicker;
104 }
105 
106 // MessageReceived
107 void
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
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