The notion of an event in the Prolog+Tcl/Tk system is overloaded. We have already come across the following kinds of events:
It is further about to be overloaded with the notion of Tcl/Tk events. It is possible to create event handlers in Tcl/Tk for reacting to other kinds of events. We will not cover them here but describe them so that the library functions are understandable and in case the user needs these features in an advanced application.
There are the following kinds of Tcl/Tk events:
The problem is that in advanced Tcl/Tk applications it is possible to create event handlers for each of these kinds of event, but they are not normally serviced while in Prolog code. This can result in unresponsive behavior in the application; for example, if window events are not serviced regularly then if the user tries to resize a Tk window, it will not resize in a timely fashion.
The solution to this is to introduce a Prolog predicate that
passes control to Tk for a while so that it can process its events,
tk_do_one_event/[0,1]. If an application is unresponsive because
it is spending a lot of time in Prolog and is not servicing Tk events
often enough, then critical sections of the Prolog code can be sprinkled
with calls to
tk_do_one_event/[0,1] to alleviate the problem.
tk_do_one_event/[0,1] has the following forms:
which passes control to Tk to handle a single event before passing control back to Prolog. The type of events handled is passed through the ListOrBitMask variable. As indicated, this is either a list of atoms that are event types, or a bit mask as specified in the Tcl/Tk documentation. (The bit mask should be avoided for portability between Tcl/Tk versions.)
The ListOrBitMask list can contain the following atoms:
tk_do_one_event/0 is equivalent to a call to
tk_do_one_event/1 with all flags set.
A call to either of these predicates succeeds only if an event of
the appropriate type happens in the Tcl/Tk interpreter. If there are no
such events, then
tk_do_one_event/1 will fail if the
tk_dont_wait wait flag is present, as will
tk_do_one_event/0, which has that flag set implicitly.
tk_dont_wait flag is not set, then a call to
tk_do_one_event/1 will block until an appropriate Tk event
happens (in which case it will succeed).
It is straight forward to define a predicate that handles all Tk events and then returns:
tk_do_all_events :- tk_do_one_event, !, tk_do_all_events. tk_do_all_events.
tk_next_event/[2,3] is similar to
tk_do_one_event/[0,1] except that it processes Tk events until at
least one Prolog event happens. (We came across this predicate
before when discussing Prolog event queue predicates. This shows
the overloading of the notion event where we have a predicate that
handles both Tcl/Tk events and Prolog queue events.)
It has the following forms:
tk_next_event(+TclInterpreter, -Event) tk_next_event(+ListOrBitMask, +TclInterpreter, -Event)
The Prolog event is returned in the variable Event and is the
first term on the Prolog event queue associated with the
interpreter TclInterpreter. (Prolog events are initiated on the
Tcl side through the new Tcl command
earlier; see prolog_event).