#pragma once #include #include "ifaces/INode.h" #include "links/LeafLink.h" #include "links/OneToManyLink.h" #include template class LazyLinkMixin : public INode { public: void linkChild(const NodePtr& childNode) override { lazyInit(); upgradeLinkIfNeeded(); LinkPtr childLink = childNode->getLink(); childLink->setParent(link_); link_->addChild(childLink); } void unlinkParent() override { lazyInit(); LinkPtr parentLink = link_->getParent(); if (!parentLink) return; parentLink->removeChild(this->getLink()); link_->setParent(nullptr); } LinkPtr getLink() override { lazyInit(); return link_; } ~LazyLinkMixin() override { std::cout << "--- Destructor called for: " << "LazyLinkMixin" << "\n"; } protected: virtual std::shared_ptr getShared() = 0; NodePtr getSelf() override { return getShared(); } private: void lazyInit() { if (!link_) { link_ = std::make_shared(getSelf()); } } void upgradeLinkIfNeeded() { if (!std::dynamic_pointer_cast(link_)) return; auto newLink = std::make_shared(getSelf()); if (auto parentLink = link_->getParent()) { parentLink->removeChild(link_); parentLink->addChild(newLink); } newLink->setParent(link_->getParent()); link_ = newLink; } void downgradeLinkIfPossible() { if (link_->getChildren().empty() && std::dynamic_pointer_cast(link_)) { auto newLink = std::make_shared(getSelf()); if (auto parentLink = link_->getParent()) { parentLink->removeChild(link_); parentLink->addChild(newLink); } newLink->setParent(link_->getParent()); link_ = newLink; } } LinkPtr link_; };