Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [platform-swt-dev] MacOS X port status?


Hello Jeff!  I'm sorry it took so long to answer this post but here goes ...

In fact, you are wrong - readAndDispatch performs a single read and dispatch
event cycle for the particular operating system.  If in the course of dispatching an
event, client code runs that starts another event loop, it can hardly be the fault of
the original readAndDispatch that events are dispatched from some other
readAndDispatch in the program.  So, if you write client code that uses multiple
stacked event loops, don't be surprised when multiple stacked event loops run
in your client code.

The fact that on some platforms (ie. Motif) it may also process "timer" and
"alternate input" events is irrelevant to an SWT client.  These are platform specific
concepts that don't show up in SWT (in the case of "alternate input") and are not
events (in the case of "timer").  In the case of "drag and drop", it is unspecifed what
happens after the drag is started and where/when/if the OS starts a modal loop.

The return value of readAndDispatch indicates that there is no more work for SWT
to do - ie. there are no more events in the OS, no more timer Runnables, no more
sync/async messages.  If it's "false", SWT can go to sleep, waiting for more work.

The discussion of "modal" blurs the meaning.  The operating systems have a
definite concept of "modal" that involves blocking input to one or more windows.
This says nothing about event loops.  When you say, "modal", you really mean
running an event loop until some condition is met, typically so you can guarantee
that a value has been assigned by the user.  This is a good use of a stacked SWT
event loop.  BTW, the event loop fragment that you supplied is wrong - it exits as
soon as there are no pending events, probably no what you intended:

// wrong - it exits early
while (someOptionalConditions && !display.readAndDispatch())
display.sleep()


This is the correct way to code it:

// correct - exits when the conditions are met
while (someOptionalConditions) {
    if (!display.readAndDispatch()) display.sleep()
}

So, it's up to the application to decide if they are waiting for a value and/or
blocking input to windows, not SWT.  Constructing a "higher level concept of
modality" is not the job of SWT - only the app can decide.  Besides, the SWT
charter says that we provide efficient access to the capabilites of the operating
system, not invent "higher level concepts".  Actually, I'm quite interested how
you think this might look because this is an area that tends to confuse Java
programmers.  Operating system programmers know what an event loop is
and are not surprised when they are asked to code one.

I'm sorry that you don't like the "openeness" of SWT event
loop but I claim that a toolkit that doesn't give you access it and gives you one
for free is not doing you any favours.  There is invariably API that allows you to
access the hidden loop.  Often hiding the loop involves creating another thread
and this brings it's own grief.  Having an explicit event loop allows you to answer
the question "When does my program end?" and "Mommy, where do events
come from?" (ANSWER: Events come when you call out to SWT, typically from
the event loop).

I'm not sure what the discussion of "sendEvent" versus "postEvent" for the SWT
implementor is getting at.  In fact, "postEvent" is an artifact and there has been
some discussion around here about getting rid of it.

Having an "open API" for the event loop allows you to flush all pending events
without waiting as follows:  "while (display.readAndDispatch ());".  Also, you can
do whacky things like looking for global state changes between events (such as
tracking the focus widget or counting the number of shells) - this isn't recomended
because it slows down the event loop - but it's all possible.

Finally, if you really hate typing the two lines, put them in a helper method that
dispatches events "while (true)" and get on with life.




"Jeff Brown" <j9brown@xxxxxxxxxxxxxxxxx>
Sent by: platform-swt-dev-admin@xxxxxxxxxxx

11/23/01 02:27 PM
Please respond to platform-swt-dev

       
        To:        <platform-swt-dev@xxxxxxxxxxx>
        cc:        
        Subject:        Re: [platform-swt-dev] MacOS X port status?


Hope I get all the details right this time...

> >Combined with the fact that readAndDispatch does *not* guarantee that it
> >will return after processing a single event (it may have some others it
> >needs to process), I didn't think that I was breaking it's behavior too
> >badly.
> I've read the doc again and I think that it processes at most one OS event
> and possibly more inter-thread messages.
> May be somone from the SWT team can help?

There is no guarantee that only one event will be processed.  In the case of
modal loops, readAndDispatch() may indirectly invoke an event handler
containing its own readAndDispatch()-based modal loop.  Hence there is
no bound on the number of events processed by the call, or even on its
completion time.  Even in the absence of such nesting, the SWT
implementation
may handle an arbitrary number of events, provided the ordering of
dispatched events does not violate the event model semantics.
(i.e. can't process keyReleased before keyPressed)  The SWT Motif
implementation of readAndDispatch() may read an event of the top of
each of 3 queues to equitably deal with X events, timer events, and
auxiliary
input events (used by display.wake()) -- only processing one could lead to
short-term starvation.  Finally, there is no one-to-one correspondence
between OS events received and user events fired for obvious reasons.
On additional oddity: in the case of drag and drop on Motif with threading
enabled, the platform actually runs its own modal event loop from within
the event dispatching code!

All told, _no_ assumptions may ever be made about how many / which events
readAndDispatch() will process.  The only guarantee is that at some
time readAndDispatch() will return false to indicate that display.sleep()
should be called to block the thread instead of causing a busy wait
(since readAndDispatch() does not block if no events are pending).
The return value is not even an indicator of whether or not events were
actually processed, or whether any more are pending!

> I think nobody does anything interesting in an event loop besides having a
> special _expression_ for terminating the loop and leaving the modal mode.

Doing anything else inside the event loop would not yield useful behaviour.
Since the readAndDispatch() runs for an indeterminate amount of time,
using the event loop body for polling or other periodic operations cannot
be guaranteed precise bounds on service time.  Better off registering a
timerExec() for these sorts of things.  Besides, doing any moderately
intensive processing within this loop could slow the application's event
processing down noticeably.

Hence, the only useful event loop for SWT is of the form:
while (someOptionalConditions && ! display.readAndDispatch())
display.sleep();

<idle_rambling>

Personally, I'm somewhat disappointed by the openness of that API
as it is error prone and not very useful except perhaps to construct
modal loops.  Invariably this amounts to nesting an event loop within
the dispatch portion of some outer event loop.  Among other things,
this means for SWT implementers that some care must be taken when
user event handlers are invoked immediately via sendEvent() instead
of being deferred via postEvent() since sendEvent() might not return
"prompty", and the message queue may be a few events shorter when
it does.

IMHO, rather than worrying about the added complexity involved with
possible nesting of event loops, perhaps some higher-level modality
support could be constructed.  Unfortunately, I can't think of any
ways to do this without breaking the SWT event model in some way.
Any ideas?

</idle_rambling>

Jeff.


_______________________________________________
platform-swt-dev mailing list
platform-swt-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/platform-swt-dev



Back to the top