Post Goal to the thread
running XPCE. This supports XPCE running in a foreground thread
(handling the GUI and short application-oriented actions) while one or
more background threads do computation and other background work.
Background threads call in_pce_thread(Goal) to insert a Prolog goal into
the main thread's event loop -- the goal is placed in the normal
X11/Windows event queue. in_pce_thread/1
returns immediately in the calling thread.
A typical setup has the background thread compute a result and ask
the GUI to present it. The result may be passed as an argument to Goal
or held in dynamic predicates. Both threads run in parallel, so
update/read of shared dynamic data must be properly coordinated. To wait
for the GUI to complete the calling thread can use a message queue:
sync_call(Goal) :-
thread_self(Me),
in_pce_thread(make_sync_goal(Goal, Me)),
thread_get_message(sync_goal(Result, Binding)),
( Result == true
-> Goal = Binding
; Result == exception
-> throw(Binding)
).
make_sync_goal(Goal, Thread) :-
( catch(Goal, E, true)
-> ( var(E)
-> Msg = sync_goal(true, Goal)
; Msg = sync_goal(exception, E)
)
; Msg = sync_goal(false, _)
),
thread_send_message(Thread, Msg).