[interfacekit] Re: BHandler::fToken

> > > App_server messages concerning BViews are very numerous! For every
> > > message that's meant for a BView, I have to make a search through the
> > > BViews tree. That is really expensive, and there is NO better
> > > algorithm for
> > > searching a specified BView!!!
> >
> > Actually, the BMessages sent from the app_sever
>
> No, BMessages created by BWindow from app_server 'simple' messages

Please say clearly when you are talking about your app_server or the BeOS R5
one. I only know the BeOS R5 one, so when I talk about app_server does this
and that, it's the BeOS R5 one I'm referring to :).

> > -Mouse messages: if a view grabbed the pointer, it's sent to this one.
> > Otherwise a quick search through the view tree using the
> coordinates does
> > the trick.
>
> Yes, and that I'm trying to avoid! Having a pointer to that view
> eliminates the search?!

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".

> Handler tokens are handled by BLooper when it gets a BMessage through it's
> port; Server tokens are handled by BWindow! They are attached to a message
> that BWindow receives form it's server counterpart, ServerWindow.
> Note that
> these messages do not came through BLooper's port, they came
> through a port
> that BWindow opens in it's constructor! Then, they are readed in the
> virtual private function task_looper() (BWindow's version listens to 2
> ports),
> 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().
BWindow::ConvertToMessage() is a virtual overridden method called from the
BLooper methods. 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. At least that's how R5 works.

> > I also don't see why there would
> > be so much overhead. Even if you would do a FindView(where) call every
> time
> > you get a B_MOUSE_MOVED message, since the amount of checks in the view
> tree
> > is at most the depth of the tree. I think reading the
> parameters from the
> > BMessage takes more time then the searching.
>
> I don't need to read any parameter from any BMessage! Remember! BWindow
> creates a BMessage for a specified BView, and, I already know the
> token(address) (ServerWindow gave it to me!)

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

> > > PLUS, this is where we AGAIN gain some time(I might say - A LOT),
> > > because we only need to search through a relatively small(!) hash, not
> the
> > > entire list of Layers that exists on the app_server!
> >
> > A hash table is usually used to search fast through a relatively large
> list
> > in O(1) time.
>
> You must be kidding. It's complexity is O(n).

O(n) is the complexity you get with structures like linked lists, vectors,
etc. With a decent hash table implementation you can achieve O(1)
complexity.

> No, here you are right! Let me remind you that ServerWindow, also does a
> search through its tree of Layers, before sending a message to a BWindow.
> Now why would we do that twice? It is later, after we complete R1, that we
> will try to optimize our code, why not doing it now, when we
> already have a
> method?

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.

Marc Flerackers (mflerackers@xxxxxxxxxx)
Software Engineer


Other related posts: