2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 02a36abc authored by Declara Denis's avatar Declara Denis Committed by Christian Schulte zu Berge
Browse files

Fixed Concurrency Bug in PropertyCollectionWidget

When rapidly switching between processors in the tree view, the
PropertyCollectionWidgets would sometimes cause the program to crash. This
happened because some signals originated from a different Thread and
sometimes caused a user-after-free error on the widget objects.
parent baebd055
...@@ -71,7 +71,7 @@ namespace campvis { ...@@ -71,7 +71,7 @@ namespace campvis {
_layout->setSpacing(8); _layout->setSpacing(8);
_layout->setMargin(0); _layout->setMargin(0);
setLayout(_layout); setLayout(_layout);
connect(this, SIGNAL(s_widgetVisibilityChanged(QWidget*, bool)), this, SLOT(onWidgetVisibilityChanged(QWidget*, bool))); connect(this, SIGNAL(s_propertyVisibilityChanged(const AbstractProperty*)), this, SLOT(onWidgetVisibilityChanged(const AbstractProperty*)), Qt::QueuedConnection);
connect(this, SIGNAL(propertyAdded(AbstractProperty*)), this, SLOT(addProperty(AbstractProperty*))); connect(this, SIGNAL(propertyAdded(AbstractProperty*)), this, SLOT(addProperty(AbstractProperty*)));
connect(this, SIGNAL(propertyRemoved(AbstractProperty*, QWidget*)), this, SLOT(removeProperty(AbstractProperty*, QWidget*))); connect(this, SIGNAL(propertyRemoved(AbstractProperty*, QWidget*)), this, SLOT(removeProperty(AbstractProperty*, QWidget*)));
} }
...@@ -91,14 +91,18 @@ namespace campvis { ...@@ -91,14 +91,18 @@ namespace campvis {
} }
void PropertyCollectionWidget::onPropertyVisibilityChanged(const AbstractProperty* prop) { void PropertyCollectionWidget::onPropertyVisibilityChanged(const AbstractProperty* prop) {
// This method is not always called on the main thread, so it is not safe to check anything here.
// The event is instead forwarded using the QT sigslot mechanism through a queued connection to the
// main thread.
emit s_propertyVisibilityChanged(prop);
}
void PropertyCollectionWidget::onWidgetVisibilityChanged(const AbstractProperty* prop) {
// const_cast does not harm anything. // const_cast does not harm anything.
std::map<AbstractProperty*, QWidget*>::iterator item = _widgetMap.find(const_cast<AbstractProperty*>(prop)); std::map<AbstractProperty*, QWidget*>::iterator item = _widgetMap.find(const_cast<AbstractProperty*>(prop));
if (item != _widgetMap.end()) if (item != _widgetMap.end())
emit s_widgetVisibilityChanged(item->second, item->first->isVisible()); item->second->setVisible(item->first->isVisible());
}
void PropertyCollectionWidget::onWidgetVisibilityChanged(QWidget* widget, bool visibility) {
widget->setVisible(visibility);
} }
void PropertyCollectionWidget::onPropCollectionPropAdded(AbstractProperty* prop) { void PropertyCollectionWidget::onPropCollectionPropAdded(AbstractProperty* prop) {
......
...@@ -72,7 +72,7 @@ namespace campvis { ...@@ -72,7 +72,7 @@ namespace campvis {
/** /**
* Gets called when the property has changed, so that widget can update its state. * Gets called when the property has changed, so that widget can update its state.
*/ */
virtual void onWidgetVisibilityChanged(QWidget* widget, bool visibility); virtual void onWidgetVisibilityChanged(const AbstractProperty* prop);
/** /**
* Creates the property widget for \a prop, connects all neccesary signals, etc. * Creates the property widget for \a prop, connects all neccesary signals, etc.
...@@ -87,7 +87,7 @@ namespace campvis { ...@@ -87,7 +87,7 @@ namespace campvis {
void removeProperty(AbstractProperty* prop, QWidget* widget); void removeProperty(AbstractProperty* prop, QWidget* widget);
signals: signals:
void s_widgetVisibilityChanged(QWidget* widget, bool visibility); void s_propertyVisibilityChanged(const AbstractProperty* prop);
void propertyAdded(AbstractProperty* prop); void propertyAdded(AbstractProperty* prop);
void propertyRemoved(AbstractProperty* prop, QWidget* widget); void propertyRemoved(AbstractProperty* prop, QWidget* widget);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment