Skip to content

Commit

Permalink
Refactor the std::variant way by using an template constructor choosi…
Browse files Browse the repository at this point in the history
…ng the right type
  • Loading branch information
svengoldberg committed Jan 16, 2025
1 parent 6b8166b commit e9d6cdd
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 51 deletions.
2 changes: 1 addition & 1 deletion TIGLViewer/src/ModificatorContainerWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void ModificatorContainerWidget::setSectionModificator(QList<tigl::CTiglSectionE


void ModificatorContainerWidget::setSectionsModificator(Ui::ElementModificatorInterface& element)
{
{
hideAllSpecializedWidgets();
ui->sectionsModificator->setCreateConnectedElement(element);
ui->sectionsModificator->setVisible(true);
Expand Down
25 changes: 16 additions & 9 deletions TIGLViewer/src/ModificatorManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,23 @@ void ModificatorManager::dispatch(cpcr::CPACSTreeItem* item)
tigl::CTiglUIDManager& uidManager = doc->GetConfiguration().GetUIDManager();
tigl::CTiglUIDManager::TypedPtr typePtr = uidManager.ResolveObject(bodyUID);

Ui::ElementModificatorInterface* element;
try {
element = reinterpret_cast<Ui::ElementModificatorInterface* >(typePtr.ptr);
}
catch (...) {
element = nullptr;
LOG(ERROR) << "ModificatorManager:: Unexpected sections type!";
}
auto get_element_interface = [](tigl::CTiglUIDManager::TypedPtr const& ptr) {
if (ptr.type == &typeid(tigl::CCPACSWing)) {
tigl::CCPACSWing &wing = *reinterpret_cast<tigl::CCPACSWing*>(ptr.ptr);
return Ui::ElementModificatorInterface(wing);
}
else if (ptr.type == &typeid(tigl::CCPACSFuselage)) {
tigl::CCPACSFuselage &fuselage = *reinterpret_cast<tigl::CCPACSFuselage*>(ptr.ptr);
return Ui::ElementModificatorInterface(fuselage);
}
else {
LOG(ERROR) << "ModificatorManager:: Unexpected sections type!";
return Ui::ElementModificatorInterface(tigl::CCPACSFuselage(nullptr, nullptr));
}
};

modificatorContainerWidget->setSectionsModificator(*element);
auto element = get_element_interface(typePtr);
modificatorContainerWidget->setSectionsModificator(element);
}
else if (item->getType() == "positioning" ) {
tigl::CTiglUIDManager& uidManager = doc->GetConfiguration().GetUIDManager();
Expand Down
42 changes: 5 additions & 37 deletions TIGLViewer/src/modificators/ModificatorSectionsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,7 @@ void ModificatorSectionsWidget::execNewConnectedElementDialog()
return;
}

std::vector<std::string> elementUIDs;
// Construction to 'unwrap' the std::variant createConnectedElement and apply the defined function from the correct class (which is part of the std::variant)
std::visit(
[&elementUIDs](auto& element){
elementUIDs = element.GetOrderedConnectedElement();
},
*createConnectedElement
);
std::vector<std::string> elementUIDs = createConnectedElement->GetOrderedConnectedElement();

QStringList elementUIDsQList;
for (int i = 0; i < elementUIDs.size(); i++) {
Expand All @@ -72,22 +65,10 @@ void ModificatorSectionsWidget::execNewConnectedElementDialog()
NewConnectedElementDialog::Where where = newElementDialog.getWhere();
try {
if (where == NewConnectedElementDialog::Before) {
// Construction to 'unwrap' the std::variant createConnectedElement and apply the defined function from the correct class (which is part of the std::variant)
std::visit(
[startUID](auto& element){
element.CreateNewConnectedElementBefore(startUID);
},
*createConnectedElement
);
createConnectedElement->CreateNewConnectedElementBefore(startUID);
}
else if (where == NewConnectedElementDialog::After) {
// Construction to 'unwrap' the std::variant createConnectedElement and apply the defined function from the correct class (which is part of the std::variant)
std::visit(
[startUID](auto& element){
element.CreateNewConnectedElementAfter(startUID);
},
*createConnectedElement
);
createConnectedElement->CreateNewConnectedElementAfter(startUID);
}
}
catch (const tigl::CTiglError& err) {
Expand All @@ -112,14 +93,7 @@ void ModificatorSectionsWidget::execDeleteConnectedElementDialog()
return;
}

std::vector<std::string> elementUIDs;
// Construction to 'unwrap' the std::variant createConnectedElement and apply the defined function from the correct class (which is part of the std::variant)
std::visit(
[&elementUIDs](auto& element){
elementUIDs = element.GetOrderedConnectedElement();
},
*createConnectedElement
);
std::vector<std::string> elementUIDs = createConnectedElement->GetOrderedConnectedElement();

QStringList elementUIDsQList;
for (int i = 0; i < elementUIDs.size(); i++) {
Expand All @@ -130,13 +104,7 @@ void ModificatorSectionsWidget::execDeleteConnectedElementDialog()
if (deleteDialog.exec() == QDialog::Accepted) {
QString uid = deleteDialog.getUIDToDelete();
try {
// Construction to 'unwrap' the std::variant createConnectedElement and apply the defined function from the correct class (which is part of the std::variant)
std::visit(
[uid](auto& element){
element.DeleteConnectedElement(uid.toStdString());
},
*createConnectedElement
);
createConnectedElement->DeleteConnectedElement(uid.toStdString());
}
catch (const tigl::CTiglError& err) {
TIGLViewerErrorDialog errDialog(this);
Expand Down
38 changes: 34 additions & 4 deletions TIGLViewer/src/modificators/ModificatorSectionsWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,45 @@
#define MODIFICATORSECTIONSWIDGET_H

#include <QWidget>
#include <variant>
#include <string>
#include "CCPACSFuselage.h"
#include "CCPACSWing.h"

namespace Ui
{
using ElementModificatorInterface = std::variant<tigl::CCPACSFuselage, tigl::CCPACSWing>; // could be extended by Duct, Pylon, Tank in the future

// Interface-like structure to account for different possible object types whose member variables may be adapted by the CPACSCreator.
// It is currently used for CCPACSFuselage and CCPACSWing.
// Could be extended by Duct, Pylon, Tank, etc. in the future (observe: The respective classes need to define the listed functions).
struct ElementModificatorInterface
{
// Here, functions are defined as member variables calling the 'right' (depending on present data type) function from CCPACSFuselage, CCPACSWing, etc. via lambdas
template <typename T>
ElementModificatorInterface(T&& t)
: CreateNewConnectedElementAfter(
[&t](std::string str){ return t.CreateNewConnectedElementAfter(str); }
)
, CreateNewConnectedElementBefore(
[&t](std::string str){ return t.CreateNewConnectedElementBefore(str); }
)
, CreateNewConnectedElementBetween(
[&t](std::string str1, std::string str2){ return t.CreateNewConnectedElementBetween(str1, str2); }
)
, DeleteConnectedElement(
[&t](std::string str){ return t.DeleteConnectedElement(str); }
)
, GetOrderedConnectedElement(
[&t](){ return t.GetOrderedConnectedElement(); }
)
{}

std::function<void(std::string)> CreateNewConnectedElementAfter;
std::function<void(std::string)> CreateNewConnectedElementBefore;
std::function<void(std::string, std::string)> CreateNewConnectedElementBetween;
std::function<void(std::string)> DeleteConnectedElement;
std::function<std::vector<std::string>()> GetOrderedConnectedElement;
};

class ModificatorSectionsWidget;
}

Expand All @@ -49,8 +81,6 @@ public slots:

private:
Ui::ModificatorSectionsWidget* ui;
// Defined as std::variant
// Construction is used to avoid an abstract basis class from which all possible variant types had to be inherited
Ui::ElementModificatorInterface* createConnectedElement;
};

Expand Down

0 comments on commit e9d6cdd

Please sign in to comment.