This class provides two abstract handler functions. One to handle changes of (not
necessary graphical) user interfaces L{on_gui_changed}. And another one
L{on_indiobject_changed} to handle changes of INDIobjects received from the INDI server.
It allows to detect if the method L{on_gui_changed} is in asked to be called, while the method
L{on_indiobject_changed} is running. This situation has to be take special care of, as loopbacks or data losses
are likely to happen if one does not take care.
In order to allow this mechanism to work
every function must B{not} call on_gui_changed directly, but any function may call
L{_blocking_on_gui_changed} instead. So if you are writing a custom handler please link the callback of
your GUI to L{_blocking_on_gui_changed} and implement it in L{on_gui_changed}
def indiclient.gui_indi_object_handler.on_blocked |
( |
|
self, |
|
|
|
args |
|
) |
| |
The method L{_blocking_on_gui_changed} is called by the GUI, in order to inform us, that a widget has changed.
If the blocked property is C{True}, when L{_blocking_on_gui_changed} is called by the GUI. This method (L{on_blocked}) is called and nothing else done.
The blocked property is C{True} while the L{on_indiobject_changed} function is running, so and indiobject has been received from the server
and L{on_indiobject_changed} is currently changing the widget associated with it. So there is a question: Was L{_blocking_on_gui_changed} called by the GUI?
because L{on_indiobject_changed} changed the widget or was it called because the user changed something?
Well, we don't know! And this is bad.
Because if L{on_indiobject_changed} did it and we send the new state to the server, the server will reply, which will in turn trigger
L{on_indiobject_changed} which will cause the GUI to emit another L{_blocking_on_gui_changed} signal and finally call L{on_blocked}.
This way we have generated a nasty loopback. But if we don't send the new state to the server and the change was caused by the user, the user
will see the widget in the new state, but the server will not know about it, so the user has got another idea of the status of the system than the server
and this is also quite dangerous. For the moment we print a warning and send the signal to the server, so we use the solution that might cause a loopback,
but we make sure that the GUI and the server have got the same information about the status of the devices. One possible solution to this problem that
causes neither of the problems is implemented in the L{gtkindiclient._comboboxentryhandler} class. We do no send the new state to the server. But we load the latest state
we received from the server and set the gui to this state. So the user might have clicked at a GUI element, and it might not have changed in the proper
way. We tested this for the combobox and the togglebutton and it worked.
@param args: The arguments describing the change of the GUI object(s)
@type args: list
@return: B{None}
@rtype: NoneType