Print

Print


Sean,

Thank you very much for your time and kind help. The design of Mason
seems very good to me (for the purpose it has designed). I think I
should be able to handle this with your descriptions.

Thank you again,
Mac


> This is a question with a very complex answer, and it's not easy to
> answer given the hack that you're doing here.  So some background.
> When you press "play" on the Console, here's what it does in short:
>
> 1. Calls start() on the GUIState (which in turn calls start() on the
> underlying SimState)
> 2. Spawns a thread (the "play thread") which:
>         2a. Blocks waiting for all Swing Events to have completed (using
> SwingUtilities.invokeAndWait)
>         2b.  Loops:
>                 2b.i. calls simulation.step() to step the simulation once.  This
> automatically synchronizes on the schedule until the step is completed.
>                 2b.ii. Blocks until all Swing Events have completed
>
> When we try (from the Swing event thread) to repaint the window or
> inspect an object in the window or modify a feature of an object, we
> first synchronize on the underlying Schedule.  This causes us to
> block until the playThread's call of simulation.step() has completed,
> so we don't modify or read bad stuff on the model.
>
> When you call "stop" on the Console we:
>
> 1. Interrupt the play thread (since we were called via a java event
> -- mouse click on stop button -- we know we have control and the
> underlying thread is blocking waiting for our Swing Event to complete.
>
> 2. Kill the play thread
>
> 3. Call finish() on the GUIState
>
>
> [Keep in mind that you should call init() on the GUIState and also
> quit() on it when you first create it and later destroy it at the end
> of your application.]
>
> The important item to note here is that MASON's GUI facilities are
> designed to hand off a baton and forth between an underlying thread
> (called the "play thread") and Swing.  Whoever has the baton is
> allowed to read/write the model and the schedule, otherwise they have
> to wait.  Waiting for and acquiring the baton is easy: just
> synchronize on the Schedule.
>
> It looks like you are deviating from this model in two ways:
>
> 1. You're not handing off the baton.  This could result in race
> conditions you don't want to see.
> 2. Your model thread (the equivalent of the "play thread" above) is
> the underlying main() thread perhaps?  It's not made clear.
> Ordinarily in Java GUI applications, the main thread just sets things
> up and dies.
>
> The easiest way to handle this is to NOT call start(), but rather let
> the console handle it for you.  Just call console.pressPlay() to
> start the simulation, and console.pressStop() to stop the
> simulation.  You really ought to do these from the GUI thread, not
> the main thread.  If you're not in the GUI thread, you can still do
> this by creating a small Runnable, whose sole function in life is to
> call console.pressPlay(), and adding him to SwingUtilities with a
> SwingUtilities.invokeAndWait(...).  Likewise for console.pressStop().
>
> When the Display2D's window is disposed, by default it calls
> Display2D.quit() first.  But note that in Java by default when you
> click on a close box in a window, it doesn't dispose the window.  It
> just hides it.  That's what MASON is relying on -- it's just hiding
> the window.  You can change the behavior of closing the window to
> actually dispose the window (and thus call quit()), look at JFrame's
> documentation.  Basically, let Display2D create its window with
> createFrame(), and then change that frame's close-box behavior.
>
> If you do this, you will also want to hook into JFrame's quit()
> method to quit your program when the window is closed.  The quick and
> dirty, ugly way to do this is to just override the quit() method in
> Display2D to call System.exit(0).  That will kill everything
> immediately and quit your application.  A better approach would be to
> call console.doClose(), which will cleanly shut down and dispose
> everything.
>
> Good luck!  Beware that multithreading coding in Swing is
> nontrivial!  :-)
>
> Sean
>