diff --git a/src/simplnx/DataStructure/BaseGroup.cpp b/src/simplnx/DataStructure/BaseGroup.cpp index a19058b4db..bae8fb2000 100644 --- a/src/simplnx/DataStructure/BaseGroup.cpp +++ b/src/simplnx/DataStructure/BaseGroup.cpp @@ -1,6 +1,7 @@ #include "BaseGroup.hpp" #include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/Utilities/StringUtilities.hpp" using namespace nx::core; @@ -21,7 +22,7 @@ BaseGroup::BaseGroup(const BaseGroup& other) { } -BaseGroup::BaseGroup(BaseGroup&& other) +BaseGroup::BaseGroup(BaseGroup&& other) noexcept : DataObject(std::move(other)) , m_DataMap(std::move(other.m_DataMap)) { @@ -105,6 +106,11 @@ bool BaseGroup::canInsert(const DataObject* obj) const { return false; } + // Do not allow adding a DataStructure to a BaseGroup + if(dynamic_cast(obj) != nullptr) + { + return false; + } if(contains(obj) || contains(obj->getName())) { return false; diff --git a/src/simplnx/DataStructure/BaseGroup.hpp b/src/simplnx/DataStructure/BaseGroup.hpp index d676f1b7be..6bb3de0600 100644 --- a/src/simplnx/DataStructure/BaseGroup.hpp +++ b/src/simplnx/DataStructure/BaseGroup.hpp @@ -67,7 +67,7 @@ class SIMPLNX_EXPORT BaseGroup : public DataObject * the provided BaseGroup. * @param other */ - BaseGroup(BaseGroup&& other); + BaseGroup(BaseGroup&& other) noexcept; /** * @brief Destroys the BaseGroup and removes it from the list of it's @@ -278,7 +278,7 @@ class SIMPLNX_EXPORT BaseGroup : public DataObject /** * @brief Clears the group of all children. */ - void clear(); + virtual void clear(); /** * @brief Returns an iterator to the beginning of the container. diff --git a/src/simplnx/DataStructure/DataObject.cpp b/src/simplnx/DataStructure/DataObject.cpp index d52f530536..26dca024dd 100644 --- a/src/simplnx/DataStructure/DataObject.cpp +++ b/src/simplnx/DataStructure/DataObject.cpp @@ -76,7 +76,7 @@ DataObject& DataObject::operator=(DataObject&& rhs) noexcept DataObject::~DataObject() noexcept { - if(m_DataStructure == nullptr) + if(m_DataStructure == nullptr || m_DataStructure == this) { return; } diff --git a/src/simplnx/DataStructure/DataStructure.cpp b/src/simplnx/DataStructure/DataStructure.cpp index 3127121bae..0fa1a685a1 100644 --- a/src/simplnx/DataStructure/DataStructure.cpp +++ b/src/simplnx/DataStructure/DataStructure.cpp @@ -29,13 +29,14 @@ const std::string k_Delimiter = "|--"; namespace nx::core { DataStructure::DataStructure() -: m_IsValid(true) +: BaseGroup(*this, k_TypeName) +, m_IsValid(true) { } DataStructure::DataStructure(const DataStructure& dataStructure) -: m_DataObjects(dataStructure.m_DataObjects) -, m_RootGroup(dataStructure.m_RootGroup) +: BaseGroup(dataStructure) +, m_DataObjects(dataStructure.m_DataObjects) , m_IsValid(dataStructure.m_IsValid) , m_NextId(dataStructure.m_NextId) { @@ -54,16 +55,16 @@ DataStructure::DataStructure(const DataStructure& dataStructure) } // Updates all DataMaps with the corresponding m_DataObjects pointers. // Updates all DataObjects with their new DataStructure - m_RootGroup.setDataStructure(this); + setDataStructure(this); } DataStructure::DataStructure(DataStructure&& dataStructure) noexcept -: m_DataObjects(std::move(dataStructure.m_DataObjects)) -, m_RootGroup(std::move(dataStructure.m_RootGroup)) +: BaseGroup(std::move(dataStructure)) +, m_DataObjects(std::move(dataStructure.m_DataObjects)) , m_IsValid(dataStructure.m_IsValid) , m_NextId(dataStructure.m_NextId) { - m_RootGroup.setDataStructure(this); + getDataMap().setDataStructure(this); } DataStructure::~DataStructure() @@ -98,7 +99,7 @@ size_t DataStructure::getSize() const void DataStructure::clear() { - auto topDataIds = m_RootGroup.getKeys(); + auto topDataIds = getDataMap().getKeys(); for(auto dataId : topDataIds) { removeData(dataId); @@ -125,7 +126,7 @@ LinkedPath DataStructure::getLinkedPath(const DataPath& path) const try { std::vector pathIds; - const DataObject* data = m_RootGroup[path[0]]; + const DataObject* data = getDataMap()[path[0]]; const BaseGroup* parent = dynamic_cast(data); pathIds.push_back(data->getId()); @@ -163,7 +164,7 @@ Result DataStructure::makePath(const DataPath& path) { std::vector pathIds; std::string name = path[0]; - const DataObject* data = m_RootGroup[name]; + const DataObject* data = getDataMap()[name]; if(data == nullptr) { data = nx::core::DataGroup::Create(*this, name); @@ -272,7 +273,7 @@ DataObject* DataStructure::getData(const DataPath& path) { return nullptr; } - DataObject* targetObject = m_RootGroup[path[0]]; + DataObject* targetObject = getDataMap()[path[0]]; for(usize index = 1; index < path.getLength(); index++) { if(targetObject == nullptr) @@ -351,7 +352,7 @@ const DataObject* DataStructure::getData(const DataPath& path) const { return nullptr; } - const DataObject* targetObject = m_RootGroup[path[0]]; + const DataObject* targetObject = getDataMap()[path[0]]; for(usize index = 1; index < path.getLength(); index++) { if(targetObject == nullptr) @@ -508,6 +509,11 @@ void DataStructure::dataDeleted(DataObject::IdType identifier, const std::string notify(msg); } +DataMap& DataStructure::getRootGroup() +{ + return getDataMap(); +} + std::vector DataStructure::getTopLevelData() const { std::vector topLevel(m_RootGroup.getSize(), nullptr); @@ -520,16 +526,6 @@ std::vector DataStructure::getTopLevelData() const return topLevel; } -const DataMap& DataStructure::getDataMap() const -{ - return m_RootGroup; -} - -DataMap& DataStructure::getRootGroup() -{ - return m_RootGroup; -} - bool DataStructure::insertTopLevel(const std::shared_ptr& obj) { if(obj == nullptr) @@ -537,18 +533,19 @@ bool DataStructure::insertTopLevel(const std::shared_ptr& obj) return false; } - if(m_RootGroup.contains(obj.get()) || m_RootGroup.contains(obj->getName())) + auto& dataMap = getDataMap(); + if(dataMap.contains(obj.get()) || dataMap.contains(obj->getName())) { return false; } - return m_RootGroup.insert(obj); + return dataMap.insert(obj); } bool DataStructure::removeTopLevel(DataObject* data) { std::string name = data->getName(); - if(!m_RootGroup.remove(data)) + if(!getDataMap().remove(data)) { return false; } @@ -585,22 +582,22 @@ bool DataStructure::finishAddingObject(const std::shared_ptr& dataOb DataStructure::Iterator DataStructure::begin() { - return m_RootGroup.begin(); + return getDataMap().begin(); } DataStructure::Iterator DataStructure::end() { - return m_RootGroup.end(); + return getDataMap().end(); } DataStructure::ConstIterator DataStructure::begin() const { - return m_RootGroup.begin(); + return getDataMap().begin(); } DataStructure::ConstIterator DataStructure::end() const { - return m_RootGroup.end(); + return getDataMap().end(); } bool DataStructure::insert(const std::shared_ptr& dataObject, const DataPath& dataPath) @@ -644,7 +641,7 @@ bool DataStructure::insertIntoRoot(const std::shared_ptr& dataObject return false; } - if(!m_RootGroup.insert(dataObject)) + if(!getDataMap().insert(dataObject)) { return false; } @@ -734,7 +731,7 @@ void DataStructure::notify(const std::shared_ptr& DataStructure& DataStructure::operator=(const DataStructure& rhs) { m_DataObjects = rhs.m_DataObjects; - m_RootGroup = rhs.m_RootGroup; + getDataMap() = rhs.getDataMap(); m_IsValid = rhs.m_IsValid; m_NextId = rhs.m_NextId; @@ -760,7 +757,7 @@ DataStructure& DataStructure::operator=(const DataStructure& rhs) DataStructure& DataStructure::operator=(DataStructure&& rhs) noexcept { m_DataObjects = std::move(rhs.m_DataObjects); - m_RootGroup = std::move(rhs.m_RootGroup); + getDataMap() = std::move(rhs.getDataMap()); m_IsValid = std::move(rhs.m_IsValid); m_NextId = std::move(rhs.m_NextId); @@ -768,9 +765,25 @@ DataStructure& DataStructure::operator=(DataStructure&& rhs) noexcept return *this; } +std::shared_ptr DataStructure::deepCopy(const DataPath& copyPath) +{ + // DataStructure cannot be contained in another DataStructure... + return nullptr; +} + +DataObject* DataStructure::shallowCopy() +{ + return new DataStructure(*this); +} + +std::string DataStructure::getTypeName() const +{ + return k_TypeName; +} + void DataStructure::applyAllDataStructure() { - m_RootGroup.setDataStructure(this); + setDataStructure(this); } nonstd::expected DataStructure::validateNumberOfTuples(const std::vector& dataPaths) const @@ -861,7 +874,7 @@ void DataStructure::resetIds(DataObject::IdType startingId) dataObjectPtr->checkUpdatedIds(updatedIdsMap); } } - m_RootGroup.updateIds(updatedIdsMap); + getDataMap().updateIds(updatedIdsMap); } void DataStructure::exportHierarchyAsGraphViz(std::ostream& outputStream) const @@ -1015,7 +1028,7 @@ Result<> DataStructure::validateGeometries() const * the compile will fail if the unit tests are enabled. Which they are on all the CI machines. */ Result<> result; - for(const auto& dataObject : m_RootGroup) + for(const auto& dataObject : getDataMap()) { auto dataObjectType = dataObject.second->getDataObjectType(); if(dataObjectType >= DataObject::Type::IGeometry && dataObjectType <= DataObject::Type::TetrahedralGeom) diff --git a/src/simplnx/DataStructure/DataStructure.hpp b/src/simplnx/DataStructure/DataStructure.hpp index 10197d7d29..5745798192 100644 --- a/src/simplnx/DataStructure/DataStructure.hpp +++ b/src/simplnx/DataStructure/DataStructure.hpp @@ -1,6 +1,7 @@ #pragma once #include "simplnx/Common/Result.hpp" +#include "simplnx/DataStructure/BaseGroup.hpp" #include "simplnx/DataStructure/DataMap.hpp" #include "simplnx/DataStructure/DataObject.hpp" #include "simplnx/DataStructure/LinkedPath.hpp" @@ -40,7 +41,7 @@ inline const std::string k_ImportableTag = "Importable"; * geometries, and scalars are added to the structure. The DataStructure allows * parents to be added to or removed from DataObjects. */ -class SIMPLNX_EXPORT DataStructure +class SIMPLNX_EXPORT DataStructure : public BaseGroup { using WeakCollectionType = std::map>; @@ -56,6 +57,8 @@ class SIMPLNX_EXPORT DataStructure bool finishAddingObject(const std::shared_ptr& obj, const std::optional& parent = {}); public: + static constexpr StringLiteral k_TypeName = "DataStructure"; + using SignalType = nod::signal&)>; using Iterator = DataMap::Iterator; using ConstIterator = DataMap::ConstIterator; @@ -95,7 +98,7 @@ class SIMPLNX_EXPORT DataStructure * @brief Clears the DataStructure by removing all DataObjects. The next * DataObject ID remains unchanged after the operation. */ - void clear(); + void clear() override; /** * @brief Returns the IdType for the DataObject found at the specified DataPath. The @@ -745,12 +748,6 @@ class SIMPLNX_EXPORT DataStructure */ std::vector getTopLevelData() const; - /** - * @brief Returns a reference to the DataMap backing the top level of the DataStructure. - * @return const DataMap& - */ - const DataMap& getDataMap() const; - /** * @brief Inserts a new DataObject into the DataStructure nested under the given * DataPath. If the DataPath is empty, the DataObject is added directly to @@ -868,6 +865,24 @@ class SIMPLNX_EXPORT DataStructure */ DataStructure& operator=(DataStructure&& rhs) noexcept; + /** + * @brief Returns a deep copy of the DataStructure. + * @return DataObject* + */ + std::shared_ptr deepCopy(const DataPath& copyPath) override; + + /** + * @brief Returns a shallow copy of the DataObject. + * @return DataObject* + */ + DataObject* shallowCopy() override; + + /** + * @brief Returns typename of the DataObject as a std::string. + * @return std::string + */ + std::string getTypeName() const override; + /** * @brief Sets the next ID to use when constructing a DataObject. * Because IDs are created to be unique, this should only be called when @@ -1025,7 +1040,6 @@ class SIMPLNX_EXPORT DataStructure // Variables SignalType m_Signal; WeakCollectionType m_DataObjects; - DataMap m_RootGroup; bool m_IsValid = false; DataObject::IdType m_NextId = 1; };