Mercurial > octave
changeset 28395:a379987a74b0 stable
Make sure Objects and their proxy are initialized synchronously (bug #55225)
* qt-graphics-toolkit.cc (qt_graphics_toolkit::qt_graphics_toolkit): use
Qt::BlockingQueuedConnection to make sure the Object proxy "init" method
has been called when we return.
* ObjectProxy.h (sendFinalize, sendPrint): remove unused signals.
* ObjectProxy.cc (ObjectProxy::ObjectProxy): Remove connections to slotPrint,
and slotFinalize.
(ObjectProxy::print): Use QMetaObject::invokeMethod with a
Qt::BlockingQueuedConnection to execute slotPrint. Raise an error if either
the GUI Object is not valid or invokeMethod failed.
(ObjectProxy::finalize): Raise an error if either the GUI Object is not valid
or invokeMethod failed.
(ObjectProxy::get_pixels): Raise an error if the GUI Object is not valid.
(ObjectProxy::setObject): Only call finalize with a valid GUI Object.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Tue, 26 May 2020 09:42:06 +0200 |
parents | 0824d92a449d |
children | 4ea54a38c500 2a0e566a03e1 |
files | libgui/graphics/ObjectProxy.cc libgui/graphics/ObjectProxy.h libgui/graphics/qt-graphics-toolkit.cc |
diffstat | 3 files changed, 28 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/graphics/ObjectProxy.cc Mon Jun 01 23:37:34 2020 +0200 +++ b/libgui/graphics/ObjectProxy.cc Tue May 26 09:42:06 2020 +0200 @@ -55,14 +55,10 @@ { disconnect (this, SIGNAL (sendUpdate (int)), m_object, SLOT (slotUpdate (int))); - disconnect (this, SIGNAL (sendFinalize (void)), - m_object, SLOT (slotFinalize (void))); disconnect (this, SIGNAL (sendRedraw (void)), m_object, SLOT (slotRedraw (void))); disconnect (this, SIGNAL (sendShow (void)), m_object, SLOT (slotShow (void))); - disconnect (this, SIGNAL (sendPrint (const QString&, const QString&)), - m_object, SLOT (slotPrint (const QString&, const QString&))); } m_object = obj; @@ -71,15 +67,10 @@ { connect (this, SIGNAL (sendUpdate (int)), m_object, SLOT (slotUpdate (int))); - connect (this, SIGNAL (sendFinalize (void)), - m_object, SLOT (slotFinalize (void))); connect (this, SIGNAL (sendRedraw (void)), m_object, SLOT (slotRedraw (void))); connect (this, SIGNAL (sendShow (void)), m_object, SLOT (slotShow (void))); - connect (this, SIGNAL (sendPrint (const QString&, const QString&)), - m_object, SLOT (slotPrint (const QString&, const QString&)), - Qt::BlockingQueuedConnection); } } } @@ -87,7 +78,10 @@ void ObjectProxy::setObject (Object *obj) { - finalize (); + // Eventually destroy previous Object + if (m_object) + finalize (); + init (obj); } @@ -101,14 +95,15 @@ ObjectProxy::finalize (void) { if (! m_object) - return; + error ("ObjectProxy::finalize: invalid GUI Object"); Qt::ConnectionType t = Qt::BlockingQueuedConnection; if (QThread::currentThread () == QCoreApplication::instance ()->thread ()) t = Qt::DirectConnection; - QMetaObject::invokeMethod (m_object, "slotFinalize", t); + if (! QMetaObject::invokeMethod (m_object, "slotFinalize", t)) + error ("ObjectProxy::finalize: unable to delete GUI Object"); } void @@ -126,12 +121,26 @@ void ObjectProxy::print (const QString& file_cmd, const QString& term) { - emit sendPrint (file_cmd, term); + if (! m_object) + error ("ObjectProxy::print: invalid GUI Object"); + + Qt::ConnectionType t = Qt::BlockingQueuedConnection; + + if (QThread::currentThread () == QCoreApplication::instance ()->thread ()) + t = Qt::DirectConnection; + + if (! QMetaObject::invokeMethod (m_object, "slotPrint", t, + Q_ARG (QString, file_cmd), + Q_ARG (QString, term))) + error ("ObjectProxy::print: unable to print figure"); } uint8NDArray ObjectProxy::get_pixels (void) { + if (! m_object) + error ("ObjectProxy::finalize: invalid GUI Object"); + uint8NDArray retval; // The ObjectProxy is generally ran from the interpreter thread
--- a/libgui/graphics/ObjectProxy.h Mon Jun 01 23:37:34 2020 +0200 +++ b/libgui/graphics/ObjectProxy.h Tue May 26 09:42:06 2020 +0200 @@ -56,10 +56,8 @@ signals: void sendUpdate (int pId); - void sendFinalize (void); void sendRedraw (void); void sendShow (void); - void sendPrint (const QString& file_cmd, const QString& term); private: void init (Object *obj);
--- a/libgui/graphics/qt-graphics-toolkit.cc Mon Jun 01 23:37:34 2020 +0200 +++ b/libgui/graphics/qt-graphics-toolkit.cc Tue May 26 09:42:06 2020 +0200 @@ -107,9 +107,14 @@ // cross from the interpreter thread (where requests to create // graphics object are initiated) to the GUI application thread // (where they are actually created and displayed). + // We need to make sure the GUI Object and its proxy are properly + // created before the initialize method returns, so we use a + // BlockingQueuedConnection. After the signal is emitted, the interpreter + // thread is locked until the slot has returned. connect (this, SIGNAL (create_object_signal (double)), - this, SLOT (create_object (double))); + this, SLOT (create_object (double)), + Qt::BlockingQueuedConnection); } bool