diff --git a/include/sdf/Param.hh b/include/sdf/Param.hh index d0a952f4c..5a6be379d 100644 --- a/include/sdf/Param.hh +++ b/include/sdf/Param.hh @@ -326,6 +326,15 @@ namespace sdf public: bool SetParentElement(ElementPtr _parentElement, sdf::Errors &_errors); + /// \brief Set the parent Element of this Param. + /// \param[in] _parentElement Pointer to new parent Element. A nullptr can + /// be provided to remove the current parent Element. + /// \param[out] _errors Vector of errors. + /// \return True if the parent Element was set and the value was reparsed + /// successfully. + public: bool SetParentElementNoReparse( + ElementPtr _parentElement); + /// \brief Reset the parameter to the default value. public: void Reset(); diff --git a/include/sdf/SDFImpl.hh b/include/sdf/SDFImpl.hh index fb7e96ea0..e4d57fc1e 100644 --- a/include/sdf/SDFImpl.hh +++ b/include/sdf/SDFImpl.hh @@ -166,8 +166,9 @@ namespace sdf class SDFORMAT_VISIBLE SDF { public: SDF(); + public: SDF(const SDF& other);//Copy constructor /// \brief Destructor - public: ~SDF(); + public: virtual ~SDF(); public: void PrintDescription(); public: void PrintDescription(sdf::Errors &_errors); public: void PrintDoc(); diff --git a/src/Element.cc b/src/Element.cc index fd8950d7f..7c95b6a9c 100644 --- a/src/Element.cc +++ b/src/Element.cc @@ -256,7 +256,7 @@ ElementPtr Element::Clone(sdf::Errors &_errors) const aiter != this->dataPtr->attributes.end(); ++aiter) { auto clonedAttribute = (*aiter)->Clone(); - SDF_ASSERT(clonedAttribute->SetParentElement(clone), + SDF_ASSERT(clonedAttribute->SetParentElementNoReparse(clone), "Cannot set parent Element of cloned attribute Param to cloned " "Element."); clone->dataPtr->attributes.push_back(clonedAttribute); @@ -279,7 +279,7 @@ ElementPtr Element::Clone(sdf::Errors &_errors) const if (this->dataPtr->value) { clone->dataPtr->value = this->dataPtr->value->Clone(); - SDF_ASSERT(clone->dataPtr->value->SetParentElement(clone), + SDF_ASSERT(clone->dataPtr->value->SetParentElementNoReparse(clone), "Cannot set parent Element of cloned value Param to cloned Element."); } diff --git a/src/Param.cc b/src/Param.cc index 2336f4296..317d47a77 100644 --- a/src/Param.cc +++ b/src/Param.cc @@ -1326,6 +1326,13 @@ bool Param::SetParentElement(ElementPtr _parentElement, sdf::Errors &_errors) return true; } +////////////////////////////////////////////////// +bool Param::SetParentElementNoReparse(ElementPtr _parentElement) +{ + this->dataPtr->parentElement = _parentElement; + return true; +} + ////////////////////////////////////////////////// void Param::Reset() { diff --git a/src/Root.cc b/src/Root.cc index 03349d2af..bd4120df8 100644 --- a/src/Root.cc +++ b/src/Root.cc @@ -213,12 +213,19 @@ Errors Root::LoadSdfString(const std::string &_sdf) return this->LoadSdfString(_sdf, ParserConfig::GlobalConfig()); } +static SDFPtr cachedRoot; +static bool cacheActive = false; + ///////////////////////////////////////////////// Errors Root::LoadSdfString(const std::string &_sdf, const ParserConfig &_config) { Errors errors; - SDFPtr sdfParsed(new SDF()); - init(sdfParsed); + if (!cacheActive) { + cacheActive = true; + cachedRoot = std::make_shared(); + init(cachedRoot); + } + SDFPtr sdfParsed = std::make_shared(*cachedRoot); // Read an SDF string, and store the result in sdfParsed. if (!readString(_sdf, _config, sdfParsed, errors)) diff --git a/src/SDF.cc b/src/SDF.cc index d9fa57dbd..87e982936 100644 --- a/src/SDF.cc +++ b/src/SDF.cc @@ -220,7 +220,10 @@ SDF::SDF() : dataPtr(new SDFPrivate) { } - +SDF::SDF(const SDF& other) +{ + this->dataPtr = std::make_unique(*other.dataPtr); +} ///////////////////////////////////////////////// SDF::~SDF() { diff --git a/src/SDFImplPrivate.hh b/src/SDFImplPrivate.hh index eefc57fcd..6d8183e07 100644 --- a/src/SDFImplPrivate.hh +++ b/src/SDFImplPrivate.hh @@ -34,7 +34,14 @@ namespace sdf { public: SDFPrivate() : root(new Element) { - }; + } + + public: SDFPrivate(const SDFPrivate& other) + { + this->path = other.path; + this->originalVersion = other.originalVersion; + this->root = other.root->Clone(); + } /// \brief Store the root element. /// \sa ElementPtr Root()