[interfacekit] Re: BHandler::StartWatching()

> 
> alan@xxxxxxxxxxxxxx (Alan Ellis) wrote:
> > A warning. The BeBook is somewhat incorrect on this topic. I can't
> > remember the exact details, but I know that how it works in R5 and 
> > how
> > it is documented in the BeBook differ.
> 
> BeBook:
> "StartWatching() works by sending a message to the BHandler you want 
> to 
> observe, with a BMessenger back to the observer, so both must be 
> attached to a 
> looper at the time StartWatching() is called."
> 
> That paragraph reads like I understand StartWatching() before. And 
> Start/StopWatchingAll() does not work as expected (but was already 
> used 
> that way in applications like Tracker).

Here comes the truth: The watching stuff works bidirectional. Yep, it 
really does. The only reason, why it didn't in my test app, is that I 
accidentially removed the invocation of the superclass version of 
MessageReceived() in the TestApp class.

To state it clearly: Both, the BHandler on which StartWatching() is 
invoked and the target (the first parameter) act as observable and as 
observer at the same time. Subsequent invocations of SendNotices() on 
any of them causes a notification message to be sent to the other one. 
Bug or feature? -- I've no idea.

CU, Ingo

// observer-test.cpp

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <Application.h>
#include <Entry.h>
#include <Message.h>
#include <MessageRunner.h>
#include <Roster.h>
#include <Window.h>

class TestApp : public BApplication {
public:
        TestApp()
                : BApplication("application/x-vnd.bonefish-observer-test")
        {
        }

        virtual void DispatchMessage(BMessage *message, BHandler *handler)
        {
//              printf("TestApp::DispatchMessage(%.4s)\n", (char*)&message->
what);
                BApplication::DispatchMessage(message, handler);
        }

        virtual void MessageReceived(BMessage *message)
        {
                printf("TestApp::MessageReceived(%6ld: %.4s)\n",
                           message->ReturnAddress().Team(), 
(char*)&message->what);
//              BApplication::MessageReceived(message);
// watching is indeed a BHandler feature...
BHandler::MessageReceived(message);
        }

        virtual bool QuitRequested()
        {
                return true;
        }

};

class TestLooper : public BLooper {
public:
        TestLooper()
                : BLooper()
        {
        }

        ~TestLooper()
        {
        }

        virtual void MessageReceived(BMessage *message)
        {
                printf("TestLooper::MessageReceived(%.4s)\n", (char*)&message->
what);
                BLooper::MessageReceived(message);
        }

        virtual void DispatchMessage(BMessage *message, BHandler *handler)
        {
//              printf("TestLooper::DispatchMessage(%.4s)\n", (char*)&message->
what);
                BLooper::DispatchMessage(message, handler);
        }

        int32 test1()
        {
                status_t error = B_OK;
                StartWatching(be_app, 1);

                snooze(100000);
                // trigger notification on app
                be_app->SendNotices(1);
                // trigger notification on looper
                SendNotices(1);

                StopWatching(be_app, 1);
                snooze(100000);
                be_app->PostMessage(B_QUIT_REQUESTED);
                return 0;
        }
};

// test1
int32
test1(void *_looper)
{
        TestLooper *looper = (TestLooper*)_looper;
        looper->test1();

        looper->Lock();
        looper->Quit();
}

// main
int
main()
{
        TestApp app;
        TestLooper *looper = new TestLooper;
        looper->Run();
        thread_id thread = spawn_thread(test1, "test thread", 
B_NORMAL_PRIORITY,
                                                                        looper);
        resume_thread(thread);
        app.Run();
        int32 dummy;
        wait_for_thread(thread, &dummy);
        return 0;
}




Other related posts: