[Tutor] Re: event-based programming

Sean 'Shaleh' Perry shalehperry@attbi.com
Sat, 13 Jul 2002 09:58:36 -0700 (PDT)


On 13-Jul-2002 Erik Price wrote:
> 
> Sean & dman,
> 
> Thanks very much to both of you for addressing this question.  I now 
> know two things about event programming:
> 

glad to help

> Although I really wanted to know "what is going on", so the first answer 
> was very helpful, the second one assures me that, as with JavaScript 
> event handling in a browser, the programmer doesn't have to worry -too- 
> much about the mechanics of event programming.  Just write the event 
> handler, register it somehow (though this seems to be done for you in 
> JS), and then write the code that submits the event (also something the 
> browser does for you in JS).
> 
> Of course, this leads to further questions, naturally.
> 
> On Saturday, July 13, 2002, at 02:11  AM, Derrick 'dman' Hudson wrote:
> 
>> Note - this is not real code, but it gives the idea.
>> It is sort of a blend of the Java/Swing and GTK+ styles of
>> implementaiton since those are the toolkits I've written the most code
>> for, though not recently.  (actually, those are the only toolkits I've
>> written applications for.  The two xforms labs don't really count, and
>> I've only glanced at wxWindows)
> 
> I did not see a Swing library in my module directory.  Is this a 
> standard offering with Python 2.2?
> 

Swing is a GUI library for Java.

>> This leads to another problem, though.  What if the main thread (event
>> loop) and the worker thread both try to update some component of the
>> gui at the same time?  A race condition.  Then add modal dialogs to
>> the picture (modal dialogs are evil anyways).  One of the bugs I fixed
>> at my last job (involving java/swing) was a total lockup of the gui
>> under certain error conditions.  The problem was just that -- a worker
>> thread tried to display a modal dialog.  However, it happened that
>> that caused a deadlock in the system (without the dialog ever
>> finishing painting).  The solution was quite simple -- wrap the
>> dialog's creation in a "Runnable" object and queue it for execution in
>> the main thread.  Swing has some utility functions
>> (eg javax.swing.SwingUtils.invokeLater()) that allow you to pass a
>> java.lang.Runnable object which will be added to the end of the event
>> queue.  Then the event loop will run() that object (call its .run()
>> method) in the main thread.
> 
> I'm sorry, but this is confusing to me.  Although I'm not sure exactly 
> what a modal dialog is, I follow what you are saying -- but I don't 
> understand how the modal dialog locked up the gui.  By putting the 
> dialog's cretaion into a "Runnable" app, I am assuming that this means 
> you coded it to be performed within a separate thread (perhaps this is 
> what you were talking about by "spawning a 'worker' thread"?).  But what 
> I am unsure of is what is wrong with having the dialog just come up (the 
> way you had it originally).  This is very interesting to me, learning 
> about this topic.
> 

goes like this, the application has a loop:

while not time_to_exit:
  if check_for_event():
    handle_event()
  else:
    process other stimuli

when the application is in handle_event() NOTHING else is happening.  The modal
dialog dman mentions would cause this to happen.  handle_event will set the
time_to_exit flag is a close/exit event occurs or for some other condition.

And to help out, a modal window is one marked "you can do nothing else in this
application until finish with me".  Generally they are a bad idea.

>> An additional reason all this is necessary is because most (all?) gui
>> toolkits are not written to be thread-safe.  That is, they don't
>> provide any internal locking or synchronization; meaning that they
>> assume they will only be accessed from a single thread.  This is done
>> because locking and synchronization adds both time and memory
>> overhead, and for some applications it isn't necessary.  In addition,
>> if you follow the guidelines I outlined above (as the swing utility
>> functions make it fairly easy to do), you can avoid the issues
>> altogether and not having the speed/memory overhead is a good thing.
> 
> You mean by putting the code into a new "Runnable" instance?  I have not 
> yet learned about the "Runnable" object yet.
> 

dman is again babeling about Java.  As i understand it, Runnable is essentially
an object which queues itself and when the time is right a slice of the
program's time is given to it.

>> To summarize, event-driven programming consists of defining functions
>> or methods that will be called when an event occurs.  How events are
>> detected and handled is an implementation detail of the underlying
>> system.  Suffice it to be "magic" that is well documented.
>> Event-driven programming (at least in GUIs) tends to be seen
>> hand-in-hand with parallel processing, and all the synchronization
>> issues that entails.
> 
> That is reassuring for now, though perhaps someday I should look into 
> that implementation and see how it works.  Not at this early stage, 
> though.
> 

one of the pitfalls I tried to point out in my first mail is that events are
ASYNCHRONOUS and as dman points out, parallel.

You may be expecting:

expose
configure
move
resize

but get

configure
resize
move
expose

or any other combination.  You must write you code in a style which allows
paths in from various directions.  This often means using global variables or
the OO equivalent.

You also do not know WHEN the application (or sender) will get to your events
and vice versa.  How long has it been since this move event was sent?  Is this
network request still applicable?