[net.micro.amiga] IntuiCorrections to Draper and Luck examples

jimm@amiga.UUCP (Jim Mackraz) (12/13/85)

    Hello net.micro.amiga, and thank you John Draper for forwarding the 
    cause of IntuiEducation.  Dale Luck posted a comment on John's main
    processing loop, but his correction itself was slightly in error.

    Furthermore, John commits another common error in his example, duplicated
    below.
 
   EXAMPLE 1 ************ John D's example
   for (;;)
   {
 
      if (message = (struct IntuiMessage *)GetMsg(w->UserPort))  {
        MessageClass = message->Class;
        code = message->Code;
        ReplyMsg(message);
        switch (MessageClass) {
 
           case GADGETUP    :
           case GADGETDOWN  : do_gadgets(message, w);
                              break;
 
           case CLOSEWINDOW : close_things();
                              exit(0);
                              break;
           case MOUSEBUTTONS: break;
        }   /* Case */
      }  /* if */
   }  /* for */

    COMMENTS ********
    As Dale pointed out, a polling loop on the message port is not a proper
    multitasking way to behave.  A more subtle error: note that the message is
    replied to before its contents is used in do_gadgets().  A general
    principle (metaphor by bobp) applies: A Message is a license to use a
    portion of the sender's data space, which no longer applies after the
    message is Reply'd.  In this case, Intuition will reuse the message, its
    contents will change, and do_gadgets() may be confused, or crashed, if this
    happens.
    ** IMPORTANT ****
    I personally like the way John caches the code of the message, and replies
    as soon as possible.  This might prevent Intuition from allocating another
    message for this window if it needs to send another, but the savings are
    marginal.  With the exception of the very dangerous MENUVERIFY, REQVERIFY,
    and SIZEVERIFY messages, it doesn't really matter much if you Reply()
    before or after you use the data in the message.  HOWEVER, be careful about
    your caching.  In particular, IAddress is not guaranteed to hold a
    reasonable value if it is not defined for the particular class of message.
    So if you try to stash the Gadget ID
	((struct Gadget *)message->IAddress)->GadgetID
    at the same place John stashes the class and code, and if the class is not
    GADGETUP or GADGETDOWN, you may get an address error (Guru Meditation
    00000003.<your task here>).  Check the Intuition Manual for the exact times
    that IAddress is used and therefore guaranteed vaild.


   EXAMPLE 2 ************ Dale's correction to busy loop
    for (;;)
    {
	    Wait(1<<w->UserPort->mp_SigBit);	/* wake up when message there */
	    if (message = (......
		    etc.
    }

    COMMENTS *******
    This demonstrates the spirit of the block-until-message approach, but makes
    a subtle error: Messages queue, while Signals do not.  Therefore, if two 
    messages arrive while you are in the body of the loop, when you Wait() you
    will not sleep (signal has already been posted with the arrival of the
    messages), but will process only one message.  Next time you Wait(), you
    will sleep although there is a message in the queue.

   EXAMPLE 3 ************  What I use.
    FOREVER /* define as for(;;) in intuition.h */
    {
	if ((msg = (struct IntuiMessage *)GetMsg(window->UserPort)) == NULL)
	{
	    Wait(1<<window->UserPort->mp_SigBit);
	    continue;
	}
	...... etc.  ...
    }

    COMMENTS ***** You may feel free to use any flow of control you like,
    of course.  I think I chose this one because it was different than the
    first solution I saw.

    GENERAL ***** I want to thank John again for his contributions.  Unless I
    missed something, the remainder of his posting was accurate and clear.
    I'm the new guy at Amiga Software, and my responsibilities include 
    maintenance and enhancement of Intuition.  I welcome all questions and
    suggestions and comments.  We have trouble mailing through ARPAnet
    gateways, so include your phone number or USnail address, if you might
    want a direct reply.

    It is my hope that I can also provide some examples for new Intuition
    and Amiga application programmers, but time ..., you know.

				{hplabs,decwr}!pyramid!amiga!jimm