[comp.sys.mac] MultiFinder programming tip

han@apple.UUCP (Byron Han) (12/04/87)

A tip for MultiFinder friendly programming.

I have been tracking down a bug in a program which I am working on
for about 3 weeks.  I squashed it last night. 

Whenever you call GetNextEvent/WaitNextEvent, you should ALWAYS be
prepared to handle updates and also suspends/resumes.  ALWAYS.  

In otherwords, you may have a loop looking for keyDown's only::

WHILE GetNextEvent(keyDownMask, theEvent) DO BEGIN
	{blah blah blah}
END;

You should always use keyDownMask + updateMask at the very least,
and including app4Mask as well is desirable. 

If you do not include updateMask, you will "drop" update events which is 
unsightly confusing and bad.  If you do not include app4Mask, you will
drop suspend/resumes.  This is bad.  

And things bad will make the UITP be angry as well as the MPTP. :-) 
(User Interface Thought Police/Macintosh Programming Thought Police)
BTW:  the Thought Police references are purely in jest.  

Hope this helps someone.

-----
Byron Han - Apple Computer Inc - 20525 Mariani Ave MS 27Y - Cupertino, CA 95014
    "These are my opinions and views only.  Apple has nothing to do with them."
                         ATTNet: 408-973-1940  GENIE: BYRONHAN  APPLELINK: HAN1
                                UUCP: {sun, voder, nsc, mtxinu, dual}!apple!han

gardner@prls.UUCP (12/04/87)

In article <6897@apple.UUCP> han@apple.UUCP (Byron Han) writes:
>A tip for MultiFinder friendly programming.

>Whenever you call GetNextEvent/WaitNextEvent, you should ALWAYS be
>prepared to handle updates and also suspends/resumes.  ALWAYS.  

>You should always use keyDownMask + updateMask at the very least,
>and including app4Mask as well is desirable. 

>If you do not include updateMask, you will "drop" update events which is 
>unsightly confusing and bad.  If you do not include app4Mask, you will
>drop suspend/resumes.  This is bad.  

This sounds like a Multifinder bug. It also sounds like a pain.

Somewhat related, I have a GetNextEvent gripe that's been bothering me:
I would like to be able to get only events associated with a given
window. Is there some way of doing this? Perhaps with EventAvailable 
or something and still guarantee that you remove only proper events
from the queue?

Robert Gardner

goldman@apple.UUCP (Phil Goldman) (12/05/87)

In article <7838@prls.UUCP> gardner@prls.UUCP (Robert Gardner) writes:
>In article <6897@apple.UUCP> han@apple.UUCP (Byron Han) writes:
>>A tip for MultiFinder friendly programming.
>
>>Whenever you call GetNextEvent/WaitNextEvent, you should ALWAYS be
>>prepared to handle updates and also suspends/resumes.  ALWAYS.  
>
>This sounds like a Multifinder bug. It also sounds like a pain.
>
It is not a MultiFinder bug, but it is a pain.

It is not quite true that you have to always be prepared to handle update
events.  For example, if you are in the foreground in the middle of some
high priority mouse tracking code, you might want to only look for mouse
events.  The key is to handle update events in a timely fashion while in the
background (i.e. not the frontmost layer).  MultiFinder will stop feeding an
app in the background update events after a certain large number go by without
it updating.  It is simply to costly on the system to run through this app
over and over.

You have to always be prepared to handle suspend/resumes because they only
have meaning at that exact _WaitNextEvent/_GetNextEvent/_EventAvail call.
It would make no sense at all (and would probably cause problems in most apps)
to receive a suspend event after you've already been switched back into --
Whatever you needed to do in response to the event it's already too late for.

It is difficult in some cases to always handle suspend/resume, but it becomes
very simple if you guarantee that you only call _WaitNextEvent/_GetNextEvent
/_EventAvail from one routine in your program, and just let this routine
handle suspend/resume itself.  Then, if you have multiple event loops let
each call the routine instead of the _WNE/_GNE/_EvAvail traps themselves.

-Phil Goldman
Apple Computer

gardner@prls.UUCP (12/08/87)

In article <6907@apple.UUCP> goldman@apple.UUCP (Phil Goldman) writes:
>In article <7838@prls.UUCP> gardner@prls.UUCP (Robert Gardner) writes:
>>In article <6897@apple.UUCP> han@apple.UUCP (Byron Han) writes:
>>>A tip for MultiFinder friendly programming.

>>>Whenever you call GetNextEvent/WaitNextEvent, you should ALWAYS be
>>>prepared to handle updates and also suspends/resumes.  ALWAYS.  

>>This sounds like a Multifinder bug. It also sounds like a pain.

>It is not a MultiFinder bug, but it is a pain.

>It is not quite true that you have to always be prepared to handle update
>events.  For example, if you are in the foreground in the middle of some
>high priority mouse tracking code, you might want to only look for mouse
>events.  The key is to handle update events in a timely fashion while in the
>background (i.e. not the frontmost layer).  MultiFinder will stop feeding an
>app in the background update events after a certain large number go by without
>it updating.  It is simply to costly on the system to run through this app
>over and over.

Explanation appreciated. I read suspend/resume and thought activate/de-
activate. I guess my mind hasn't been Multifinder-ized yet.

This does raise a big question for me, though. The main place I call
*NextEvent outside the main loop is in ModalDialog replacements. 
Supposedly, I will never be using this routine while in the background. 
So, do I need to worry about this problem in ModalDialog replacements?

In otherwords, the "ALWAYS" above should be "whenever there's a possibility
it will be executed in the background". Do I understand this correctly?

Thank you,
Robert Gardner

P.S. Are people going to start getting annoyed with modal dialogs if
they can't switch out of them? Should I work on replacing all my modal
dialogs with modeless ones (or "quasi-modal, draggable dialogs" like
in MS Word 3)?