From 96a980537731bff0a3647eb67e2138e92189862d Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Tue, 31 Mar 2020 21:08:25 +0200 Subject: [PATCH] Cleanup XML visitor --- SessionVisitor.cpp | 166 ++++++++++++++++++++++++++++++++++++++++++++ SessionVisitor.h | 25 +++++++ Visitor.h | 23 +----- tinyxml2Toolkit.cpp | 41 +++++++++++ tinyxml2Toolkit.h | 17 +++++ 5 files changed, 250 insertions(+), 22 deletions(-) create mode 100644 SessionVisitor.cpp create mode 100644 SessionVisitor.h create mode 100644 tinyxml2Toolkit.cpp create mode 100644 tinyxml2Toolkit.h diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp new file mode 100644 index 0000000..691eebb --- /dev/null +++ b/SessionVisitor.cpp @@ -0,0 +1,166 @@ +#include "Visitor.h" +#include "Log.h" +#include "Scene.h" +#include "Primitives.h" +#include "MediaPlayer.h" +#include "GstToolkit.h" + +#include + +#include +using namespace tinyxml2; + +#ifndef XMLCheckResult + #define XMLCheckResult(a_eResult) if (a_eResult != XML_SUCCESS) { Log::Warning("XML error %i\n", a_eResult); return; } +#endif + +SessionVisitor::SessionVisitor(std::string filename) : filename_(filename) +{ + xmlDoc_ = new XMLDocument; + xmlCurrent_ = nullptr; +} + +void SessionVisitor::visit(Group &n) +{ + XMLElement *xmlParent = xmlCurrent_; + xmlCurrent_ = xmlDoc_->NewElement("Group"); + visit( (Node&) n); + + for (int node = 0; node < n.numChildren(); ++node) + { + Node *child = n.getChild(node); + + Group *g = dynamic_cast(child); + if (g != nullptr) { + g->accept(*this); + continue; + } + + TexturedRectangle *tr = dynamic_cast(child); + if (tr != nullptr) { + tr->accept(*this); + continue; + } + + MediaRectangle *mr = dynamic_cast(child); + if (mr != nullptr) { + mr->accept(*this); + continue; + } + + LineStrip *ls = dynamic_cast(child); + if (ls != nullptr) { + ls->accept(*this); + continue; + } + + Primitive *p = dynamic_cast(child); + if (p != nullptr) { + p->accept(*this); + continue; + } + + } + + // recursive + xmlParent->InsertEndChild(xmlCurrent_); + xmlCurrent_ = xmlParent; + +} + +void SessionVisitor::visit(Node &n) +{ + XMLElement *transform = XMLElementGLM(xmlDoc_, n.transform_); + xmlCurrent_->InsertEndChild(transform); +} + +void SessionVisitor::visit(Primitive &n) +{ + visit( (Node&) n); +} + +void SessionVisitor::visit(TexturedRectangle &n) +{ + // type specific + XMLElement *xmlParent = xmlCurrent_; + xmlCurrent_ = xmlDoc_->NewElement("TexturedRectangle"); + + XMLElement *image = xmlDoc_->NewElement("filename"); + xmlCurrent_->InsertEndChild(image); + XMLText *filename = xmlDoc_->NewText( n.getResourcePath().c_str() ); + image->InsertEndChild(filename); + + // inherited from Primitive + visit( (Primitive&) n); + + // recursive + xmlParent->InsertEndChild(xmlCurrent_); + xmlCurrent_ = xmlParent; +} + +void SessionVisitor::visit(MediaRectangle &n) +{ + // type specific + XMLElement *xmlParent = xmlCurrent_; + xmlCurrent_ = xmlDoc_->NewElement("MediaRectangle"); + + XMLElement *media = xmlDoc_->NewElement("filename"); + xmlCurrent_->InsertEndChild(media); + XMLText *filename = xmlDoc_->NewText( n.getMediaPath().c_str() ); + media->InsertEndChild(filename); + + // TODO : visit MediaPlayer + + // inherited from Primitive + visit( (Primitive&) n); + + // recursive + xmlParent->InsertEndChild(xmlCurrent_); + xmlCurrent_ = xmlParent; +} + +void SessionVisitor::visit(LineStrip &n) +{ + // type specific + XMLElement *xmlParent = xmlCurrent_; + xmlCurrent_ = xmlDoc_->NewElement("LineStrip"); + + XMLElement *color = XMLElementGLM(xmlDoc_, n.getColor()); + color->SetAttribute("type", "RGBA"); + xmlCurrent_->InsertEndChild(color); + + std::vector points = n.getPoints(); + for(size_t i = 0; i < points.size(); ++i) + { + XMLElement *p = XMLElementGLM(xmlDoc_, points[i]); + p->SetAttribute("point", (int) i); + xmlCurrent_->InsertEndChild(p); + } + + // inherited from Primitive + visit( (Primitive&) n); + + // recursive + xmlParent->InsertEndChild(xmlCurrent_); + xmlCurrent_ = xmlParent; +} + +void SessionVisitor::visit(Scene &n) +{ + XMLDeclaration *pDec = xmlDoc_->NewDeclaration(); + xmlDoc_->InsertFirstChild(pDec); + + XMLElement *pRoot = xmlDoc_->NewElement("Session"); + xmlDoc_->InsertEndChild(pRoot); + + std::string s = "Saved on " + GstToolkit::date_time_string(); + XMLComment *pComment = xmlDoc_->NewComment(s.c_str()); + pRoot->InsertEndChild(pComment); + + // save scene + xmlCurrent_ = pRoot; + n.getRoot()->accept(*this); + + XMLError eResult = xmlDoc_->SaveFile(filename_.c_str()); + XMLCheckResult(eResult); +} diff --git a/SessionVisitor.h b/SessionVisitor.h new file mode 100644 index 0000000..ce7886b --- /dev/null +++ b/SessionVisitor.h @@ -0,0 +1,25 @@ +#ifndef XMLVISITOR_H +#define XMLVISITOR_H + +#include "Visitor.h" + +class SessionVisitor : public Visitor { + + std::string filename_; + tinyxml2::XMLDocument *xmlDoc_; + tinyxml2::XMLElement *xmlCurrent_; + +public: + SessionVisitor(std::string filename); + + void visit(Node& n) override; + void visit(Primitive& n) override; + void visit(Group& n) override; + void visit(TexturedRectangle& n) override; + void visit(MediaRectangle& n) override; + void visit(LineStrip& n) override; + void visit(Scene& n) override; + +}; + +#endif // XMLVISITOR_H diff --git a/Visitor.h b/Visitor.h index 42b8558..49bb0ec 100644 --- a/Visitor.h +++ b/Visitor.h @@ -3,10 +3,7 @@ #include -namespace tinyxml2 { -class XMLDocument; -class XMLElement; -} +#include "tinyxml2Toolkit.h" // Forward declare different kind of Node class Node; @@ -31,23 +28,5 @@ public: virtual void visit(Scene& n) = 0; }; -class SessionVisitor : public Visitor { - - std::string filename_; - tinyxml2::XMLDocument *xmlDoc_; - tinyxml2::XMLElement *xmlCurrent_; - -public: - SessionVisitor(std::string filename); - - void visit(Node& n) override; - void visit(Primitive& n) override; - void visit(Group& n) override; - void visit(TexturedRectangle& n) override; - void visit(MediaRectangle& n) override; - void visit(LineStrip& n) override; - void visit(Scene& n) override; - -}; #endif // VISITOR_H diff --git a/tinyxml2Toolkit.cpp b/tinyxml2Toolkit.cpp new file mode 100644 index 0000000..7453d7c --- /dev/null +++ b/tinyxml2Toolkit.cpp @@ -0,0 +1,41 @@ +#include "tinyxml2Toolkit.h" + +#include +using namespace tinyxml2; + +#include +#include +#include + + +XMLElement *XMLElementGLM(XMLDocument *doc, glm::vec3 vector) +{ + XMLElement *newelement = doc->NewElement( "vec3" ); + newelement->SetAttribute("x", vector[0]); + newelement->SetAttribute("y", vector[1]); + newelement->SetAttribute("z", vector[2]); + return newelement; +} + +XMLElement *XMLElementGLM(XMLDocument *doc, glm::vec4 vector) +{ + XMLElement *newelement = doc->NewElement( "vec4" ); + newelement->SetAttribute("x", vector[0]); + newelement->SetAttribute("y", vector[1]); + newelement->SetAttribute("z", vector[2]); + newelement->SetAttribute("w", vector[3]); + return newelement; +} + +XMLElement *XMLElementGLM(XMLDocument *doc, glm::mat4 matrix) +{ + XMLElement *newelement = doc->NewElement( "mat4" ); + for (int r = 0 ; r < 4 ; r ++) + { + glm::vec4 row = glm::row(matrix, r); + XMLElement *rowxml = XMLElementGLM(doc, row); + rowxml->SetAttribute("row", r); + newelement->InsertEndChild(rowxml); + } + return newelement; +} diff --git a/tinyxml2Toolkit.h b/tinyxml2Toolkit.h new file mode 100644 index 0000000..af6d03a --- /dev/null +++ b/tinyxml2Toolkit.h @@ -0,0 +1,17 @@ +#ifndef TINYXML2TOOLKIT_H +#define TINYXML2TOOLKIT_H + +#include + +namespace tinyxml2 { + +class XMLDocument; +class XMLElement; + +tinyxml2::XMLElement *XMLElementGLM(tinyxml2::XMLDocument *doc, glm::vec3 vector); +tinyxml2::XMLElement *XMLElementGLM(tinyxml2::XMLDocument *doc, glm::vec4 vector); +tinyxml2::XMLElement *XMLElementGLM(tinyxml2::XMLDocument *doc, glm::mat4 matrix); + +} + +#endif // TINYXML2TOOLKIT_H