From 71ce85cec449e5757bd61d87fd8a941bae67fa7a Mon Sep 17 00:00:00 2001 From: trotFunky Date: Thu, 16 May 2019 01:16:19 +0200 Subject: [PATCH] Continuing vector graphics exercise New classes : - DrawingElement (Base class for every other element) - Group : Groups DrawingElements together Modified Circle to work with DrawingElement Corrected a *maybe* failed vector copy in Polynomial.tpp --- snippets/CMakeLists.txt | 7 ++- snippets/Circle.cpp | 39 ++++++++++-- snippets/Circle.h | 17 ++++-- snippets/DrawingElement.cpp | 103 ++++++++++++++++++++++++++++++++ snippets/DrawingElement.h | 45 ++++++++++++++ snippets/Group.cpp | 65 ++++++++++++++++++++ snippets/Group.h | 38 ++++++++++++ snippets/Polynomial.tpp | 6 ++ snippets/gTestXMLParser.cpp | 114 +++++++++++++++++++++++++++++++----- 9 files changed, 405 insertions(+), 29 deletions(-) create mode 100644 snippets/DrawingElement.cpp create mode 100644 snippets/DrawingElement.h create mode 100644 snippets/Group.cpp create mode 100644 snippets/Group.h diff --git a/snippets/CMakeLists.txt b/snippets/CMakeLists.txt index 9ebb729..c81bfaf 100644 --- a/snippets/CMakeLists.txt +++ b/snippets/CMakeLists.txt @@ -39,7 +39,8 @@ endif() add_executable(compte_mots compte_mots.cpp) -add_executable(parseXML xmlParser.cpp xmlParser.h Circle.h Circle.cpp) +add_executable(parseXML xmlParser.cpp xmlParser.h Circle.h Circle.cpp Group.cpp Group.h DrawingElement.cpp DrawingElement.h DrawingElement.cpp) +target_link_libraries(parseXML sfml-window sfml-graphics) find_path(PugiXML_INCLUDE_DIR pugixml.hpp) target_link_libraries(parseXML pugixml) @@ -48,7 +49,9 @@ target_link_directories(parseXML PRIVATE ${PugiXML_INCLUDE_DIR}) if(GTest_FOUND) - add_executable(xmlTest gTestXMLParser.cpp Circle.h xmlParser.h xmlParser.cpp Circle.cpp) + add_executable(xmlTest gTestXMLParser.cpp Circle.h xmlParser.h xmlParser.cpp Circle.cpp Group.cpp Group.h DrawingElement.cpp DrawingElement.h DrawingElement.cpp) + + target_link_libraries(xmlTest sfml-window sfml-graphics) target_include_directories(xmlTest PRIVATE ${PugiXML_INCLUDE_DIR}) target_link_directories(xmlTest PRIVATE ${PugiXML_INCLUDE_DIR}) diff --git a/snippets/Circle.cpp b/snippets/Circle.cpp index 8b2243c..a8d60ee 100644 --- a/snippets/Circle.cpp +++ b/snippets/Circle.cpp @@ -6,10 +6,39 @@ namespace xmlParser { - Circle::Circle() : x(0), y(1), r(2), label("Test circle") - {} - Circle::Circle(pugi::xml_node& node) : x(node.attribute("x").as_int(0)), y(node.attribute("y").as_int(1)), - r(node.attribute("r").as_int(2)), label(node.attribute("label").as_string("Test circle")) - {} + Circle::Circle() : DrawingElement(), r(2) + { + label = "Test Circle"; + shape = new sf::CircleShape(r); + shape->setPosition(x,y); + shape->setFillColor(color); + } + + Circle::Circle(const pugi::xml_node& node) : DrawingElement(node), r(node.attribute("r").as_int(2)) + { + if(label == "Test DrawingElement") + { + label = "Test Circle"; + } + shape = new sf::CircleShape(r); + shape->setPosition(x,y); + shape->setFillColor(color); + } + + void Circle::draw(sf::RenderWindow& window) + { + window.draw(*(dynamic_cast(shape))); + } + + int Circle::getR() const + { + return r; + } + + void Circle::setR(int newR) + { + r = newR; + dynamic_cast(shape)->setRadius(r); + } } \ No newline at end of file diff --git a/snippets/Circle.h b/snippets/Circle.h index 2a90cab..4b362ff 100644 --- a/snippets/Circle.h +++ b/snippets/Circle.h @@ -7,20 +7,25 @@ #include #include +#include + +#include "DrawingElement.h" namespace xmlParser { - class Circle + class Circle : public DrawingElement { public: Circle(); - explicit Circle(pugi::xml_node&); + explicit Circle(const pugi::xml_node&); - int x; - int y; + void draw(sf::RenderWindow&) override; + + int getR() const; + void setR(int newR); + + private: int r; - - std::string label; }; } #endif //SNIPPETS_CIRCLE_H diff --git a/snippets/DrawingElement.cpp b/snippets/DrawingElement.cpp new file mode 100644 index 0000000..1b6bccc --- /dev/null +++ b/snippets/DrawingElement.cpp @@ -0,0 +1,103 @@ +// +// Created by trotfunky on 15/05/19. +// + +#include "DrawingElement.h" + + +namespace xmlParser +{ + DrawingElement::DrawingElement() : x(0), y(1), label("Test DrawingElement"), color(sf::Color::Yellow), shape(nullptr) + {} + + DrawingElement::DrawingElement(const pugi::xml_node& node) : x(node.attribute("x").as_int(0)), + y(node.attribute("y").as_int(1)), label(node.attribute("label").as_string("Test DrawingElement")), shape(nullptr) + { + setColor(node.attribute("color").as_string("Yellow")); + } + + int xmlParser::DrawingElement::getX() const + { + return x; + } + + void xmlParser::DrawingElement::setX(int newX) + { + x = newX; + + if(shape) + { + shape->setPosition(x,y); + } + } + + int xmlParser::DrawingElement::getY() const + { + return y; + } + + void xmlParser::DrawingElement::setY(int newY) + { + y = newY; + + if(shape) + { + shape->setPosition(x,y); + } + } + + const sf::Color& xmlParser::DrawingElement::getColor() const + { + return color; + } + + void xmlParser::DrawingElement::setColor(const sf::Color& newColor) + { + color = newColor; + + if(shape) + { + shape->setFillColor(color); + } + } + + void DrawingElement::setColor(const std::string& stringColor) + { + if(stringColor == "Black") + { + color = sf::Color::Black; + } + else if(stringColor == "White") + { + color = sf::Color::White; + } + else if(stringColor == "Red") + { + color = sf::Color::Red; + } + else if(stringColor == "Green") + { + color = sf::Color::Green; + } + else if(stringColor == "Blue") + { + color = sf::Color::Blue; + } + else if(stringColor == "Yellow") + { + color = sf::Color::Yellow; + } + else if(stringColor == "Magenta") + { + color = sf::Color::Magenta; + } + else if(stringColor == "Cyan") + { + color = sf::Color::Cyan; + } + else + { + color = sf::Color::Green; + } + } +} \ No newline at end of file diff --git a/snippets/DrawingElement.h b/snippets/DrawingElement.h new file mode 100644 index 0000000..5a4bfa8 --- /dev/null +++ b/snippets/DrawingElement.h @@ -0,0 +1,45 @@ +// +// Created by trotfunky on 15/05/19. +// + +#ifndef SNIPPETS_DRAWINGELEMENT_H +#define SNIPPETS_DRAWINGELEMENT_H + +#include +#include +#include + +namespace xmlParser +{ + class DrawingElement + { + public: + + DrawingElement(); + explicit DrawingElement(const pugi::xml_node&); + + virtual void draw(sf::RenderWindow&) = 0; + + std::string label; + + int getX() const; + void setX(int newX); + + int getY() const; + void setY(int newY); + + const sf::Color& getColor() const; + void setColor(const sf::Color& newColor); + void setColor(const std::string& stringColor); + + protected: + int x; + int y; + + sf::Color color; + + sf::Shape* shape; + }; +} + +#endif //SNIPPETS_DRAWINGELEMENT_H diff --git a/snippets/Group.cpp b/snippets/Group.cpp new file mode 100644 index 0000000..aec9d44 --- /dev/null +++ b/snippets/Group.cpp @@ -0,0 +1,65 @@ +// +// Created by trotfunky on 15/05/19. +// + +#include "Group.h" + +namespace xmlParser +{ + Group::Group() : DrawingElement(), drawingElements({}) + { + label = "Test Group"; + } + + Group::Group(const pugi::xml_node& node) : DrawingElement(node) + { + if(label == "Test DrawingElement") + { + label = "Test Group"; + } + + pugi::xml_object_range circleChildren = node.children(); + for(pugi::xml_node_iterator child : circleChildren) + { + pugi::xml_node& childNode = (*child); + DrawingElement* newElement = !strncmp(childNode.name(),"Circle",6) ? dynamic_cast(new Circle(childNode)) : + !strncmp(childNode.name(),"Group",5) ? dynamic_cast(new Group(childNode)) : nullptr; + if(newElement) + { + drawingElements.insert(std::make_pair(newElement->label,newElement)); + } + } + } + + Group::Group(const std::map& elements) : Group() + { + std::transform(elements.begin(),elements.end(),std::inserter(drawingElements,drawingElements.begin()), + [](std::pair pair) + { + return(pair); + }); + } + + bool Group::addDrawingElement(DrawingElement* drawingElement) + { + return(drawingElements.insert(std::make_pair(drawingElement->label,drawingElement)).second); + } + + bool Group::removeDrawingElement(const std::string& label) + { + return(drawingElements.erase(label)); + } + + DrawingElement* Group::getDrawingElement(const std::string& label) + { + return(drawingElements.at(label)); + } + + void Group::draw(sf::RenderWindow& window) + { + for(auto element : drawingElements) + { + element.second->draw(window); + } + } +} \ No newline at end of file diff --git a/snippets/Group.h b/snippets/Group.h new file mode 100644 index 0000000..b5d75d2 --- /dev/null +++ b/snippets/Group.h @@ -0,0 +1,38 @@ +// +// Created by trotfunky on 15/05/19. +// + +#ifndef SNIPPETS_GROUP_H +#define SNIPPETS_GROUP_H + +#include +#include +#include +#include + +#include "Circle.h" +#include "DrawingElement.h" + +namespace xmlParser +{ + + class Group : public DrawingElement + { + public: + Group(); + explicit Group(const pugi::xml_node&); + explicit Group(const std::map&); + + bool addDrawingElement(DrawingElement* drawingElement); + bool removeDrawingElement(const std::string& label); + + DrawingElement* getDrawingElement(const std::string&); + + void draw(sf::RenderWindow&) override; + private: + std::map drawingElements; + }; + +} + +#endif //SNIPPETS_GROUP_H diff --git a/snippets/Polynomial.tpp b/snippets/Polynomial.tpp index 04a2dd9..c8fa7c2 100644 --- a/snippets/Polynomial.tpp +++ b/snippets/Polynomial.tpp @@ -9,6 +9,7 @@ #include #include #include +#include template class Polynomial; @@ -72,6 +73,11 @@ Polynomial::Polynomial(const std::vector& polynomialFactors) : Polynomial< { if(polynomialFactors.size()>0) { + std::transform(polynomialFactors.begin(),polynomialFactors.end(),std::back_inserter(factors), + [](T factor) + { + return(factor); + }); factors = polynomialFactors; } } diff --git a/snippets/gTestXMLParser.cpp b/snippets/gTestXMLParser.cpp index 5687076..ecaa347 100644 --- a/snippets/gTestXMLParser.cpp +++ b/snippets/gTestXMLParser.cpp @@ -6,44 +6,126 @@ #include "Circle.h" #include "xmlParser.h" +#include "SFML/Graphics.hpp" +#include "Group.h" -TEST(readXML,initEmptyCircle) + +TEST(xmlParserInits,initEmptyCircle) { xmlParser::Circle cercle = xmlParser::Circle(); - ASSERT_EQ(cercle.x,0); - ASSERT_EQ(cercle.y,1); - ASSERT_EQ(cercle.r,2); - ASSERT_EQ(cercle.label,"Test circle"); + EXPECT_EQ(cercle.getX(),0); + EXPECT_EQ(cercle.getY(),1); + EXPECT_EQ(cercle.getR(),2); + EXPECT_EQ(cercle.label,"Test Circle"); + EXPECT_EQ(cercle.getColor(),sf::Color::Yellow); } -TEST(readXML,initEmptyCirclePugiXML) +TEST(xmlParserInits,initEmptyCirclePugiXML) { xmlParser::Circle cercle = xmlParser::Circle(); pugi::xml_node node; - ASSERT_EQ(cercle.x,0); - ASSERT_EQ(cercle.y,1); - ASSERT_EQ(cercle.r,2); - ASSERT_EQ(cercle.label,"Test circle"); + EXPECT_EQ(cercle.getX(),0); + EXPECT_EQ(cercle.getY(),1); + EXPECT_EQ(cercle.getR(),2); + EXPECT_EQ(cercle.label,"Test Circle"); + EXPECT_EQ(cercle.getColor(),sf::Color::Yellow); } -TEST(readXML,parseXMLCircle) +TEST(xmlParserInits,initEmptyGroup) +{ + xmlParser::Group group = xmlParser::Group(); + + EXPECT_EQ(group.getX(),0); + EXPECT_EQ(group.getY(),1); + EXPECT_EQ(group.label,"Test Group"); +} + +TEST(xmlParserInits,initEmptyGroupPugiXML) +{ + pugi::xml_node node; + xmlParser::Group group = xmlParser::Group(node); + + EXPECT_EQ(group.getX(),0); + EXPECT_EQ(group.getY(),1); + EXPECT_EQ(group.label,"Test Group"); +} + +TEST(parseXML,parseXMLCircle) { std::string xml = "\n" ""; pugi::xml_document doc; pugi::xml_parse_result result = doc.load_string(xml.c_str()); - EXPECT_NE(0,result); + ASSERT_NE(0,result); pugi::xml_node node = doc.child("Circle"); xmlParser::Circle cercle = xmlParser::Circle(node); - ASSERT_EQ(cercle.x,0); - ASSERT_EQ(cercle.y,1); - ASSERT_EQ(cercle.r,2); - ASSERT_EQ(cercle.label,"testCircle"); + EXPECT_EQ(cercle.getX(),0); + EXPECT_EQ(cercle.getY(),1); + EXPECT_EQ(cercle.getR(),2); + EXPECT_EQ(cercle.label,"testCircle"); + EXPECT_EQ(cercle.getColor(),sf::Color::Black); +} + + +TEST(parseXML,parseXMLGroup) +{ + std::string xml = "\n" + "\n" + " \n" + " \n" + ""; + + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_string(xml.c_str()); + ASSERT_NE(0,result); + + pugi::xml_node node = doc.child("Group"); + xmlParser::Group group = xmlParser::Group(node); + + EXPECT_EQ(group.getX(),0); + EXPECT_EQ(group.getY(),1); + EXPECT_EQ(group.label,"testGroup"); + + ASSERT_TRUE(group.getDrawingElement("testCircle1")); + xmlParser::Circle* testCircle1 = dynamic_cast(group.getDrawingElement("testCircle1")); + EXPECT_EQ(testCircle1->getX(),2); + EXPECT_EQ(testCircle1->getY(),3); + EXPECT_EQ(testCircle1->getR(),4); + EXPECT_EQ(testCircle1->getColor(),sf::Color::Black); + + ASSERT_TRUE(group.getDrawingElement("testCircle2")); + xmlParser::Circle* testCircle2 = dynamic_cast(group.getDrawingElement("testCircle2")); + EXPECT_EQ(testCircle2->getX(),5); + EXPECT_EQ(testCircle2->getY(),6); + EXPECT_EQ(testCircle2->getR(),7); + EXPECT_EQ(testCircle2->getColor(),sf::Color::Black); +} + +TEST(parseXML,parseXMLNestGroup) +{ + std::string xml = "\n" + "\n" + " \n" + " \n" + ""; + + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_string(xml.c_str()); + ASSERT_NE(0,result); + + pugi::xml_node node = doc.child("Group"); + xmlParser::Group group = xmlParser::Group(node); + ASSERT_TRUE(group.getDrawingElement("testGroup2")); + + xmlParser::Group* testGroup2 = dynamic_cast(group.getDrawingElement("testGroup2")); + EXPECT_EQ(testGroup2->getX(),5); + EXPECT_EQ(testGroup2->getY(),6); + EXPECT_EQ(testGroup2->label,"testGroup2"); } int main(int argc, char** argv)