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