From 8185c934577d6de37e38d4abd2d472beaeff4dbb Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Fri, 5 Feb 2021 18:11:16 +0100 Subject: [PATCH] Fixed replacement of failed RenderView after sessionSource import (if a sessionSource contains a RenderView, the later should be re-created). --- Mixer.cpp | 87 +++++++++++++++++++++++++++++++++------------- Mixer.h | 3 +- SessionCreator.cpp | 13 +++---- SessionCreator.h | 2 +- SessionSource.cpp | 4 +-- 5 files changed, 74 insertions(+), 35 deletions(-) diff --git a/Mixer.cpp b/Mixer.cpp index eb761b2..1fb5470 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -220,10 +220,8 @@ void Mixer::update() // failed Render loopback: replace it with one matching the current session RenderSource *failedRender = dynamic_cast(failure); if (failedRender != nullptr) { - RenderSource *fixedRender = new RenderSource; - replaceSource(failedRender, fixedRender); - fixedRender->setSession(session_); - failure = nullptr; // prevent delete (already done in replace) + if ( recreateSource(failedRender) ) + failure = nullptr; // prevent delete (already done in recreateSource) } // delete the source deleteSource(failure, false); @@ -423,36 +421,75 @@ void Mixer::insertSource(Source *s, View::Mode m) } -void Mixer::replaceSource(Source *from, Source *to) +bool Mixer::replaceSource(Source *from, Source *to) { - if ( from != nullptr && to != nullptr) - { - // rename - renameSource(to, from->name()); + if ( from == nullptr || to == nullptr) + return false; - // remove source Nodes from all views - detach(from); + // rename + renameSource(to, from->name()); - // copy all transforms - to->group(View::MIXING)->copyTransform( from->group(View::MIXING) ); - to->group(View::GEOMETRY)->copyTransform( from->group(View::GEOMETRY) ); - to->group(View::LAYER)->copyTransform( from->group(View::LAYER) ); - to->group(View::MIXING)->copyTransform( from->group(View::MIXING) ); + // remove source Nodes from all views + detach(from); - // TODO copy all filters + // copy all transforms + to->group(View::MIXING)->copyTransform( from->group(View::MIXING) ); + to->group(View::GEOMETRY)->copyTransform( from->group(View::GEOMETRY) ); + to->group(View::LAYER)->copyTransform( from->group(View::LAYER) ); + to->group(View::MIXING)->copyTransform( from->group(View::MIXING) ); + + // TODO copy all filters - // add sources Nodes to all views - attach(to); + // add source Nodes to all views + attach(to); - // add source - session_->addSource(to); + // add source + session_->addSource(to); - // delete source - session_->deleteSource(from); + // delete source + session_->deleteSource(from); - } + return true; +} + +bool Mixer::recreateSource(Source *s) +{ + if ( s == nullptr ) + return false; + + // get the xml description from this source, and exit if not wellformed + tinyxml2::XMLDocument xmlDoc; + tinyxml2::XMLError eResult = xmlDoc.Parse(Source::xml(s).c_str()); + if ( XMLResultError(eResult)) + return false; + tinyxml2::XMLElement *root = xmlDoc.FirstChildElement(APP_NAME); + if ( root == nullptr ) + return false; + XMLElement* sourceNode = root->FirstChildElement("Source"); + if ( sourceNode == nullptr ) + return false; + + // actually create the source with SessionLoader using xml description + SessionLoader loader( session_ ); + Source *replacement = loader.createSource(sourceNode, false); // not clone + if (replacement == nullptr) + return false; + + // remove source Nodes from all views + detach(s); + + // delete source + session_->deleteSource(s); + + // add sources Nodes to all views + attach(replacement); + + // add source + session_->addSource(replacement); + + return true; } void Mixer::deleteSource(Source *s, bool withundo) @@ -1106,7 +1143,7 @@ void Mixer::paste(const std::string& clipboard) XMLElement* sourceNode = root->FirstChildElement("Source"); for( ; sourceNode ; sourceNode = sourceNode->NextSiblingElement()) { - addSource(loader.cloneOrCreateSource(sourceNode)); + addSource(loader.createSource(sourceNode)); } } diff --git a/Mixer.h b/Mixer.h index bbdab79..5bb9d81 100644 --- a/Mixer.h +++ b/Mixer.h @@ -109,7 +109,8 @@ protected: SourceList candidate_sources_; SourceList stash_; void insertSource(Source *s, View::Mode m = View::INVALID); - void replaceSource(Source *from, Source *to); + bool replaceSource(Source *from, Source *to); + bool recreateSource(Source *s); void setCurrentSource(SourceList::iterator it); SourceList::iterator current_source_; diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 6604c1d..ef22772 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -220,7 +220,7 @@ void SessionLoader::load(XMLElement *sessionNode) } -Source *SessionLoader::cloneOrCreateSource(tinyxml2::XMLElement *sourceNode) +Source *SessionLoader::createSource(tinyxml2::XMLElement *sourceNode, bool clone_duplicates) { xmlCurrent_ = sourceNode; @@ -228,10 +228,13 @@ Source *SessionLoader::cloneOrCreateSource(tinyxml2::XMLElement *sourceNode) Source *load_source = nullptr; bool is_clone = false; + SourceList::iterator sit = session_->end(); // check if a source with the given id exists in the session - uint64_t id__ = 0; - xmlCurrent_->QueryUnsigned64Attribute("id", &id__); - SourceList::iterator sit = session_->find(id__); + if (clone_duplicates) { + uint64_t id__ = 0; + xmlCurrent_->QueryUnsigned64Attribute("id", &id__); + sit = session_->find(id__); + } // no source with this id exists if ( sit == session_->end() ) { @@ -278,8 +281,6 @@ Source *SessionLoader::cloneOrCreateSource(tinyxml2::XMLElement *sourceNode) // apply config to source if (load_source) { load_source->accept(*this); - // reset mixing (force to place in mixing scene) - load_source->group(View::MIXING)->translation_ = glm::vec3(DEFAULT_MIXING_TRANSLATION, 0.f); // increment depth for clones (avoid supperposition) if (is_clone) load_source->group(View::LAYER)->translation_.z += 0.2f; diff --git a/SessionCreator.h b/SessionCreator.h index bc504da..ed5b032 100644 --- a/SessionCreator.h +++ b/SessionCreator.h @@ -19,7 +19,7 @@ public: void load(tinyxml2::XMLElement *sessionNode); inline std::list getIdList() const { return sources_id_; } - Source *cloneOrCreateSource(tinyxml2::XMLElement *sourceNode); + Source *createSource(tinyxml2::XMLElement *sourceNode, bool clone_duplicates = true); // Elements of Scene void visit (Node& n) override; diff --git a/SessionSource.cpp b/SessionSource.cpp index ae4cebf..acef465 100644 --- a/SessionSource.cpp +++ b/SessionSource.cpp @@ -226,7 +226,7 @@ void SessionSource::update(float dt) void SessionSource::accept(Visitor& v) { Source::accept(v); - if (!failed()) +// if (!failed()) v.visit(*this); } @@ -281,6 +281,6 @@ void RenderSource::init() void RenderSource::accept(Visitor& v) { Source::accept(v); - if (!failed()) +// if (!failed()) v.visit(*this); }