root/src/tests/servers/app/newerClipping/ClientLooper.cpp

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include <Message.h>
#include <MessageQueue.h>
#include <MessageRunner.h>
#include <Messenger.h>
#include <Rect.h>
#include <String.h>

#include "WindowLayer.h"

#include "ClientLooper.h"

#define SLOW_DRAWING 0

#define SPEED 2.0

// random_number_between
static float
random_number_between(float v1, float v2)
{
        if (v1 < v2)
                return v1 + fmod(rand() / 1000.0, (v2 - v1));
        else if (v2 < v1)
                return v2 + fmod(rand() / 1000.0, (v1 - v2));
        return v1;
}

// init_polygon
static void
init_polygon(const BRect& b, point* polygon)
{
        polygon[0].x = b.left;
        polygon[0].y = b.top;
        polygon[0].direction_x = random_number_between(-SPEED, SPEED);
        polygon[0].direction_y = random_number_between(-SPEED, SPEED);
        polygon[1].x = b.right;
        polygon[1].y = b.top;
        polygon[1].direction_x = random_number_between(-SPEED, SPEED);
        polygon[1].direction_y = random_number_between(-SPEED, SPEED);
        polygon[2].x = b.right;
        polygon[2].y = b.bottom;
        polygon[2].direction_x = random_number_between(-SPEED, SPEED);
        polygon[2].direction_y = random_number_between(-SPEED, SPEED);
        polygon[3].x = b.left;
        polygon[3].y = b.bottom;
        polygon[3].direction_x = random_number_between(-SPEED, SPEED);
        polygon[3].direction_y = random_number_between(-SPEED, SPEED);
}

// morph
static inline void
morph(double* value, double* direction, double min, double max)
{
        *value += *direction;
        if (*value < min) {
                *value = min;
                *direction = -*direction;
        } else if (*value > max) {
                *value = max;
                *direction = -*direction;
        }
}

// morph_polygon
static inline void
morph_polygon(const BRect& b, point* polygon)
{
        morph(&polygon[0].x, &polygon[0].direction_x, b.left, b.right);
        morph(&polygon[1].x, &polygon[1].direction_x, b.left, b.right);
        morph(&polygon[2].x, &polygon[2].direction_x, b.left, b.right);
        morph(&polygon[3].x, &polygon[3].direction_x, b.left, b.right);
        morph(&polygon[0].y, &polygon[0].direction_y, b.top, b.bottom);
        morph(&polygon[1].y, &polygon[1].direction_y, b.top, b.bottom);
        morph(&polygon[2].y, &polygon[2].direction_y, b.top, b.bottom);
        morph(&polygon[3].y, &polygon[3].direction_y, b.top, b.bottom);
}



// constructor
ClientLooper::ClientLooper(const char* name, WindowLayer* serverWindow)
        : BLooper("", B_DISPLAY_PRIORITY),
          fServerWindow(serverWindow),
          fViewCount(0)
{
        BString clientName(name);
        clientName << " client";
        SetName(clientName.String());

        BMessenger messenger(this);
        fTicker = new BMessageRunner(messenger, new BMessage(MSG_TICK), 40000);

        init_polygon(BRect(0, 0, 100, 100), fPolygon);
}

// destructor
ClientLooper::~ClientLooper()
{
        delete fTicker;
}

// MessageReceived
void
ClientLooper::MessageReceived(BMessage* message)
{
        switch (message->what) {
                case MSG_UPDATE:

                        fServerWindow->PostMessage(MSG_BEGIN_UPDATE);

                        for (int32 i = 0; i < fViewCount; i++) {
                                // the client is slow
//                              snooze(40000L);
                                // send the command to redraw a view
                                if (i == 5) {
                                        _DrawAnimatedLayer(i);
                                } else {
                                        BMessage command(MSG_DRAWING_COMMAND);
                                        command.AddInt32("token", i);
                                        fServerWindow->PostMessage(&command);
                                }
                        }

                        fServerWindow->PostMessage(MSG_END_UPDATE);

                        break;
                case MSG_VIEWS_ADDED: {
                        int32 count;
                        if (message->FindInt32("count", &count) >= B_OK) {
                                fViewCount += count;
                        }
                        break;
                }
                case MSG_VIEWS_REMOVED: {
                        int32 count;
                        if (message->FindInt32("count", &count) >= B_OK)
                                fViewCount -= count;
                        break;
                }

                case MSG_WINDOW_HIDDEN:
                        // there is no way we're going to accept this
                        // discrimination for longer than 2 seconds!
                        snooze(2000000);
                        fServerWindow->PostMessage(MSG_SHOW);
                        break;

                case MSG_TICK: {
                        BMessage invalidate(MSG_INVALIDATE_VIEW);
                        invalidate.AddInt32("token", 5);
                        fServerWindow->PostMessage(&invalidate);

                        morph_polygon(BRect(0, 0, 100, 100), fPolygon);
                        break;
                }

                default:
                        BLooper::MessageReceived(message);
                        break;
        }
}

// _DrawAnimatedLayer
void
ClientLooper::_DrawAnimatedLayer(int32 token)
{
        BMessage message(MSG_DRAW_POLYGON);
        message.AddInt32("token", token);

        message.AddPoint("point", BPoint(fPolygon[0].x, fPolygon[0].y));
        message.AddPoint("point", BPoint(fPolygon[1].x, fPolygon[1].y));
        message.AddPoint("point", BPoint(fPolygon[2].x, fPolygon[2].y));
        message.AddPoint("point", BPoint(fPolygon[3].x, fPolygon[3].y));

        fServerWindow->PostMessage(&message);
}