diff --git a/ActionManager.cpp b/ActionManager.cpp index ca37834..f083a81 100644 --- a/ActionManager.cpp +++ b/ActionManager.cpp @@ -1,6 +1,5 @@ #include #include -#include #include "Log.h" #include "View.h" @@ -28,7 +27,7 @@ Action::Action(): history_step_(0), history_max_step_(0) { } -void Action::init(const std::string &xml) +void Action::init() { // clean the history history_doc_.Clear(); @@ -36,28 +35,6 @@ void Action::init(const std::string &xml) history_max_step_ = 0; // start fresh store("Session start"); - - // clean the snapshots - snapshots_doc_.Clear(); - snapshots_.clear(); - - if ( !xml.empty() ) { - if ( XMLResultError( snapshots_doc_.Parse( xml.c_str() ) )) - Log::Info("Failed to load snapshots"); - else - { - const XMLElement* N = snapshots_doc_.RootElement(); - for( ; N ; N=N->NextSiblingElement()) { - - char c; - u_int64_t id = 0; - std::istringstream nodename( N->Name() ); - nodename >> c >> id; - snapshots_.push_back(id); - } - } - } - } void Action::store(const std::string &label) @@ -173,48 +150,47 @@ void Action::snapshot(const std::string &label) if (locked_ || label.empty()) return; + // get session to operate on + Session *se = Mixer::manager().session(); + // create snapshot id u_int64_t id = GlmToolkit::uniqueId(); - snapshots_.push_back(id); + se->snapshots()->keys_.push_back(id); // create snapshot node - XMLElement *sessionNode = snapshots_doc_.NewElement( SNAPSHOT_NODE(id) ); - snapshots_doc_.InsertEndChild(sessionNode); + XMLElement *sessionNode = se->snapshots()->xmlDoc_->NewElement( SNAPSHOT_NODE(id) ); + se->snapshots()->xmlDoc_->InsertEndChild(sessionNode); // label describes the snapshot sessionNode->SetAttribute("label", label.c_str()); - // get session to operate on - Session *se = Mixer::manager().session(); - // save all sources using source visitor - SessionVisitor sv(&snapshots_doc_, sessionNode); + SessionVisitor sv(se->snapshots()->xmlDoc_, sessionNode); for (auto iter = se->begin(); iter != se->end(); ++iter, sv.setRoot(sessionNode) ) (*iter)->accept(sv); - // TODO: copy action history instead? + // TODO: copy current action history instead? // debug #ifdef ACTION_DEBUG Log::Info("Snapshot stored %d '%s'", id, label.c_str()); -// XMLSaveDoc(&xmlDoc_, "/home/bhbn/history.xml"); #endif } -const char *Action::snapshotsDescription() + +std::list Action::snapshots() const { - // get compact string - XMLPrinter xmlPrint; - snapshots_doc_.Print( &xmlPrint ); - - return xmlPrint.CStr(); + Session *se = Mixer::manager().session(); + return se->snapshots()->keys_; } - std::string Action::label(uint64_t snapshotid) const { std::string l = ""; - const XMLElement *sessionNode = snapshots_doc_.FirstChildElement( SNAPSHOT_NODE(snapshotid) ); + + // get snapshot node of target in current session + Session *se = Mixer::manager().session(); + const XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) ); if (sessionNode) { l = sessionNode->Attribute("label"); @@ -224,8 +200,9 @@ std::string Action::label(uint64_t snapshotid) const void Action::setLabel (uint64_t snapshotid, const std::string &label) { - // get history node of target - XMLElement *sessionNode = snapshots_doc_.FirstChildElement( SNAPSHOT_NODE(snapshotid) ); + // get snapshot node of target in current session + Session *se = Mixer::manager().session(); + XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) ); if (sessionNode) { sessionNode->SetAttribute("label", label.c_str()); @@ -234,12 +211,13 @@ void Action::setLabel (uint64_t snapshotid, const std::string &label) void Action::remove(uint64_t snapshotid) { - // get history node of target - XMLElement *sessionNode = snapshots_doc_.FirstChildElement( SNAPSHOT_NODE(snapshotid) ); + // get snapshot node of target in current session + Session *se = Mixer::manager().session(); + XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) ); if (sessionNode) { - snapshots_doc_.DeleteChild( sessionNode ); - snapshots_.remove(snapshotid); + se->snapshots()->xmlDoc_->DeleteChild( sessionNode ); + se->snapshots()->keys_.remove(snapshotid); } } @@ -248,8 +226,9 @@ void Action::restore(uint64_t snapshotid) // lock locked_ = true; - // get history node of target - XMLElement *sessionNode = snapshots_doc_.FirstChildElement( SNAPSHOT_NODE(snapshotid) ); + // get snapshot node of target in current session + Session *se = Mixer::manager().session(); + XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) ); if (sessionNode) { // actually restore @@ -260,6 +239,5 @@ void Action::restore(uint64_t snapshotid) locked_ = false; store("Snapshot " + label(snapshotid)); - } diff --git a/ActionManager.h b/ActionManager.h index a1ab358..e936735 100644 --- a/ActionManager.h +++ b/ActionManager.h @@ -23,7 +23,7 @@ public: static Action _instance; return _instance; } - void init(const std::string &xml = ""); + void init(); // UNDO History void store(const std::string &label); @@ -38,17 +38,13 @@ public: // Snapshots void snapshot(const std::string &label); - inline std::list snapshots() const { return snapshots_; } + std::list snapshots() const; void restore(uint64_t snapshotid); void remove (uint64_t snapshotid); std::string label(uint64_t snapshotid) const; void setLabel (uint64_t snapshotid, const std::string &label); - const char *snapshotsDescription(); - -// inline const tinyxml2::XMLElement *snapshotsRoot() const { return snapshots_doc_.RootElement(); } - private: tinyxml2::XMLDocument history_doc_; @@ -57,9 +53,6 @@ private: std::atomic locked_; void restore(uint target); - tinyxml2::XMLDocument snapshots_doc_; - std::list snapshots_; - }; diff --git a/Mixer.cpp b/Mixer.cpp index 08cce02..23d628e 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -1164,7 +1164,7 @@ void Mixer::swap() back_session_ = nullptr; // reset History manager - Action::manager().init( session_->snapshots() ); + Action::manager().init(); // notification Log::Notify("Session %s loaded. %d source(s) created.", session_->filename().c_str(), session_->numSource()); diff --git a/Session.cpp b/Session.cpp index c0feb5d..a406226 100644 --- a/Session.cpp +++ b/Session.cpp @@ -17,7 +17,7 @@ SessionNote::SessionNote(const std::string &t, bool l, int s): label(std::to_str { } -Session::Session() : active_(true), filename_(""), failedSource_(nullptr), snapshots_(""), fading_target_(0.f) +Session::Session() : active_(true), filename_(""), failedSource_(nullptr), fading_target_(0.f) { config_[View::RENDERING] = new Group; config_[View::RENDERING]->scale_ = glm::vec3(0.f); @@ -37,6 +37,8 @@ Session::Session() : active_(true), filename_(""), failedSource_(nullptr), snaps config_[View::TEXTURE] = new Group; config_[View::TEXTURE]->scale_ = Settings::application.views[View::TEXTURE].default_scale; config_[View::TEXTURE]->translation_ = Settings::application.views[View::TEXTURE].default_translation; + + snapshots_.xmlDoc_ = new tinyxml2::XMLDocument; } @@ -60,6 +62,9 @@ Session::~Session() delete config_[View::LAYER]; delete config_[View::MIXING]; delete config_[View::TEXTURE]; + + snapshots_.keys_.clear(); + delete snapshots_.xmlDoc_; } void Session::setActive (bool on) @@ -126,7 +131,6 @@ void Session::update(float dt) } - SourceList::iterator Session::addSource(Source *s) { // lock before change @@ -178,7 +182,6 @@ SourceList::iterator Session::deleteSource(Source *s) return its; } - void Session::removeSource(Source *s) { // lock before change @@ -201,7 +204,6 @@ void Session::removeSource(Source *s) access_.unlock(); } - Source *Session::popSource() { Source *s = nullptr; @@ -385,7 +387,6 @@ void Session::unlink (SourceList sources) } } - void Session::addNote(SessionNote note) { notes_.push_back( note ); @@ -419,7 +420,6 @@ std::list Session::getMixingGroups () const return lmg; } - std::list::iterator Session::deleteMixingGroup (std::list::iterator g) { if (g != mixing_groups_.end()) { @@ -449,7 +449,6 @@ void Session::unlock() access_.unlock(); } - void Session::validate (SourceList &sources) { // verify that all sources given are valid in the sesion diff --git a/Session.h b/Session.h index 5bb099c..a1962be 100644 --- a/Session.h +++ b/Session.h @@ -6,6 +6,9 @@ #include "SourceList.h" #include "RenderView.h" +namespace tinyxml2 { +class XMLDocument; +} class FrameGrabber; class MixingGroup; @@ -21,16 +24,12 @@ struct SessionNote SessionNote(const std::string &t = "", bool l = false, int s = 0); }; -struct SessionSnapshot -{ - uint64_t id; - std::string label; - std::string xml; +struct SessionSnapshots { - SessionSnapshot(const std::string &l, const std::string &desc); + tinyxml2::XMLDocument *xmlDoc_; + std::list keys_; }; - class Session { public: @@ -120,8 +119,7 @@ public: std::list::iterator deleteMixingGroup (std::list::iterator g); // snapshots - void setSnapshots (const std::string &xml) { snapshots_ = xml; } - std::string snapshots () const { return snapshots_; } + SessionSnapshots * const snapshots () { return &snapshots_; } // lock and unlock access (e.g. while saving) void lock (); @@ -137,7 +135,7 @@ protected: std::list notes_; std::list mixing_groups_; std::map config_; - std::string snapshots_; + SessionSnapshots snapshots_; float fading_target_; std::mutex access_; }; diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 38c090b..64559ab 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -1,4 +1,4 @@ -#include "SessionCreator.h" +#include #include "Log.h" #include "defines.h" @@ -18,10 +18,10 @@ #include "MediaPlayer.h" #include "SystemToolkit.h" -#include #include "tinyxml2Toolkit.h" using namespace tinyxml2; +#include "SessionCreator.h" std::string SessionCreator::info(const std::string& filename) { @@ -127,8 +127,17 @@ void SessionCreator::loadSnapshots(XMLElement *snapshotsNode) { if (snapshotsNode != nullptr && session_ != nullptr) { - std::string text = std::string ( snapshotsNode->GetText() ); - session_->setSnapshots( text ); + const XMLElement* N = snapshotsNode->FirstChildElement(); + for( ; N ; N = N->NextSiblingElement()) { + + char c; + u_int64_t id = 0; + std::istringstream nodename( N->Name() ); + nodename >> c >> id; + + session_->snapshots()->keys_.push_back(id); + session_->snapshots()->xmlDoc_->InsertEndChild( N->DeepClone(session_->snapshots()->xmlDoc_) ); + } } } @@ -406,7 +415,7 @@ Source *SessionLoader::createSource(tinyxml2::XMLElement *sourceNode, Mode mode) } -bool SessionLoader::isClipboard(std::string clipboard) +bool SessionLoader::isClipboard(const std::string &clipboard) { if (clipboard.size() > 6 && clipboard.substr(0, 6) == "<" APP_NAME ) return true; @@ -414,7 +423,7 @@ bool SessionLoader::isClipboard(std::string clipboard) return false; } -tinyxml2::XMLElement* SessionLoader::firstSourceElement(std::string clipboard, XMLDocument &xmlDoc) +tinyxml2::XMLElement* SessionLoader::firstSourceElement(const std::string &clipboard, XMLDocument &xmlDoc) { tinyxml2::XMLElement* sourceNode = nullptr; @@ -435,7 +444,7 @@ tinyxml2::XMLElement* SessionLoader::firstSourceElement(std::string clipboard, X return sourceNode; } -void SessionLoader::applyImageProcessing(const Source &s, std::string clipboard) +void SessionLoader::applyImageProcessing(const Source &s, const std::string &clipboard) { if ( !isClipboard(clipboard) ) return; diff --git a/SessionCreator.h b/SessionCreator.h index df87fde..63602e8 100644 --- a/SessionCreator.h +++ b/SessionCreator.h @@ -29,9 +29,9 @@ public: } Mode; Source *createSource(tinyxml2::XMLElement *sourceNode, Mode mode = CLONE); - static bool isClipboard(std::string clipboard); - static tinyxml2::XMLElement* firstSourceElement(std::string clipboard, tinyxml2::XMLDocument &xmlDoc); - static void applyImageProcessing(const Source &s, std::string clipboard); + static bool isClipboard(const std::string &clipboard); + static tinyxml2::XMLElement* firstSourceElement(const std::string &clipboard, tinyxml2::XMLDocument &xmlDoc); + static void applyImageProcessing(const Source &s, const std::string &clipboard); //TODO static void applyMask(const Source &s, std::string clipboard); // Elements of Scene diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index c40ab2a..c735b33 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -76,12 +76,9 @@ bool SessionVisitor::saveSession(const std::string& filename, Session *session) // 3. snapshots XMLElement *snapshots = xmlDoc.NewElement("Snapshots"); -// const XMLElement* N = Action::manager().snapshotsRoot(); -// for( ; N ; N=N->NextSiblingElement()) -// snapshots->InsertEndChild( N->DeepClone( &xmlDoc )); - - XMLText *desc = xmlDoc.NewText( Action::manager().snapshotsDescription() ); - snapshots->InsertEndChild( desc ); + const XMLElement* N = session->snapshots()->xmlDoc_->FirstChildElement(); + for( ; N ; N=N->NextSiblingElement()) + snapshots->InsertEndChild( N->DeepClone( &xmlDoc )); xmlDoc.InsertEndChild(snapshots); // 4. optional notes