#Wait problem continued
10 messages in this thread
Here's the details on my IDCMP problem. Hopefully I'm just doing something
stupid and it can be easily fixed.
I've got a window open and I'm plotting a fractal in it. Eventually I'll
hang a menu on it, but for now I just wanted to be able to click on the
window to stop the plot if it's not going like I wanted. (Experimental
color mappings, etc.) To that end, I've set the IDCMP_MOUSEBUTTONS flag on
the window (and that's the only one.) If I understand correctly, this
should give me two IDCMP messages — one when the button goes down, and
another when it's released. So after each point is plotted, I check for a
message. If I don't get it, I go on to the next point. If I get it, I
reply to it. Then, I know that it was the message for the button being
pushed, and there should be another for the button being released. So I
check for another message. If it's there, I reply to it and exit.
Everything is OK. If it's not there, it must mean the user hasn't let go
'of the button by the time the program got to this point. Here's where the
problem starts! I do a Wait(1 << window->UserPort->mp_SigBit). By
printing out the message pointer, I've found out that the program is going
right through the Wait(), and GetMsg then returns a message pointer of
zero. Of course, replying to this immediately kills the system, with an
error number of 80000025.
So, why is it ignoring the Wait? I've written a test program without all
the plotting code etc., and it happens there too. I could post it if
someone tells me how to keep CIS from reformatting my messages.
Jim,
I don't see anything fundamentally wrong with your reasoning here, but I
would point out that as a matter of implementation, you should not be
replying a NULL message… you seem to have already determined (perhaps
through debugging it) that you are getting a NULL message, so don't reply
if it is.
It's kinda hard to say exactly what's happening, but you should be doing
something like…
alive = TRUE;
while(alive)
{
plot_pixels();
if( msg = GetMsg( window->UserPort ) )
{
if( msg->Class == MOUSEBUTTONS )
alive = FALSE;
ReplyMsg( msg );
}
}
while( msg = GetMsg( window->UserPort ) )
ReplyMsg( msg );
CloseWindow( window );
.. this is a bit simplified, but was meant to point out that you should
only reply to a messsage _if_ you get one.
– Keith
Yes, I realize that I should only reply to real messages, but it still
bothers me that it's passing the Wait() without a message actually being
waiting.
Jim,
Without seeing the actual event loop who knows what you may be doing
incorrectly — I can think of a bunch of things to cause what you describe
— the most obvious thing to check is that you aren't mixing
GT_GetIMsg()/GetMsg() and GT_ReplyIMsg()/ReplyMsg().
-sja
Nope, I'm not mixing GadTools and regular code. I have some GadTools code
in my program, but it's all in a different module to handle a different
window. The only flag set in this window is MOUSEBUTTONS for the time
being.
Jim,
I can't help you with your programming problem, but I think you can
tell CIS not to format your lines for you by preceding each line with a
'.' (just the dot). Hope it helps.
-Sean
Jim,
It's not clear that it IS ignoring the Wait(). The example for writing
an IDCMP 'loop' is perhaps a bit unclear. One thing is certain tho, you
NEVER Reply() with a NULL as an argument… the loop SHOULD look like:
while (notdone)
{
Wait(1<<window->UserPort->mp_SigBit);
while (msg = GetMsg(window->UserPort)
{
…do all your message processing here
…it probably is a switch statement to handle
… all of the possible message 'types'
… SOMETHING in here must set 'notdone' to false if you ever
… want the loop to terminate
Reply(msg); // if you feel compelled to Reply() earlier
// you MUST copy the relevant information from
// the msg structure, since it MAY be destroyed
// as soon as the message is Reply()d
}
}
A careful reading of how the Signal() and Wait() functions DO work will
show that (using the above loops) you CAN get calls to GetMsg() which will
return NULL even immediately AFTER the Wait() returns.
Now to address YOUR problem specifically. You say you ONLY call Wait() if
you check for a message, find one, and check for another message and do
NOT find one. Right??
If this is the case, the Signal bit is STILL set in the port. Wait()
is the ONLY function which clears the bits, so the scenario I envision
would almost guarantee the guru in your program. Write the loop as I've
shown above, it's MUCH safer…and look for the mousebutton 'up' message
to set the notdone flag to false.
Hey Now,
I think you should reply to your IntuiMessage as soon as possible.
Usually I get the code, window pointer, subcode, etc. and reply
immediately.
That's the way I do it…
Mike Uman
[]xxi, Inc. >>>
running under AutoPilot
Mike,
So do we actually, but it makes the example code FAR to complex. BTW,
I'm no longer sure that it's the best strategy.
Wait() is the only thing that clears the signal? That would explain the
problem then — I assumed ReplyMsg() did it. Just goes to show you what
happens when you don't have docs!