[interfacekit] sync
- From: "Adi Oanca" <adioanca@xxxxxxxxxxxxx>
- To: "IK Team" <interfacekit@xxxxxxxxxxxxx>
- Date: Mon, 22 Sep 2003 19:22:12 +0300
Hello!
Marc, I need your idea on a very serious problem that I have.
[ I bet you were expecting this... :-) ]
It's about synchronization between app_server and BView class.
OK, what's this about?
Let's follow an example so you could understand better.
In BView::ResizeTo() I send to app_server a message, in turn it sends
back the new width and height of that view, as well as the ones for its
children. This is NOT a synchronous call! The server sends B_VIEW_RESIZED
messages to window's server port to be dispatched through BWindow's message
loop - like all other server messages.
The problem appears when I call BView::Frame() because it contacts
app_server seeing that B_VIEW_COORD_BIT flag was set by BView::ResizeTo().
This call is synchronous! It sends AS_LAYER_GET_COORDS msg to app_server and
expects for them.
THE PROBLEM is app_server already sent some B_VIEW_RESIZED messages that
have NOT been processed! ... and when BSession::ReadXXX tries to read the
coordinates... it reads the WRONG data! - B_VIEW_RESIZED messages came
first!
If I think a bit, I realize THIS is not the only time when
de-synchronization appears! It's there EVERY time app_server sends a
messages
to BWindow/BView, e.g.. _UPDATE_ msg, and a synchronous call to app_server
is
made.
Haven't you encountered the same problem? How did you solved it? How did
Be solved it!
I have an idea about solving it! It involves prefixing each synchronous
reply with an identifier(the same as the message name sent to server) and
till the right reply arrives dispatch those before it!
The code looks like this:
BView::Frame(){
...
session->WriteInt32( AS_LAYER_GET_COORDS );
session->Sync();
ensureRightReply( AS_LAYER_GET_COORDS );
session->ReadRect( &fBounds );
session->ReadFloat( &originX );
session->ReadFloat( &originY );
...
}
BView::ensureRightReply( int32 code ){
int32 c;
session->ReadInt32( &c );
while( c != code ){
BMessage *msg = NULL;
msg = ConvertToMessage( c );
if ( msg )
DispatchMessage( msg );
if ( msg )
delete msg;
}
}
PS: lots of BView::ResizeTo/By generate ONLY ONE BView::FrameResized()! How
is this done? A flag is set and when in task_looper it is checked and a
message sent if set?
I cannot think of another way since in:
====
ResizeTo(153.0f, 271.0f);
frame = Frame();
printf("Applying ResizeTo(153.0, 271.0)...\n");
printf("\tFrame(): (%f,%f,%f,%f)\n", frame.left, frame.top, frame.right,
frame.bottom);
Flush(); //Sync();
ResizeBy(11.0f, 6.0f);
frame = Frame();
printf("Applying ResizeBy(11.0, 6.0)...\n");
printf("\tView1::Frame(): (%f,%f,%f,%f)\n", frame.left, frame.top,
frame.right, frame.bottom);
===
BView::FrameResized() it's called once.
Adi.
- Follow-Ups:
- [interfacekit] Re: sync
- From: Marc Flerackers
Other related posts:
- » [interfacekit] sync
- » [interfacekit] sync
- » [interfacekit] Re: sync
- [interfacekit] Re: sync
- From: Marc Flerackers