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 22static float 23random_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 33static void 34init_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 55static inline void 56morph(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 69static inline void 70morph_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 85ClientLooper::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 101ClientLooper::~ClientLooper() 102{ 103 delete fTicker; 104} 105 106// MessageReceived 107void 108ClientLooper::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 168void 169ClientLooper::_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