[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: rethinking interpreter <-> gui interaction
From: |
Daniel J Sebald |
Subject: |
Re: rethinking interpreter <-> gui interaction |
Date: |
Mon, 1 Jul 2019 23:57:35 -0400 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.1 |
On 7/1/19 2:47 PM, John W. Eaton wrote:
Currently, most communication between the Octave interpreter and GUI is
managed by the octave_link class interface defined in the interpreter.
The actions specific to the GUI are implemented in the GUI by the
octave_qt_link class. These classes provide a thread-safe way for
interpreter and GUI to ask each other to perform actions. For example,
the interpreter may notify the GUI that the workspace has changed so
that the workspace view in the GUI may be updated. Or the GUI may ask
the interpreter to invoke a function to change the current directory.
As I understand it, there are four cases that may need to be handled:
1. The interpreter makes a request or sends a notification to the GUI
and does not need an immediate result. The interpreter and GUI threads
may continue to run independently. For example, the inteprerter
notifies the GUI that the current working directory has changed. The
GUI will respond by updating the directory displayed in the file browser
widget but the interpreter may continue executing while the GUI performs
this action.
2. The interpreter makes a request or sends a notification to the GUI
and requires an immediate result. The interpreter thread must be
suspended and wait until the GUI thread is finished with the action. For
example, and interpreter asks the GUI to display an interactive file
selection dialog to obtain a file name from the user. This action must
be completed before the interpreter may continue executing.
3. The GUI asks the interpreter to perform an action and does not
need an immediate result. For example, if the user changes the current
directory through the GUI file browser widget the GUI will ask the
interpreter to execute the "cd" function. An immediate result is not
needed, so the GUI may continue to execute while this action is
performed. The interpreter will execute it separately and signal the
GUI when the action is performed so that the file browser may display
the new directory.
4. The GUI asks the interpreter to perform an action and requires an
immediate result. The GUI thread must be suspended and wait until the
interpreter thread is finished with the action. Although this type of
interaction is possible, I'm not sure what examples of it that we
currently have, or whether any that we do have could be rewritten to
behave like item 3 above so that the requested action is performed by
the interpreter and the GUI is notified of the result using a separate
signal sent from the interpreter.
For actions like items 1 and 2 above, the interpreter calls a function
in the GUI that simply emits a Qt signal that is connected to a Qt slot.
These connections are thread safe and queued if needed. (The only
reason we don't just emit the Qt signal directly from the interpreter is
to avoid making Qt a direct dependency of the interpreter.)
For actions like items 3 and 4 above, the GUI queues a function that the
interpreter will execute when it is otherwise idle.
The octave_link class is inflexible in that it declares a set of about
30 pure virtual functions that all must be defined by any GUI that
wishes to work with the GUI. So instead of allowing the GUI to
subscribe to whatever signals it chooses, it must explicitly define
functions handle (or ignore) all of them. It is also not possible for
the GUI to easily (or independently) attach multiple actions to a signal.
I am looking for alternatives to the current design of the octave_link
class. It must be thread safe and it should be easy to connect
(disconnect) signals to (from) actions. It should be possible to attach
a signal to multiple actions or to have multiple signals trigger a
single action.
This all begins to sound a lot like the Qt signal/slot mechanism,
something that we should probably not be re-inventing. However, I still
hesitate to bring that into the interpreter as it would introduce Qt as
a direct dependency of the interpreter (interpreter objects that need to
emit signals or define slots would have to inherit from the QObject
class). I would also like to allow for the possibility of other GUI
interfaces that could connect to these interpreter signals and actions
without requiring Qt.
Comments and suggestions welcome.
Yes, 3 sounds like the right idea.
My memory is the following patch is designed as such:
https://savannah.gnu.org/patch/?func=detailitem&item_id=8016#options
There shouldn't be a need to make either side of the link suspend and
wait on anything. To make the GUI wait feels unnatural. Instead, you'd
like to allow the user to edit files and whatnot when a long worker
process is running. Perhaps there might be some arrangement in which a
sequence of events has to happen in the GUI, but I'm pretty sure one can
think of a dynamic signal/slot connection to do that.
In the patch, that is the key, dynamic connections to a "queue" result.
There currently is a queuing mechanism for commands, say "cd" or "pwd".
The patch extends that idea to include a broadcaster. In the latter
command, some information is returned in an octave_value class. In the
GUI, the object that wants the information puts the command "pwd" in the
queue and dynamically makes a connection to the queue result or
"broadcast". The queue also keeps a record of the requesting object's
ID (this) so that on the return trip all the objects that may be
connected to the broadcaster can compare their "this" against the ID to
recognize, "Hey, that's my data!". Once the GUI has its data, it can
choose to disconnect so that the broadcaster doesn't get too many
subscribers--or whatever analogy one wants to use.
Dan