Skip to content

Question/Discussion: Is passing concrete types as parent pointers a good idea? #62

@joergbrech

Description

@joergbrech

There are a few generic types in CPACS, such as the StringVectorType or the TransformationType, that are used all over the place. Everytime we add a new CPACSNode that depends on a generic type, the generic type must be modified to accomodate for the new possible parent it can have.

Here is a simplified example:

struct CPACSWing;
struct CPACSFuselage;
struct CPACSTransformation
{
    CPACSTransformation(CPACSWing* parent) {}
    CPACSTransformation(CPACSFuselage* parent) {}
};

struct CPACSWing
{
    CPACSWing() : m_trafo(this) {}
    CPACSTransformation m_trafo;
};

struct CPACSFuselage
{
    CPACSFuselage() : m_trafo(this) {}
    CPACSTransformation m_trafo;
};

If I were to define a new CPACSFlyingSaucer with a transformation, I need to add an according constructor to CPACSTransformation. This is done for the generated class automatically, but since we customize CPACSTransformation in TiGL, we have to manually modify the CCPACSTransformation class.

In fact, adding/modifying/deleting constructors in customized classes is something we encounter frequently when CPACS changes. Additionally, to me it seems like a design issue that CPACSTransformation needs to know about CPACSFuselage, CPACSWing and CPACSFlyingSaucer. Finally, the information about the concrete type of the parent is lost anyway because the parent pointer is stored in a (scary) void pointer:

https://github.com/DLR-SC/tigl/blob/2ac52417007fa981c757fa3e3fbe18bd40e8d35d/src/generated/CPACSTransformation.h#L168

Proposal

We could introduce a CPACSNode class as a base class for all CPACS nodes, that

  • manages the parent-child relations of the CPACS tree
  • optionally stores some type information, like std::type_info or similar.

That way, the generic CPACS types only know of their parent as a CPACSNode, not the concrete derived type.

Here is a simplified example:

struct CPACSNode
{
    CPACSNode(CPACSNode* parent = nullptr) : m_parent(parent) {}
    CPACSNode* m_parent;
    // optional: type info
};


struct CPACSTransformation : public CPACSNode
{
    CPACSTransformation(CPACSNode* parent) : CPACSNode(parent) {}
};

struct CPACSWing : public CPACSNode
{
    CPACSWing() : m_trafo(this) {}
    CPACSTransformation m_trafo;
};

struct CPACSFuselage : public CPACSNode
{
    CPACSFuselage() : m_trafo(this) {}
    CPACSTransformation m_trafo;
};

@RlanderRISCSW, @MarAlder, @merakulix, @svengoldberg, @sdeinert, @AntonReiswich: What do you guys think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions