[plt-scheme] MrEd: how can I _cleanly_ keep the states of various widgets in sync?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Nov 30 08:19:24 EST 2007

I recommend against the background thread, because it introduces many
race conditions. Any time that you send on a channel, you could instead
queue a callback (using `queue-callback'), which would keep everything
in the same thread.

For that matter, you could just make a direct call, instead of
scheduling a callback. I'm not sure that a single event, as below,
solves the original problem of having the radio-box know nothing about
the button.


Are "listeners" the right solution here? That is, each widget could
keep a list of callback procedures to run instead just a single
callback. Then, the button could register a listener procedure with the
radio-box that enables/disables the button, in addition to whatever
action other callbacks take.

It would be easy to add this generalization into the MrEd widgets. In
the meantime, it's not too difficult to implement yourself.

A drawback of listeners is that registration and deregistration of
listeners are imperative operations. You'd really like to wire things
together more declaratively (as Shriram said in another thread last
week).

Matthew

At Thu, 29 Nov 2007 19:12:56 -0500, Matthias Felleisen wrote:
> You communicate the event of a change in GUI state via a channel and  
> then your thread can update the guis. Something like the below is a  
> start.
> 
> (Since the #t is useless, I am wondering whether we can get some  
> other kind of event to do all this, looking a bit more functional.)
> 
> -- Matthias
> 
> 
> #! /bin/sh
> #| Hey Emacs, this is -*-scheme-*- code!
> #$Id: gui-constraints.ss 5286 2007-11-29 23:51:36Z erich $
> exec mred --no-init-file --mute-banner --version --require "$0"
> |#
> (module gui-constraints mzscheme
>    (require (lib "class.ss")
>             (lib "mred.ss" "mred"))
> 
>    (define frame (new frame% (label "Constraint Testing")))
> 
>    (define delta (make-channel))
> 
>    (define button
>      (new button% (parent frame) (label "Click me!")
>           (callback (lambda (item event)
>                       (message-box "OK" "Now what?")))))
> 
>    (define radio-box
>      (new radio-box% (label "Pick one")
>           (callback (lambda (e x) (channel-put delta #t)))
>           (choices '("Disable that button there" "Let it be enabled"))
>           (parent frame)))
> 
>    (thread
>     (lambda ()
>       (let loop ()
>         (sync (system-idle-evt) delta)
>         (channel-get delta)
>         (send button enable
>               (not (zero? (send radio-box get-selection))))
>         (loop))))
> 
>    (send frame show #t)
> 
>    )
> 
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme


Posted on the users mailing list.