You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.0 KiB
C++

#pragma once
#include <iostream>
#include "ifaces/INode.h"
#include "links/LeafLink.h"
#include "links/OneToManyLink.h"
#include <memory>
template <class TFinalNode>
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<TFinalNode> getShared() = 0;
NodePtr getSelf() override { return getShared(); }
private:
void lazyInit() {
if (!link_) {
link_ = std::make_shared<LeafLink>(getSelf());
}
}
void upgradeLinkIfNeeded() {
if (!std::dynamic_pointer_cast<LeafLink>(link_)) return;
auto newLink = std::make_shared<OneToManyLink>(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<OneToManyLink>(link_)) {
auto newLink = std::make_shared<LeafLink>(getSelf());
if (auto parentLink = link_->getParent()) {
parentLink->removeChild(link_);
parentLink->addChild(newLink);
}
newLink->setParent(link_->getParent());
link_ = newLink;
}
}
LinkPtr link_;
};