diff --git a/Mixer.cpp b/Mixer.cpp index ac00b52..8b15c74 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -948,7 +948,7 @@ void Mixer::load(const std::string& filename) if (sessionLoaders_.empty()) { // Start async thread for loading the session // Will be obtained in the future in update() - sessionLoaders_.emplace_back( std::async(std::launch::async, Session::load, filename) ); + sessionLoaders_.emplace_back( std::async(std::launch::async, Session::load, filename, 0) ); } #else set( Session::load(filename) ); @@ -986,7 +986,7 @@ void Mixer::import(const std::string& filename) if (sessionImporters_.empty()) { // Start async thread for loading the session // Will be obtained in the future in update() - sessionImporters_.emplace_back( std::async(std::launch::async, Session::load, filename) ); + sessionImporters_.emplace_back( std::async(std::launch::async, Session::load, filename, 0) ); } #else merge( Session::load(filename) ); diff --git a/SearchVisitor.cpp b/SearchVisitor.cpp index 1a2512f..584c43b 100644 --- a/SearchVisitor.cpp +++ b/SearchVisitor.cpp @@ -1,6 +1,11 @@ +#include + #include "SearchVisitor.h" #include "Scene.h" +#include "MediaSource.h" +#include "Session.h" +#include "SessionSource.h" SearchVisitor::SearchVisitor(Node *node) : Visitor(), node_(node), found_(false) { @@ -42,12 +47,11 @@ void SearchVisitor::visit(Scene &n) -SearchFileVisitor::SearchFileVisitor(std::string filename) : Visitor(), filename_(filename), found_(false) +SearchFileVisitor::SearchFileVisitor() : Visitor() { } - void SearchFileVisitor::visit(Node &n) { @@ -55,13 +59,8 @@ void SearchFileVisitor::visit(Node &n) void SearchFileVisitor::visit(Group &n) { - if (found_) - return; - for (NodeSet::iterator node = n.begin(); node != n.end(); node++) { (*node)->accept(*this); - if (found_) - break; } } @@ -81,10 +80,29 @@ void SearchFileVisitor::visit(Scene &n) void SearchFileVisitor::visit (MediaSource& s) { - + filenames_.push_back( s.path() ); } void SearchFileVisitor::visit (SessionFileSource& s) { + filenames_.push_back( s.path() ); } + +std::list SearchFileVisitor::parse (Session *se) +{ + SearchFileVisitor sv; + + for (auto iter = se->begin(); iter != se->end(); iter++){ + (*iter)->accept(sv); + } + + return sv.filenames(); +} + +bool SearchFileVisitor::find (Session *se, std::string path) +{ + std::list filenames = parse (se); + return std::find(filenames.begin(), filenames.end(), path) != filenames.end(); +} + diff --git a/SearchVisitor.h b/SearchVisitor.h index a927108..9a66d1b 100644 --- a/SearchVisitor.h +++ b/SearchVisitor.h @@ -1,9 +1,12 @@ #ifndef SEARCHVISITOR_H #define SEARCHVISITOR_H +#include #include #include "Visitor.h" +class Session; + class SearchVisitor: public Visitor { Node *node_; @@ -15,33 +18,35 @@ public: inline Node *node() const { return found_ ? node_ : nullptr; } // Elements of Scene - void visit(Scene& n) override; - void visit(Node& n) override; - void visit(Primitive&) override {} - void visit(Group& n) override; - void visit(Switch& n) override; + void visit (Scene& n) override; + void visit (Node& n) override; + void visit (Primitive&) override {} + void visit (Group& n) override; + void visit (Switch& n) override; }; class SearchFileVisitor: public Visitor { - std::string filename_; - bool found_; + std::list filenames_; public: - SearchFileVisitor(std::string filename); - inline bool found() const { return found_; } + SearchFileVisitor(); + inline std::list filenames() const { return filenames_; } // Elements of Scene - void visit(Scene& n) override; - void visit(Node& n) override; - void visit(Primitive&) override {} - void visit(Group& n) override; - void visit(Switch& n) override; + void visit (Scene& n) override; + void visit (Node& n) override; + void visit (Primitive&) override {} + void visit (Group& n) override; + void visit (Switch& n) override; // Sources void visit (MediaSource& s) override; void visit (SessionFileSource& s) override; + + static std::list parse (Session *se); + static bool find (Session *se, std::string path); }; #endif // SEARCHVISITOR_H diff --git a/Session.cpp b/Session.cpp index 556d474..0efb43f 100644 --- a/Session.cpp +++ b/Session.cpp @@ -4,7 +4,6 @@ #include "Settings.h" #include "FrameBuffer.h" #include "Session.h" -#include "GarbageVisitor.h" #include "FrameGrabber.h" #include "SessionCreator.h" #include "SessionSource.h" @@ -323,9 +322,9 @@ void Session::unlock() } -Session *Session::load(const std::string& filename) +Session *Session::load(const std::string& filename, uint recursion) { - SessionCreator creator; + SessionCreator creator(recursion); creator.load(filename); return creator.session(); diff --git a/Session.h b/Session.h index 4451710..91ed510 100644 --- a/Session.h +++ b/Session.h @@ -14,7 +14,7 @@ public: Session(); ~Session(); - static Session *load(const std::string& filename); + static Session *load(const std::string& filename, uint recursion = 0); // add given source into the session SourceList::iterator addSource (Source *s); diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 69c5aed..344c499 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -52,7 +52,7 @@ std::string SessionCreator::info(const std::string& filename) return ret; } -SessionCreator::SessionCreator(): SessionLoader(nullptr) +SessionCreator::SessionCreator(uint recursion): SessionLoader(nullptr, recursion) { } @@ -108,7 +108,7 @@ void SessionCreator::loadConfig(XMLElement *viewsNode) } } -SessionLoader::SessionLoader(Session *session): Visitor(), session_(session) +SessionLoader::SessionLoader(Session *session, uint recursion): Visitor(), session_(session), recursion_(recursion) { } @@ -117,6 +117,11 @@ void SessionLoader::load(XMLElement *sessionNode) { sources_id_.clear(); + if (recursion_ > MAX_SESSION_LEVEL) { + Log::Warning("Recursive or imbricated sessions detected! Interrupting loading after %d iterations.\n", MAX_SESSION_LEVEL); + return; + } + if (sessionNode != nullptr && session_ != nullptr) { XMLElement* sourceNode = sessionNode->FirstChildElement("Source"); @@ -534,11 +539,11 @@ void SessionLoader::visit (SessionFileSource& s) XMLElement* pathNode = xmlCurrent_->FirstChildElement("path"); if (pathNode) { std::string path = std::string ( pathNode->GetText() ); + // load only new files if ( path != s.path() ) - s.load(path); + s.load(path, recursion_ + 1); } - } void SessionLoader::visit (SessionGroupSource& s) @@ -550,10 +555,9 @@ void SessionLoader::visit (SessionGroupSource& s) XMLElement* sessionGroupNode = xmlCurrent_->FirstChildElement("Session"); if (sessionGroupNode) { // load session inside group - SessionLoader grouploader( s.session() ); + SessionLoader grouploader( s.session(), recursion_ + 1 ); grouploader.load( sessionGroupNode ); } - } void SessionLoader::visit (RenderSource& s) diff --git a/SessionCreator.h b/SessionCreator.h index ded2480..ed3dea6 100644 --- a/SessionCreator.h +++ b/SessionCreator.h @@ -13,7 +13,7 @@ class SessionLoader : public Visitor { public: - SessionLoader(Session *session); + SessionLoader(Session *session, uint recursion = 0); inline Session *session() const { return session_; } void load(tinyxml2::XMLElement *sessionNode); @@ -58,6 +58,7 @@ protected: tinyxml2::XMLElement *xmlCurrent_; Session *session_; std::list sources_id_; + uint recursion_; static void XMLToNode(tinyxml2::XMLElement *xml, Node &n); }; @@ -69,7 +70,7 @@ class SessionCreator : public SessionLoader { void loadConfig(tinyxml2::XMLElement *viewsNode); public: - SessionCreator(); + SessionCreator(uint recursion = 0); void load(const std::string& filename); diff --git a/SessionSource.cpp b/SessionSource.cpp index 4a7da94..5690a1e 100644 --- a/SessionSource.cpp +++ b/SessionSource.cpp @@ -128,7 +128,7 @@ SessionFileSource::SessionFileSource() : SessionSource(), path_("") wait_for_sources_ = false; } -void SessionFileSource::load(const std::string &p) +void SessionFileSource::load(const std::string &p, uint recursion) { path_ = p; @@ -142,10 +142,11 @@ void SessionFileSource::load(const std::string &p) if ( path_.empty() ) { // empty session session_ = new Session; + Log::Warning("Empty Session filename provided."); } else { // launch a thread to load the session file - sessionLoader_ = std::async(std::launch::async, Session::load, path_); + sessionLoader_ = std::async(std::launch::async, Session::load, path_, recursion); Log::Notify("Opening %s", p.c_str()); } } diff --git a/SessionSource.h b/SessionSource.h index 9cce888..cf6a7e8 100644 --- a/SessionSource.h +++ b/SessionSource.h @@ -35,7 +35,7 @@ public: void accept (Visitor& v) override; // SessionFile Source specific interface - void load(const std::string &p = ""); + void load(const std::string &p = "", uint recursion = 0); inline std::string path() const { return path_; } glm::ivec2 icon() const override { return glm::ivec2(2, 16); } diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index e1a0f0f..6f81374 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -433,9 +433,10 @@ void SessionVisitor::visit (SessionGroupSource& s) XMLElement *rootgroup = xmlDoc_->NewElement("Session"); xmlCurrent_->InsertEndChild(rootgroup); - setRoot(rootgroup); - for (auto iter = se->begin(); iter != se->end(); iter++, setRoot(rootgroup) ) + for (auto iter = se->begin(); iter != se->end(); iter++){ + setRoot(rootgroup); (*iter)->accept(*this); + } } diff --git a/defines.h b/defines.h index f837a16..a5b2e31 100644 --- a/defines.h +++ b/defines.h @@ -9,6 +9,7 @@ #define XML_VERSION_MAJOR 0 #define XML_VERSION_MINOR 2 #define MAX_RECENT_HISTORY 20 +#define MAX_SESSION_LEVEL 3 #define MINI(a, b) (((a) < (b)) ? (a) : (b)) #define MAXI(a, b) (((a) > (b)) ? (a) : (b))