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

Commit 0b1ebc43 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Implemented a real PropertyWidgetFactory where property widgets can register...

Implemented a real PropertyWidgetFactory where property widgets can register themselves together with the property type they wrap around. Registration is implemented using CRTP do allow automatic registration across DLL boundaries during static initialization time.
This commit replaces the long list of if-else in PropertyWidgetFactory with a much more generic approach.
parent 0f9b7b7f
......@@ -30,9 +30,10 @@
namespace campvis {
AbstractPropertyWidget::AbstractPropertyWidget(AbstractProperty* property, bool displayBoxed /*= false*/,
QWidget* parent /*= 0*/)
DataContainer* dataContainer /*= nullptr*/, QWidget* parent /*= 0*/)
: QWidget(parent)
, _property(property)
, _dataContainer(dataContainer)
, _layout(0)
{
_ignorePropertyUpdates = 0;
......
......@@ -33,6 +33,7 @@
namespace campvis {
class AbstractProperty;
class DataContainer;
/**
* Abstract base class for property widgets.
......@@ -46,11 +47,12 @@ namespace campvis {
*
* If displayBoxed is true, the widget is displayed vertically in a QGroupBox.
*
* \param property The property the widget shall handle
* \param property The property the widget shall handle.
* \param displayBoxed Should the widget be displayed in a group box?
* \param parent Parent Qt widget
* \param dataContainer DataContainer to use (optional), defaults to nullptr. However, some derived classed might need a valid pointer here!
* \param parent Parent Qt widget, defaults to nullptr.
*/
AbstractPropertyWidget(AbstractProperty* property, bool displayBoxed = false, QWidget* parent = 0);
AbstractPropertyWidget(AbstractProperty* property, bool displayBoxed = false, DataContainer* dataContainer = nullptr, QWidget* parent = nullptr);
/**
* Destructor
......@@ -64,6 +66,7 @@ namespace campvis {
void addWidget(QWidget* widget);
AbstractProperty* _property; ///< The property this widget handles
DataContainer* _dataContainer; ///< DataContainer to use (e.g. to populate GUI), may be 0!
/// Semaphore acts as flag whether the widget shall ignore incoming signals from properties being updated.
tbb::atomic<int> _ignorePropertyUpdates;
......
......@@ -27,8 +27,8 @@
#include <QCheckBox>
namespace campvis {
BoolPropertyWidget::BoolPropertyWidget(BoolProperty* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, parent)
BoolPropertyWidget::BoolPropertyWidget(BoolProperty* property, DataContainer* dataContainer, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, dataContainer, parent)
, _spinBox(0)
{
_spinBox = new QCheckBox(this);
......
......@@ -26,6 +26,7 @@
#define BOOLPROPERTYWIDGET_H__
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/propertywidgetfactory.h"
#include "core/properties/genericproperty.h"
class QCheckBox;
......@@ -43,7 +44,7 @@ namespace campvis {
* \param property The property the widget shall handle
* \param parent Parent Qt widget
*/
BoolPropertyWidget(BoolProperty* property, QWidget* parent = 0);
BoolPropertyWidget(BoolProperty* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
/**
* Destructor
......@@ -63,6 +64,9 @@ namespace campvis {
QCheckBox* _spinBox;
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<BoolPropertyWidget, BoolProperty>;
}
#endif // BOOLPROPERTYWIDGET_H__
......@@ -27,8 +27,8 @@
#include <QPushButton>
namespace campvis {
ButtonPropertyWidget::ButtonPropertyWidget(ButtonProperty* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, parent)
ButtonPropertyWidget::ButtonPropertyWidget(ButtonProperty* property, DataContainer* dataContainer, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, dataContainer, parent)
, _button(0)
{
_button = new QPushButton(QString::fromStdString(property->getTitle()), this);
......
......@@ -26,6 +26,7 @@
#define BUTTONPROPERTYWIDGET_H__
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/propertywidgetfactory.h"
#include "core/properties/buttonproperty.h"
class QPushButton;
......@@ -44,7 +45,7 @@ namespace campvis {
* \param property The property the widget shall handle
* \param parent Parent Qt widget
*/
ButtonPropertyWidget(ButtonProperty* property, QWidget* parent = 0);
ButtonPropertyWidget(ButtonProperty* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
/**
* Destructor
......@@ -64,6 +65,9 @@ namespace campvis {
QPushButton* _button;
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<ButtonPropertyWidget, ButtonProperty>;
}
#endif // BUTTONPROPERTYWIDGET_H__
......@@ -29,8 +29,8 @@
#include "core/tools/stringutils.h"
namespace campvis {
CameraPropertyWidget::CameraPropertyWidget(CameraProperty* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, true, parent)
CameraPropertyWidget::CameraPropertyWidget(CameraProperty* property, DataContainer* dataContainer, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, true, dataContainer, parent)
, _lblCameraPosition(0)
, _lblLookDirection(0)
, _lblUpVector(0)
......
......@@ -26,6 +26,7 @@
#define CAMERAPROPERTYWIDGET_H__
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/propertywidgetfactory.h"
#include "core/properties/cameraproperty.h"
class QLabel;
......@@ -42,9 +43,10 @@ namespace campvis {
/**
* Creates a new CameraPropertyWidget for the property \a property.
* \param property The property the widget shall handle
* \param dataContainer DataContainer to use (optional), defaults to nullptr.
* \param parent Parent Qt widget
*/
CameraPropertyWidget(CameraProperty* property, QWidget* parent = 0);
CameraPropertyWidget(CameraProperty* property, DataContainer* dataContainer, QWidget* parent = 0);
/**
* Destructor
......@@ -65,6 +67,9 @@ namespace campvis {
QLabel* _lblUpVector;
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<CameraPropertyWidget, CameraProperty>;
}
#endif // CAMERAPROPERTYWIDGET_H__
......
......@@ -31,10 +31,9 @@
namespace campvis {
DataNamePropertyWidget::DataNamePropertyWidget(DataNameProperty* property, DataContainer* dc, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, parent)
: AbstractPropertyWidget(property, false, dc, parent)
, _lineEdit(0)
, _combobox(0)
, _dc(dc)
{
if (property->getAccessInfo() == DataNameProperty::READ) {
_combobox = new QComboBox(this);
......@@ -63,8 +62,8 @@ namespace campvis {
}
DataNamePropertyWidget::~DataNamePropertyWidget() {
if (_dc != 0 && static_cast<DataNameProperty*>(_property)->getAccessInfo() == DataNameProperty::READ)
_dc->s_dataAdded.disconnect(this);
if (_dataContainer != 0 && static_cast<DataNameProperty*>(_property)->getAccessInfo() == DataNameProperty::READ)
_dataContainer->s_dataAdded.disconnect(this);
}
void DataNamePropertyWidget::updateWidgetFromProperty() {
......
......@@ -26,7 +26,9 @@
#define DATANAMEPROPERTYWIDGET_H__
#include "sigslot/sigslot.h"
#include "core/properties/datanameproperty.h"
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/propertywidgetfactory.h"
class QComboBox;
class QLineEdit;
......@@ -80,9 +82,11 @@ namespace campvis {
QLineEdit* _lineEdit;
QComboBox* _combobox;
DataContainer* _dc;
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<DataNamePropertyWidget, DataNameProperty, 10>;
}
#endif // DATANAMEPROPERTYWIDGET_H__
......@@ -25,8 +25,8 @@
#include "floatpropertywidget.h"
namespace campvis {
FloatPropertyWidget::FloatPropertyWidget(FloatProperty* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, parent)
FloatPropertyWidget::FloatPropertyWidget(FloatProperty* property, DataContainer* dataContainer, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, dataContainer, parent)
, _adjuster(0)
{
_adjuster = new DoubleAdjusterWidget();
......
......@@ -27,6 +27,7 @@
#include "application/gui/adjusterwidgets/doubleadjusterwidget.h"
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/propertywidgetfactory.h"
#include "core/properties/floatingpointproperty.h"
namespace campvis {
......@@ -40,9 +41,10 @@ namespace campvis {
/**
* Creates a new FloatPropertyWidget for the property \a property.
* \param property The property the widget shall handle
* \param dataContainer DataContainer to use (optional), defaults to nullptr.
* \param parent Parent Qt widget
*/
FloatPropertyWidget(FloatProperty* property, QWidget* parent = 0);
FloatPropertyWidget(FloatProperty* property, DataContainer* dataContainer, QWidget* parent = 0);
/**
* Destructor
......@@ -76,6 +78,9 @@ namespace campvis {
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<FloatPropertyWidget, FloatProperty>;
// ================================================================================================
namespace {
......@@ -119,7 +124,7 @@ namespace campvis {
* \param property The property the widget shall handle
* \param parent Parent Qt widget
*/
VecPropertyWidget(PropertyType* property, QWidget* parent = 0);
VecPropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
/**
* Destructor
......@@ -149,11 +154,16 @@ namespace campvis {
DoubleAdjusterWidget* _adjusters[size];
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<VecPropertyWidget<2>, typename VecPropertyWidgetTraits<2>::PropertyType>;
template class PropertyWidgetRegistrar<VecPropertyWidget<3>, typename VecPropertyWidgetTraits<3>::PropertyType>;
template class PropertyWidgetRegistrar<VecPropertyWidget<4>, typename VecPropertyWidgetTraits<4>::PropertyType>;
// ================================================================================================
template<size_t SIZE>
campvis::VecPropertyWidget<SIZE>::VecPropertyWidget(PropertyType* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, true, parent)
campvis::VecPropertyWidget<SIZE>::VecPropertyWidget(PropertyType* property, DataContainer* dataContainer, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, true, dataContainer, parent)
{
for (size_t i = 0; i < size; ++i) {
_adjusters[i] = new DoubleAdjusterWidget();
......@@ -236,8 +246,8 @@ namespace campvis {
class Vec2PropertyWidget : public VecPropertyWidget<2> {
Q_OBJECT
public:
Vec2PropertyWidget(PropertyType* property, QWidget* parent = 0)
: VecPropertyWidget<2>(property, parent)
Vec2PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
: VecPropertyWidget<2>(property, dataContainer, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_adjusters[i], SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double)));
......@@ -253,8 +263,8 @@ namespace campvis {
class Vec3PropertyWidget : public VecPropertyWidget<3> {
Q_OBJECT
public:
Vec3PropertyWidget(PropertyType* property, QWidget* parent = 0)
: VecPropertyWidget<3>(property, parent)
Vec3PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
: VecPropertyWidget<3>(property, dataContainer, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_adjusters[i], SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double)));
......@@ -270,8 +280,8 @@ namespace campvis {
class Vec4PropertyWidget : public VecPropertyWidget<4> {
Q_OBJECT
public:
Vec4PropertyWidget(PropertyType* property, QWidget* parent = 0)
: VecPropertyWidget<4>(property, parent)
Vec4PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
: VecPropertyWidget<4>(property, dataContainer, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_adjusters[i], SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double)));
......
......@@ -31,8 +31,8 @@
#include <QWidget>
namespace campvis {
IntPropertyWidget::IntPropertyWidget(IntProperty* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, parent)
IntPropertyWidget::IntPropertyWidget(IntProperty* property, DataContainer* dataContainer, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, dataContainer, parent)
, _adjuster(0)
, _timer(0)
{
......
......@@ -27,6 +27,7 @@
#include "application/gui/adjusterwidgets/intadjusterwidget.h"
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/propertywidgetfactory.h"
#include "core/properties/numericproperty.h"
class QCheckBox;
......@@ -43,10 +44,11 @@ namespace campvis {
public:
/**
* Creates a new IntPropertyWidget for the property \a property.
* \param property The property the widget shall handle
* \param parent Parent Qt widget
* \param property The property the widget shall handle
* \param dataContainer DataContainer to use (optional), defaults to nullptr.
* \param parent Parent Qt widget
*/
IntPropertyWidget(IntProperty* property, QWidget* parent = 0);
IntPropertyWidget(IntProperty* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
/**
* Destructor
......@@ -82,6 +84,9 @@ namespace campvis {
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<IntPropertyWidget, IntProperty>;
// ================================================================================================
namespace {
......@@ -125,7 +130,7 @@ namespace campvis {
* \param property The property the widget shall handle
* \param parent Parent Qt widget
*/
IVecPropertyWidget(PropertyType* property, QWidget* parent = 0);
IVecPropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
/**
* Destructor
......@@ -149,11 +154,16 @@ namespace campvis {
IntAdjusterWidget* _adjusters[size];
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<IVecPropertyWidget<2>, typename IVecPropertyWidgetTraits<2>::PropertyType>;
template class PropertyWidgetRegistrar<IVecPropertyWidget<3>, typename IVecPropertyWidgetTraits<3>::PropertyType>;
template class PropertyWidgetRegistrar<IVecPropertyWidget<4>, typename IVecPropertyWidgetTraits<4>::PropertyType>;
// ================================================================================================
template<size_t SIZE>
campvis::IVecPropertyWidget<SIZE>::IVecPropertyWidget(PropertyType* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, true, parent)
campvis::IVecPropertyWidget<SIZE>::IVecPropertyWidget(PropertyType* property, DataContainer* dataContainer, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, true, dataContainer, parent)
{
for (size_t i = 0; i < size; ++i) {
_adjusters[i] = new IntAdjusterWidget;
......@@ -221,8 +231,8 @@ namespace campvis {
class IVec2PropertyWidget : public IVecPropertyWidget<2> {
Q_OBJECT
public:
IVec2PropertyWidget(PropertyType* property, QWidget* parent = 0)
: IVecPropertyWidget<2>(property, parent)
IVec2PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
: IVecPropertyWidget<2>(property, dataContainer, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_adjusters[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
......@@ -238,8 +248,8 @@ namespace campvis {
class IVec3PropertyWidget : public IVecPropertyWidget<3> {
Q_OBJECT
public:
IVec3PropertyWidget(PropertyType* property, QWidget* parent = 0)
: IVecPropertyWidget<3>(property, parent)
IVec3PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
: IVecPropertyWidget<3>(property, dataContainer, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_adjusters[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
......@@ -255,8 +265,8 @@ namespace campvis {
class IVec4PropertyWidget : public IVecPropertyWidget<4> {
Q_OBJECT
public:
IVec4PropertyWidget(PropertyType* property, QWidget* parent = 0)
: IVecPropertyWidget<4>(property, parent)
IVec4PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
: IVecPropertyWidget<4>(property, dataContainer, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_adjusters[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
......
......@@ -27,14 +27,13 @@
namespace campvis {
MetaPropertyWidget::MetaPropertyWidget(MetaProperty* property, DataContainer* dc, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, true, parent)
: AbstractPropertyWidget(property, true, dc, parent)
, _pcw(0)
, _dc(dc)
{
tgtAssert(_dc != 0, "Pointer to DataContainer must not be 0.");
tgtAssert(_dataContainer != 0, "Pointer to DataContainer must not be 0.");
_pcw = new PropertyCollectionWidget(this);
_pcw->updatePropCollection(property, _dc);
_pcw->updatePropCollection(property, _dataContainer);
addWidget(_pcw);
}
......
......@@ -26,9 +26,10 @@
#define METAPROPERTYWIDGET_H__
#include "application/gui/properties/propertycollectionwidget.h"
#include "application/gui/properties/abstractpropertywidget.h"
#include "core/properties/metaproperty.h"
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/propertycollectionwidget.h"
#include "application/gui/properties/propertywidgetfactory.h"
namespace campvis {
class DataContainer;
......@@ -43,10 +44,11 @@ namespace campvis {
public:
/**
* Creates a new MetaPropertyWidget for the property \a property.
* \param property The property the widget shall handle
* \param parent Parent Qt widget
* \param property The property the widget shall handle
* \param dataContainer DataContainer to use, must not be 0.
* \param parent Parent Qt widget
*/
MetaPropertyWidget(MetaProperty* property, DataContainer* dc, QWidget* parent = 0);
MetaPropertyWidget(MetaProperty* property, DataContainer* dataContainer, QWidget* parent = 0);
/**
* Destructor
......@@ -62,9 +64,11 @@ namespace campvis {
private:
PropertyCollectionWidget* _pcw;
DataContainer* _dc;
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<MetaPropertyWidget, MetaProperty>;
}
#endif // METAPROPERTYWIDGET_H__
......@@ -28,8 +28,8 @@
#include "core/properties/optionproperty.h"
namespace campvis {
OptionPropertyWidget::OptionPropertyWidget(AbstractOptionProperty* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, parent)
OptionPropertyWidget::OptionPropertyWidget(AbstractOptionProperty* property, DataContainer* dataContainer /*= nullptr*/, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, false, dataContainer, parent)
, _comboBox(0)
{
_comboBox = new QComboBox(this);
......
......@@ -26,6 +26,7 @@
#define OPTIONPROPERTYWIDGET_H__
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/propertywidgetfactory.h"
#include "core/properties/optionproperty.h"
class QComboBox;
......@@ -42,10 +43,11 @@ namespace campvis {
public:
/**
* Creates a new OptionPropertyWidget for the property \a property.
* \param property The property the widget shall handle
* \param parent Parent Qt widget
* \param property The property the widget shall handle
* \param dataContainer DataContainer to use (optional), defaults to nullptr.
* \param parent Parent Qt widget
*/
OptionPropertyWidget(AbstractOptionProperty* property, QWidget* parent = 0);
OptionPropertyWidget(AbstractOptionProperty* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
/**
* Destructor
......@@ -66,5 +68,7 @@ namespace campvis {
};
// explicitly instantiate template, so that it gets registered also over DLL boundaries.
template class PropertyWidgetRegistrar<OptionPropertyWidget, AbstractOptionProperty, 10>;
}
#endif // OPTIONPROPERTYWIDGET_H__
......@@ -111,7 +111,7 @@ namespace campvis {
}
void PropertyCollectionWidget::addProperty(AbstractProperty* prop) {
QWidget* propWidget = PropertyWidgetFactory::createWidget(prop, _dataContainer);
QWidget* propWidget = PropertyWidgetFactory::getRef().createWidget(prop, _dataContainer);
if (propWidget == 0)
propWidget = new QPushButton(QString::fromStdString(prop->getTitle()));
......
......@@ -24,91 +24,64 @@
#include "propertywidgetfactory.h"
#include "application/gui/properties/abstractpropertywidget.h"
#include "application/gui/properties/buttonpropertywidget.h"
#include "application/gui/properties/boolpropertywidget.h"
#include "application/gui/properties/camerapropertywidget.h"
#include "application/gui/properties/datanamepropertywidget.h"
#include "application/gui/properties/intpropertywidget.h"
#include "application/gui/properties/floatpropertywidget.h"
#include "application/gui/properties/metapropertywidget.h"
#include "application/gui/properties/optionpropertywidget.h"
#include "application/gui/properties/stringpropertywidget.h"
#include "application/gui/properties/transferfunctionpropertywidget.h"
#include "core/datastructures/datacontainer.h"
#include "core/properties/abstractproperty.h"
#include "core/properties/cameraproperty.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/genericproperty.h"
#include "core/properties/optionproperty.h"
#include "core/properties/transferfunctionproperty.h"
#include <functional>
namespace campvis {
AbstractPropertyWidget* PropertyWidgetFactory::createWidget(AbstractProperty* property, DataContainer* dc) {
tgtAssert(property != 0, "Property must not be 0.");
tbb::atomic<PropertyWidgetFactory*> PropertyWidgetFactory::_singleton;
if (BoolProperty* tester = dynamic_cast<BoolProperty*>(property)) {
return new BoolPropertyWidget(tester);
}
if (ButtonProperty* tester = dynamic_cast<ButtonProperty*>(property)) {
return new ButtonPropertyWidget(tester);
PropertyWidgetFactory& PropertyWidgetFactory::getRef() {
if (_singleton == 0) {
std::cout << "creating PropertyWidgetFactory...\n";
PropertyWidgetFactory* tmp = new PropertyWidgetFactory();
if (_singleton.compare_and_swap(tmp, 0) != 0) {
delete tmp;
}
}
// OptionProperty must test before IntProperty
if (AbstractOptionProperty* tester = dynamic_cast<AbstractOptionProperty*>(property)) {
return new OptionPropertyWidget(tester);
}
return *_singleton;
}
if (IntProperty* tester = dynamic_cast<IntProperty*>(property)) {
return new IntPropertyWidget(tester);
}
if (IVec2Property* tester = dynamic_cast<IVec2Property*>(property)) {
return new IVec2PropertyWidget(tester);
}
if (IVec3Property* tester = dynamic_cast<IVec3Property*>(property)) {
return new IVec3PropertyWidget(tester);
}
if (IVec4Property* tester = dynamic_cast<IVec4Property*>(property)) {
return new IVec4PropertyWidget(tester);
}
void PropertyWidgetFactory::deinit() {
delete _singleton;
_singleton = nullptr;