mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-16 04:40:08 +01:00
Better implementation of SessionSnapshots saving
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#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<uint64_t> 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));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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<uint64_t> snapshots() const { return snapshots_; }
|
||||
std::list<uint64_t> 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<bool> locked_;
|
||||
void restore(uint target);
|
||||
|
||||
tinyxml2::XMLDocument snapshots_doc_;
|
||||
std::list<uint64_t> snapshots_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
13
Session.cpp
13
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<SourceList> Session::getMixingGroups () const
|
||||
return lmg;
|
||||
}
|
||||
|
||||
|
||||
std::list<MixingGroup *>::iterator Session::deleteMixingGroup (std::list<MixingGroup *>::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
|
||||
|
||||
18
Session.h
18
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<uint64_t> keys_;
|
||||
};
|
||||
|
||||
|
||||
class Session
|
||||
{
|
||||
public:
|
||||
@@ -120,8 +119,7 @@ public:
|
||||
std::list<MixingGroup *>::iterator deleteMixingGroup (std::list<MixingGroup *>::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<SessionNote> notes_;
|
||||
std::list<MixingGroup *> mixing_groups_;
|
||||
std::map<View::Mode, Group*> config_;
|
||||
std::string snapshots_;
|
||||
SessionSnapshots snapshots_;
|
||||
float fading_target_;
|
||||
std::mutex access_;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "SessionCreator.h"
|
||||
#include <sstream>
|
||||
|
||||
#include "Log.h"
|
||||
#include "defines.h"
|
||||
@@ -18,10 +18,10 @@
|
||||
#include "MediaPlayer.h"
|
||||
#include "SystemToolkit.h"
|
||||
|
||||
#include <tinyxml2.h>
|
||||
#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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user