Skip to content

Instantly share code, notes, and snippets.

@LinArcX
Last active January 17, 2022 12:50
Show Gist options
  • Save LinArcX/37eea86b43a9b2d1e6302ed2219a12fb to your computer and use it in GitHub Desktop.
Save LinArcX/37eea86b43a9b2d1e6302ed2219a12fb to your computer and use it in GitHub Desktop.
#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