ModelElement should be an abstract base rather than holding an element

ModelElement::getBody didn't check for null m_data
ArchicadElementDBaseEngine should default to returning GenericModelElement is type is unknown
This commit is contained in:
Ralph Wessel
2024-10-24 09:24:01 +01:00
parent 8893653583
commit f72d5202f9
3 changed files with 7 additions and 68 deletions
@@ -12,7 +12,7 @@
#include "Speckle/Event/Type/ProjectEvent.h"
#include "Speckle/Record/Element/Column.h"
#include "Speckle/Record/Element/ColumnSegment.h"
#include "Speckle/Record/Element/ModelElement.h"
#include "Speckle/Record/Element/GenericModelElement.h"
#include "Speckle/Record/Element/Beam.h"
#include "Speckle/Record/Element/BeamSegment.h"
#include "Speckle/Record/Element/Memo.h"
@@ -83,7 +83,7 @@ namespace {
case API_BeamSegmentID:
return std::make_unique<BeamSegment>(elementData, tableID);
default:
return std::make_unique<ModelElement>(elementData, tableID);
return std::make_unique<GenericModelElement>(elementData, tableID);
}
}
}
@@ -37,12 +37,11 @@ namespace speckle::record::element {
friend class ModelElement;
#ifdef ARCHICAD
Data(const API_Element& elem) : root{ std::make_unique<API_Element>(elem) } {}
Data(const Data& source) : root{ std::make_unique<API_Element>(*source.root) } {}
Data() {}
Data(const Data& source) : m_cache{std::make_unique<ModelElement::Body>(*source.m_cache)} {}
#endif
private:
std::unique_ptr<API_Element> root;
std::unique_ptr<ModelElement::Body> m_cache;
};
@@ -82,17 +81,6 @@ ModelElement::ModelElement(const Guid& ID, const Guid& tableID, std::optional<Le
} //ModelElement::ModelElement
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The attribute table ID (attribute type)
--------------------------------------------------------------------*/
ModelElement::ModelElement(const API_Element& elemData, const Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData);
} //ModelElement::ModelElement
/*--------------------------------------------------------------------
Copy constructor
@@ -116,7 +104,7 @@ ModelElement::~ModelElement() {}
--------------------------------------------------------------------*/
ModelElement::Body* ModelElement::getBody() const {
#ifdef ARCHICAD
if (m_data->m_cache) {
if (m_data && m_data->m_cache) {
return m_data->m_cache.get();
}
@@ -199,34 +187,13 @@ ModelElement::Body* ModelElement::getBody() const {
{
elementBody->push_back(std::move(mesh));
}
m_data = std::make_unique<Data>();
m_data->m_cache.reset(elementBody);
return m_data->m_cache.get();
#endif
} //ModelElement::getBody
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Get the (immutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& ModelElement::getHead() const {
return m_data->root->header;
} //ModelElement::getHead
/*--------------------------------------------------------------------
Get the (mutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& ModelElement::getHead() {
return m_data->root->header;
} //ModelElement::getHead
#endif
/*--------------------------------------------------------------------
Fill an inventory with the package items
@@ -42,14 +42,6 @@ namespace speckle::record::element {
*/
ModelElement(const speckle::utility::Guid& ID, const speckle::utility::Guid& tableID,
std::optional<active::measure::LengthType> unit = active::measure::LengthType::metre);
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
ModelElement(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
@@ -60,12 +52,6 @@ namespace speckle::record::element {
*/
~ModelElement();
/*!
Object cloning
@return A clone of this object
*/
ModelElement* clonePtr() const override { return new ModelElement{*this}; }
// MARK: - Functions (const)
@@ -74,23 +60,9 @@ namespace speckle::record::element {
@return An array of meshes from the element body (nullptr if no body data is available)
*/
virtual Body* getBody() const;
#ifdef ARCHICAD
/*!
Get the (immutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
virtual const API_Elem_Head& getHead() const override;
#endif
// MARK: - Functions (mutating)
#ifdef ARCHICAD
/*!
Get the (mutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
virtual API_Elem_Head& getHead() override;
#endif
// MARK: - Serialisation
@@ -114,7 +86,7 @@ namespace speckle::record::element {
private:
class Data;
///The element data
std::unique_ptr<Data> m_data;
mutable std::unique_ptr<Data> m_data;
};
}