From b07009f3ce9b34ae8cf1043e745de96a085f1e0c Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Fri, 19 Mar 2021 22:53:08 +0100 Subject: [PATCH] BugFix: SessionGroupSource creation and update in ActionManager and SessionCreator. --- ActionManager.cpp | 74 ++++++++++++++++++---------------------------- ActionManager.h | 3 +- SessionCreator.cpp | 22 ++++++-------- SessionCreator.h | 2 +- 4 files changed, 40 insertions(+), 61 deletions(-) diff --git a/ActionManager.cpp b/ActionManager.cpp index 4b794e3..35a0eb9 100644 --- a/ActionManager.cpp +++ b/ActionManager.cpp @@ -6,6 +6,7 @@ #include "Mixer.h" #include "MixingGroup.h" #include "tinyxml2Toolkit.h" +#include "SessionSource.h" #include "SessionVisitor.h" #include "SessionCreator.h" #include "Settings.h" @@ -83,15 +84,8 @@ void Action::undo() if (step_ <= 1) return; - // what id was modified to get to this step ? - // get history node of current step - std::string nodename = "H" + std::to_string(step_); - XMLElement *sessionNode = xmlDoc_.FirstChildElement( nodename.c_str() ); - uint64_t id = 0; - sessionNode->QueryUnsigned64Attribute("id", &id); - // restore always changes step_ to step_ - 1 - restore( step_ - 1, id); + restore( step_ - 1); } void Action::redo() @@ -100,14 +94,8 @@ void Action::redo() if (step_ >= max_step_) return; - // what id to modify to go to next step ? - std::string nodename = "H" + std::to_string(step_ + 1); - XMLElement *sessionNode = xmlDoc_.FirstChildElement( nodename.c_str() ); - uint64_t id = 0; - sessionNode->QueryUnsigned64Attribute("id", &id); - // restore always changes step_ to step_ + 1 - restore( step_ + 1, id); + restore( step_ + 1); } @@ -129,6 +117,8 @@ void Action::stepTo(uint target) redo(); } // ignore t == step_ + +// restore(t); } @@ -144,7 +134,7 @@ std::string Action::label(uint s) const return l; } -void Action::restore(uint target, uint64_t id) +void Action::restore(uint target) { // lock locked_ = true; @@ -173,58 +163,57 @@ void Action::restore(uint target, uint64_t id) if (se == nullptr) return; - // sessionsources contains list of ids of all sources currently in the session - SourceIdList sessionsources = se->getIdList(); + // sessionsources contains list of ids of all sources currently in the session (before loading) + SourceIdList session_sources = se->getIdList(); // for( auto it = sessionsources.begin(); it != sessionsources.end(); it++) // Log::Info("sessionsources id %s", std::to_string(*it).c_str()); // load history status: // - if a source exists, its attributes are updated, and that's all - // - if a source does not exists (in session), it is created in the session + // - if a source does not exists (in current session), it is created inside the session SessionLoader loader( se ); loader.load( sessionNode ); - // loadersources contains list of ids of all sources generated by loader - SourceIdList loadersources = loader.getIdList(); -// for( auto it = loadersources.begin(); it != loadersources.end(); it++) -// Log::Info("loadersources id %s", std::to_string(*it).c_str()); + // loaded_sources contains map of xml ids of all sources treated by loader + std::map< uint64_t, Source* > loaded_sources = loader.getSources(); // remove intersect of both lists (sources were updated by SessionLoader) - for( auto lsit = loadersources.begin(); lsit != loadersources.end(); ){ - auto ssit = std::find(sessionsources.begin(), sessionsources.end(), (*lsit)); - if ( ssit != sessionsources.end() ) { - lsit = loadersources.erase(lsit); - sessionsources.erase(ssit); + for( auto lsit = loaded_sources.begin(); lsit != loaded_sources.end(); ){ + auto ssit = std::find(session_sources.begin(), session_sources.end(), (*lsit).first); + if ( ssit != session_sources.end() ) { + lsit = loaded_sources.erase(lsit); + session_sources.erase(ssit); } else lsit++; } // remaining ids in list sessionsources : to remove - while ( !sessionsources.empty() ){ - Source *s = Mixer::manager().findSource( sessionsources.front() ); + while ( !session_sources.empty() ){ + Source *s = Mixer::manager().findSource( session_sources.front() ); if (s!=nullptr) { #ifdef ACTION_DEBUG - Log::Info("Delete id %s", std::to_string(sessionsources.front() ).c_str()); + Log::Info("Delete id %s\n", std::to_string(session_sources.front() ).c_str()); #endif // remove the source from the mixer Mixer::manager().detach( s ); // delete source from session se->deleteSource( s ); } - sessionsources.pop_front(); + session_sources.pop_front(); } - // remaining ids in list loadersources : to add - while ( !loadersources.empty() ){ + // remaining sources in list loaded_sources : to add + for ( auto lsit = loaded_sources.begin(); lsit != loaded_sources.end(); lsit++) + { #ifdef ACTION_DEBUG - Log::Info("Recreate id %s to %s", std::to_string(id).c_str(), std::to_string(loadersources.front()).c_str()); + Log::Info("Recreate id %s to %s\n", std::to_string((*lsit).first).c_str(), std::to_string((*lsit).second->id()).c_str()); #endif + // attach created source + Mixer::manager().attach( (*lsit).second ); + // change the history to match the new id - replaceSourceId(id, loadersources.front()); - // add the source to the mixer - Mixer::manager().attach( Mixer::manager().findSource( loadersources.front() ) ); - loadersources.pop_front(); + replaceSourceId( (*lsit).first, (*lsit).second->id()); } // @@ -257,13 +246,6 @@ void Action::replaceSourceId(uint64_t previousid, uint64_t newid) XMLElement* historyNode = xmlDoc_.FirstChildElement("H1"); for( ; historyNode ; historyNode = historyNode->NextSiblingElement()) { - // check if this history node references this id - uint64_t id_history_ = 0; - historyNode->QueryUnsigned64Attribute("id", &id_history_); - if ( id_history_ == previousid ) - // change to new id - historyNode->SetAttribute("id", newid); - // loop over every source in session history XMLElement* sourceNode = historyNode->FirstChildElement("Source"); for( ; sourceNode ; sourceNode = sourceNode->NextSiblingElement()) diff --git a/ActionManager.h b/ActionManager.h index dea2fc4..53001bd 100644 --- a/ActionManager.h +++ b/ActionManager.h @@ -36,8 +36,9 @@ public: private: - void restore(uint target, uint64_t id); + void restore(uint target); void replaceSourceId(uint64_t previousid, uint64_t newid); +// void replaceSourceId(tinyxml2::XMLElement* parentnode, uint64_t previousid, uint64_t newid); tinyxml2::XMLDocument xmlDoc_; uint step_; diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 25d0d35..9ccd629 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -119,14 +119,10 @@ SessionLoader::SessionLoader(Session *session, int recursion): Visitor(), } -// get the list of new source id (value in sources_id_ map) -SourceIdList SessionLoader::getIdList() const -{ - SourceIdList id_current_value; - for (auto it = sources_id_.begin(); it != sources_id_.end(); it++) - id_current_value.push_back( it->second->id() ); - return id_current_value; +std::map< uint64_t, Source* > SessionLoader::getSources() const +{ + return sources_id_; } // groups_sources_id_ is parsed in XML and contains list of groups of ids @@ -224,7 +220,6 @@ void SessionLoader::load(XMLElement *sessionNode) // remember sources_id_[id_xml_] = load_source; -// sources_id_[id_xml_] = load_source->id(); } // create clones after all sources, to be able to clone a source created above @@ -264,7 +259,6 @@ void SessionLoader::load(XMLElement *sessionNode) // remember sources_id_[id_xml_] = clone_source; -// sources_id_[id_xml_] = clone_source->id(); } } } @@ -604,7 +598,6 @@ 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, recursion_ + 1); @@ -619,9 +612,12 @@ void SessionLoader::visit (SessionGroupSource& s) // get the inside session XMLElement* sessionGroupNode = xmlCurrent_->FirstChildElement("Session"); if (sessionGroupNode) { - // load session inside group - SessionLoader grouploader( s.session(), recursion_ + 1 ); - grouploader.load( sessionGroupNode ); + // only parse if newly created + if (s.session()->empty()) { + // load session inside group + SessionLoader grouploader( s.session(), recursion_ + 1 ); + grouploader.load( sessionGroupNode ); + } } } diff --git a/SessionCreator.h b/SessionCreator.h index 0c637ee..9ce0684 100644 --- a/SessionCreator.h +++ b/SessionCreator.h @@ -18,7 +18,7 @@ public: inline Session *session() const { return session_; } void load(tinyxml2::XMLElement *sessionNode); - SourceIdList getIdList() const; + std::map< uint64_t, Source* > getSources() const; std::list< SourceList > getMixingGroups() const; Source *createSource(tinyxml2::XMLElement *sourceNode, bool clone_duplicates = true);