#pragma once #include #include #include "ifaces/ILinkMixin.h" #include "ifaces/INode.h" #include "Logger.h" /// \brief Базовый миксин для реализации ILinkMixin для INode. /// Предоставляет базовую реализацию методов для работы с дочерними узлами и родителем. class BaseLinkMixin : public virtual ILinkMixin, public std::enable_shared_from_this> { using ElemPtr = std::shared_ptr; public: ~BaseLinkMixin() override { Logger::get("ConDes").dbg("--- Destructor called for: BaseLinkMixin"); } operator std::shared_ptr() override { return this->getNode(); } void linkChild(const ElemPtr& child) override { getLink()->addChild(child); auto childLink = child->getLink(); childLink->setParent(getNode()); } void unlinkParent() override { auto link = getLink(); ElemPtr parent = link->getParent(); if (!parent) throw std::logic_error("Have no parent!"); auto parentLink = parent->getLink(); /* NOTE: * * Keep a reference to the node we gonna to unlink. * Otherwise, we'll disappear between `removeChild` and * `setParent`. Do not rearrange these calls, because * we want to modify the tree top down. */ auto node = getNode(); parentLink->removeChild(node); getLink()->setParent(nullptr); } ElemPtr parent() override { auto link = getLink(); ElemPtr parent = link->getParent(); return parent; } const std::vector& children() override { auto link = getLink(); return link->getChildren(); } protected: ElemPtr getNode() { return std::dynamic_pointer_cast(shared_from_this()); } };