[interfacekit] Re: BHandler::fToken

  • From: "Adi Oanca" <e2joseph@xxxxxxxxxx>
  • To: <interfacekit@xxxxxxxxxxxxx>
  • Date: Wed, 12 Mar 2003 19:24:03 +0200

... but FIRST!!!

PEOPLE!!!! if you know something about the internals of BeOS,
SHAREEEEE!
write a document about them!!! ESPECIALLY if you don't work in
that area!!!

I'm relatively new to BeOS, as a matter of a fact, the
most complicated program that I made under it as just 5(!!!) buttons;
but I know, in high lines, how things work under the hood, that's why
I wanted to join this project since the beginning, but I couldn't!
I stayed and studied BeOS architecture, figured some things
out, others not, made presumptions, tried to do things like Be did,
for now to discover that SOMEONE ( I think with experience in
BeOS area. Marc !?!!) ACTUALLY *KNOW* BeOS internals!!!!!

SHARE people SHARE!



> I know, but before we start to optimize, we can look if it's needed to do
> so. As some people on the list already said, and even found out by
> themselves ;), "Premature optimization is the root of all evil".

Here I don't agree. I think once you have a better method you have to
implement it!

> > dispatched to BWindow::ConvertToMessage() who will create
> > a BMessage then call BWindow::DispatchMessage().
>
> It is indeed the event port of BWindow that gets the event messages from
the
> app_server, but they arrive as normal flattened BMessages. They are
> unflattened from the port data using the normal BMessage::Unflatten(char
> const *) in _CEventPort_::GenerateMessage() called from task_looper().

That's quite strange, since, by sending a BMessage, additional data is sent
(BMessages's). By sending a message(a package of preordered data) it will be
faster. Me and DarkWyrm would like to achieve a minimum of port
messages, with a minimum of data!

> BWindow::ConvertToMessage() is a virtual overridden method called from the
> BLooper methods.

In my implementation of BWindow it looks like this:

BMessage* BWindow::ConvertToMessage(void* raw1, int32 code){
    BMessage *msg;

        // This is in case we receive a BMessage from another thread or
application
    msg   = BLooper::ConvertToMessage( raw1, code );
    if (msg)
        return msg;

        // This is in case we receive a message from app_server
    uint8  *raw;
    raw   = (uint8*)raw1;

    msg   = new BMessage();

    switch(code){
        ...
    }
    return msg;
}

Is this not good? It also performs the functions that R5's
_CEventPort_::GenerateMessage() does. What I would like you to
remember is that, in task_looper() both ports are checked for
messages, so there would be a few BMessage calls, a few app_server
message calls, a few  BMessage calls, a few app_server message
calls .... for BWindow::ConvertToMessage(...).

> If there's a message read from the event port, it's added
> to the queue using BLooper::MessageQueue()->AddMessage(),
> BWindow::DispatchMessage() is not called directly, as lot's of things need
> to happen in BLooper before you dispatch.

YES of course!

> At least that's how R5 works.

> To call view->MouseMoved you need to read at least the BPoint
> "be:view_where" from the BMessage which you get in DispatchMessage.

Hmm... here you might be right, I'm not sure if app_server will send
me the token for the view that's under the mouse. That I will have to
discuss with DarkWyrm.

> in O(1) time.

I(!), must've been kidding, saying O(n)

>
> I will try to explain how I think it happens in R5 :)
>
> To begin the story, a BView is created on the client side, since it is
> derived from BHandler, it gets a handler token, which is a unique
identifier
> for the BView in the BApplication. At a certain moment, it gets attached
to
> a BWindow (AddChild). By getting attached, it gets a counterpart on the
> app_server. The BWindow takes care of this, by sending the necessary
command
> through the session port (view_builder), one of the parameters of this
> command is the handler token.
>
> On the app_server side, the command and the parameters are read from the
> port, and a server view is created. This server view knows its counterpart
> on the client by it's handler token. When the server view is created, the
> server window writes the server_token to the port.
>
> The BWindow reads this server_token from the port and stores it in the
> BView.
>
> Now a user suddenly moves the mouse over the view. The input server
notices
> the move, and notifies the app_server of this event. The app_server looks
> through its server windows, and finds the one the mouse is over. It then
> passes the message to this server window. The server window replaces the
> point, which is in screen coordinates, to one that is in window
coordinates.
> It then searches the server view on which the mouse is over. It sets the
> target of the message to the handler token of the BView counterpart of the
> found window. Then it sends the message through the event port.
>
> The BWindow gets the message from the event port in task_looper, and puts
it
> in the message queue. In BLooper the target of the message is determined,
by
> looking up the handler token to get a BHandler*. From within BLooper
> BWindow::DispatchMessage is called with the message, and the handler (note
> that fLastMessage is set in BLooper before dispatching, and that the
message
> is filtered if needed). The BWindow sees that it's a B_MOUSE_MOVED
message,
> and calls do_mouse_moved(message, view), first dynamic casting the
BHandler*
> to a BView*. Here the necessary data is extracted from the message to call
> BView::MouseMoved.
>
> I find this way of working very clean, and especially safe. As you can
see,
> only once the view was searched through the tree, and the message went
> through the same processing pipeline as all other messages.
>

VERY GOOD! Finally someone gives me a viable solution, and
a CLEAR answer to my problems! Through out this topic
a repeatedly asked 2 things: 1) should we use BView::fToken as a
server token? or 2) should we use BView's pointer as a server token?
I really liked the solutions, the difference of opinions, I almost decided
in favor of pointers, but, woww... after this email from Marc,
bye bye pointers!

That's it, we will use BHandler::fToken!!!



Other related posts: