Hello,

It sounds a little weird to me that you use a synchronous call to the UI
thread (via syncExec and not asyncExec), but then use an asynchronous call
to an agent ?

I don't have repl here to test it, but could you make something simpler,
like creating a mutable structure in the let - an array of one object - and
during the sync call, place the result in the array ?
Would this impure approach have some drawbacks I can't see right now ? It
seems to me that this would be very local to the function, so maybe not that
bad ?

This is already an "impure" (in the functional sense) operation, since it's
an IO operation, after all ?

And also, you could optimize code in the macro by adding code to test if you
are already in the UI thread, and if so, save the call via the runnable.

And maybe, you could consider that the display is such a common thing in the
application that making it a global var such as *out*, *in*, could help
passing it as a parameter for the vast majority of functions ?
Something named like *swt-display* ?

So the macro could be (not tested) :

(defmacro swt-sync-call
  "Ensures that the body is synchronously executed in *swt-display*'s UI
thread.
   Returns the value of the last item of body.
   Does not create a Runnable if already called from within the right
thread"
  [& body]
  `(let [running-thread-display (org.eclipse.swt.Display/getCurrent)
         already-ui-thread (= *swt-display* running-thread-display)]
     (if already-ui-thread
       (do ~...@body)
       (let [val-res# (make-array Object 1)]
         (. *swt-display* syncExec (proxy [Runnable] [] (run [] (aset
val-res# 0 (do ~...@body)))))
         (aget val-res# 0)))))

HTH,

-- 
Laurent


2009/2/19 BerlinBrown <berlin.br...@gmail.com>

>
>
>
> On Feb 19, 11:58 am, BerlinBrown <berlin.br...@gmail.com> wrote:
> > I am working with this SWT application.  For most calls with SWT, if
> > you want to request data from a widget, then you must do so through
> > the  syncExec or asynExec.  These methods require an implementation of
> > runnable as an argument.
> >
> > This works fine for 'setting' a value, but I have trouble when I need
> > to get a value from a widget, like a Textarea.  This is the macro that
> > I created and it runs, but I don't think it is working properly.  Does
> > anyone have suggestions?
> >
> > Usage:
> > term    (get-sync-call disp (. box getText))
> >
> > (defmacro get-sync-call
> >   "Synchronous execute call.  Create a proxy Runnable object and then
> > execute the
> >  body code"
> >   [disp & body]
> >   ;;;;;;;;;;;;;;
> >   `(let [val-res# (agent nil)]
> >      ;;(. ~disp syncExec
> >      (. ~disp syncExec (proxy [Runnable] [] (run [] (send val-res# (fn
> > [_#] ~...@body)))))
> >      @val-res#))
>
>
> (defmacro get-sync-call
>  "Synchronous execute call.  Create a proxy Runnable object and then
> execute the
>  body code"
>  [disp & body]
>  ;;;;;;;;;;;;;;
>   `(let [val-res# (ref nil)]
>     ;;(. ~disp syncExec (proxy [Runnable] [] (run [] (send val-res#
> (fn [_#] ~...@body)))))
>     (. ~disp syncExec (proxy [Runnable] [] (run [] (dosync (ref-set
> val-res# ~...@body)))))
>     (. Thread sleep 50)
>     (deref val-res#)))
>
> OK, I added this, don't know why I added Thread.
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to