Last active
January 17, 2022 12:50
-
-
Save LinArcX/37eea86b43a9b2d1e6302ed2219a12fb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <list> | |
#include <memory> | |
#include "../pugixml-1.11/src/pugixml.hpp" | |
class Component { | |
std::shared_ptr<Component> parent_; | |
public: | |
Component() { } | |
virtual ~Component() {} | |
void SetParent(std::shared_ptr<Component> parent) { this->parent_ = parent; } | |
std::shared_ptr<Component> GetParent() const { return this->parent_; } | |
virtual std::string getCaption() = 0; | |
virtual bool IsComposite() const { return false; } | |
virtual void operation() = 0; | |
virtual void add(std::shared_ptr<Component>) {}; | |
virtual void remove(std::shared_ptr<Component>) {}; | |
virtual std::shared_ptr<Component> getChild(int) { return nullptr; }; | |
virtual std::vector<std::shared_ptr<Component>> children() { return{}; }; | |
}; | |
class Leaf : public Component { | |
std::string _name; | |
public: | |
Leaf(std::string name) : _name(name) { } | |
~Leaf() {} | |
std::string getCaption() { return _name; } | |
void operation() { std::cout << _name << std::endl; } | |
}; | |
class Composite : public Component { | |
std::string _caption; | |
std::vector<std::shared_ptr<Component>> _children; | |
public: | |
Composite(std::string caption) { _caption = caption; } | |
~Composite() {} | |
void add(std::shared_ptr<Component> c) { | |
_children.push_back(c); | |
c->SetParent(std::shared_ptr<Component>(this)); | |
} | |
void remove(std::shared_ptr<Component> c) { | |
for (auto iter = _children.begin(); iter != _children.end(); ++iter) { | |
if (*iter == c) { | |
_children.erase(iter); | |
c->SetParent(nullptr); | |
} | |
} | |
} | |
std::shared_ptr<Component> getChild(unsigned int idx) { | |
return idx < _children.size() ? _children[idx] : nullptr; | |
} | |
std::string getCaption() { return _caption; } | |
void operation() { std::cout << _caption << std::endl; } | |
virtual std::vector<std::shared_ptr<Component>> children() { return _children; }; | |
bool IsComposite() const override { return true; } | |
}; | |
std::shared_ptr<Component> GRANDPAPA; | |
std::shared_ptr<Component> FATHER; | |
std::shared_ptr<Component> CHILD; | |
int depth = 0; | |
void traverseXmlReturnCompsiteObject(pugi::xml_node node) | |
{ | |
// TERMINOLOGY: | |
// 1. grand-papa: a node without any father. (root element) | |
// 2. father: a node with a father and at least one child. | |
// 3. child: a node without children. | |
// CONSIDERATIONS: | |
// - for each node we should make an object. | |
// - father have their children inside themselves. | |
// - grand-papa have all the father objects and children. | |
// - at the end, grand-papa should return back. | |
// - nodes that their next_sybling() isn't null are brother/sister. They should be added to the same father. | |
// - we should keep the father of current node somehow. :/ | |
for (pugi::xml_node child : node.children()) | |
{ | |
CHILD = std::shared_ptr<Component>(new Composite(child.first_attribute().value())); | |
FATHER = std::shared_ptr<Component>(new Composite(child.parent().first_attribute().value())); | |
FATHER->add(CHILD); | |
traverseXmlReturnCompsiteObject(child); | |
} | |
} | |
std::shared_ptr<Component> parseXml() { | |
pugi::xml_document doc; | |
if (!doc.load_file("supervisor.xml")) return nullptr; | |
std::shared_ptr<Component> TREE(new Composite(doc.root().first_child().first_attribute().value())); | |
std::shared_ptr<Component> CHILDREN; | |
for (pugi::xml_node node : doc.children()) | |
{ | |
traverseXmlReturnCompsiteObject(node); | |
} | |
TREE->add(CHILDREN); | |
return TREE; | |
} | |
void showMenu(std::shared_ptr<Component> comp) | |
{ | |
if (comp->GetParent() == nullptr) { // This is our lovely grand-papa :) | |
system("cls"); | |
std::cout << comp->getCaption() << std::endl; | |
} | |
int selection = 0; | |
int lenght = static_cast<int>(comp->children().size()); | |
if (lenght) // This is a composite | |
{ | |
std::cin >> selection; | |
system("cls"); | |
if (selection == 0) | |
{ | |
comp->GetParent()->operation(); | |
showMenu(comp->GetParent()); | |
} | |
else if (selection <= lenght) | |
{ | |
comp->children()[selection - 1]->operation(); | |
showMenu(comp->children()[selection - 1]); | |
} | |
} | |
else { // This is a leaf | |
std::cin >> selection; | |
if (selection == 0) | |
{ | |
system("cls"); | |
comp->GetParent()->operation(); | |
showMenu(comp->GetParent()); | |
} | |
else { | |
showMenu(comp); | |
} | |
} | |
} | |
int main() { | |
std::shared_ptr<Component> xmlObject = parseXml(); | |
if (xmlObject) { | |
showMenu(xmlObject); | |
return 0; | |
} | |
else { | |
return -1; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment