add hierarchical node

This commit is contained in:
Сергей Маринкевич
2025-07-24 15:14:08 +07:00
parent 55ef99c848
commit c228caaa45
15 changed files with 330 additions and 46 deletions
+96 -33
View File
@@ -1,63 +1,126 @@
#include "nodes/SimpleNode.h"
#include "nodes/ComplexNode.h"
#include <iostream>
#include "Logger.h"
void printTree(const MixinPtr& start, int indent = 0) {
if (!start) return;
auto startNode = std::dynamic_pointer_cast<INode>(start);
if (!startNode) return;
void printTree(const NodePtr& startNode, int indent = 0) {
if (!startNode) {
std::cout << "No node" << "\n";
return;
}
for (int i = 0; i < indent; ++i) std::cout << " ";
std::cout << startNode->name() << "\n";
LinkPtr nodeLink = startNode->getLink();
for (const auto& child : nodeLink->getChildren()) {
printTree(child, indent + 1);
auto childNode = std::dynamic_pointer_cast<INode>(child);
printTree(childNode, indent + 1);
}
}
int main2() {
std::cout << "Creatin...\n\n";
auto root = std::make_shared<SimpleNode>("Root");
std::cout << "Nice!\n\n";
return 0;
}
int main() {
std::cout << "Entering main scope...\n\n";
Logger::setMinSeverity("MAIN", Logger::Severity::Debug);
//Logger::suppressCategory("Node");
Logger::suppressCategory("Link");
Logger::suppressCategory("Mixin");
auto& logger = Logger::get("MAIN");
logger.info("Entering main scope...");
{
auto root = std::make_shared<SimpleNode>("Root");
auto child2 = std::make_shared<SimpleNode>("Child1");
auto root = std::make_shared<ComplexNode>("ComplexRoot");
auto child1 = std::make_shared<ComplexNode>("ComplexChild1");
root->linkChild(child2);
std::cout << "\nInit tree:\n\n\n";
root->linkChild(child1);
std::cout << "\nInit tree:\n";
printTree(root);
std::cout << "\n";
{
auto child1 = std::make_shared<SimpleNode>("Child2");
root->linkChild(child1);
auto subchild = std::make_shared<SimpleNode>("SubChild2");
child1->linkChild(subchild);
auto child3 = std::make_shared<SimpleNode>("Child3");
auto child2 = std::make_shared<ComplexNode>("ComplexChild2");
root->linkChild(child2);
auto subchild2 = std::make_shared<SimpleNode>("SimpleSubChild2");
child2->linkChild(subchild2);
auto child3 = std::make_shared<ComplexNode>("ComplexChild3");
root->linkChild(child3);
auto subchild2 = std::make_shared<SimpleNode>("SubChild3");
child3->linkChild(subchild2);
std::cout << "\nAnother tree:\n\n\n";
printTree(root);
auto subchild3 = std::make_shared<SimpleNode>("SimpleSubChild3");
child3->linkChild(subchild3);
std::cout << "\nUnlinking Child1...\n";
child1->unlinkParent();
std::cout << "\nTree after unlink:\n\n\n";
{
// Негативный сценарий 1: попытка добавить второй SimpleNode к ComplexNode
try {
auto anotherSimple = std::make_shared<SimpleNode>("ShouldFail");
child2->linkChild(anotherSimple);
logger.err("[ERROR] Не должно было получиться добавить второй SimpleNode к ComplexNode!");
} catch (const std::logic_error& e) {
logger.warn(std::string("[Ожидаемое исключение] ") + e.what());
}
// Негативный сценарий 2: попытка добавить ComplexNode к SimpleNode
// Это допустимо: SimpleNode может иметь ComplexNode в качестве единственного ребёнка
auto goodComplex = std::make_shared<ComplexNode>("GoodComplex");
subchild2->linkChild(goodComplex);
logger.info("[OK] ComplexNode успешно добавлен к SimpleNode как единственный ребёнок.");
// Негативный сценарий: попытка добавить второго ребёнка к SimpleNode
try {
auto anotherSimple = std::make_shared<SimpleNode>("ShouldFail2");
subchild2->linkChild(anotherSimple);
logger.err("[ERROR] Не должно было получиться добавить второго ребёнка к SimpleNode!");
} catch (const std::logic_error& e) {
logger.warn(std::string("[Ожидаемое исключение] ") + e.what());
}
// Негативный сценарий: попытка добавить SimpleNode в ComplexNode, который уже содержит несколько ComplexNode-дочерних
try {
auto badSimple = std::make_shared<SimpleNode>("BadSimple");
root->linkChild(badSimple);
logger.err("[ERROR] Не должно было получиться добавить SimpleNode в ComplexNode с несколькими ComplexNode-дочерними!");
} catch (const std::logic_error& e) {
logger.warn(std::string("[Ожидаемое исключение] ") + e.what());
}
}
std::cout << "\nAnother tree:\n";
printTree(root);
std::cout << "\n\n";
std::cout << "\n";
logger.info("Unlinking ComplexChild2...\n");
child2->unlinkParent();
std::cout << "\nTree after unlink:\n";
printTree(root);
std::cout << "\n";
logger.info("Put refs of ComplexChild2, ComplexChild3 and its children");
}
std::cout << "\nTree after scope out:\n\n\n";
std::cout << "\nTree after scope out:\n";
printTree(root);
std::cout << "\n\n";
std::cout << "\n";
logger.info("Unlinking ComplexChild1 and ComplexChild3...\n");
child1->unlinkParent();
for (auto child : root->getLink()->getChildren()) {
NodePtr childNode = std::dynamic_pointer_cast<INode>(child);
if (childNode->name() == "ComplexChild3") {
childNode->unlinkParent();
break;
}
}
auto child4 = std::make_shared<SimpleNode>("SimpleChild4");
root->linkChild(child4);
std::cout << "\nTree flush and link SimpleChild4:\n";
printTree(root);
std::cout << "\n";
}
std::cout << "\nExited main scope. All smart pointers destroyed.\n";
logger.info("Exited main scope. All smart pointers destroyed.");
return 0;
}