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 {
_layout->setSpacing(8);
_layout->setMargin(0);
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(propertyRemoved(AbstractProperty*, QWidget*)), this, SLOT(removeProperty(AbstractProperty*, QWidget*)));
}
......@@ -91,14 +91,18 @@ namespace campvis {
}
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.
std::map<AbstractProperty*, QWidget*>::iterator item = _widgetMap.find(const_cast<AbstractProperty*>(prop));
if (item != _widgetMap.end())
emit s_widgetVisibilityChanged(item->second, item->first->isVisible());
}
void PropertyCollectionWidget::onWidgetVisibilityChanged(QWidget* widget, bool visibility) {
widget->setVisible(visibility);
item->second->setVisible(item->first->isVisible());
}
void PropertyCollectionWidget::onPropCollectionPropAdded(AbstractProperty* prop) {
......
......@@ -72,7 +72,7 @@ namespace campvis {
/**
* 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.
......@@ -87,7 +87,7 @@ namespace campvis {
void removeProperty(AbstractProperty* prop, QWidget* widget);
signals:
void s_widgetVisibilityChanged(QWidget* widget, bool visibility);
void s_propertyVisibilityChanged(const AbstractProperty* prop);
void propertyAdded(AbstractProperty* prop);
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