MixerSnapshot can construct based off a different session's state

This commit is contained in:
Nikolaus Gullotta 2019-03-22 13:33:23 -05:00
parent e4542f7d1e
commit 4a1bb764cc
3 changed files with 147 additions and 13 deletions

View file

@ -39,6 +39,9 @@
//REMOVE ME
#include "ardour/mixer_snapshot.h"
#include <glibmm.h>
#include <glibmm/fileutils.h>
#include "ardour/filesystem_paths.h"
#include "ardour_ui.h"
#include "editor.h"
@ -229,8 +232,9 @@ void EditorRouteGroups::write() {
camera->write();
}
void EditorRouteGroups::load() {
camera->load();
void EditorRouteGroups::load() {
string path = Glib::build_filename(user_config_directory(-1), "snapshot.xml");
camera->load(path);
}
void

View file

@ -28,10 +28,11 @@
#include "ardour/vca.h"
#include "ardour/route_group.h"
class MixerSnapshot //: public PBD::Stateful
class MixerSnapshot
{
public:
MixerSnapshot(ARDOUR::Session*);
MixerSnapshot(ARDOUR::Session*, std::string);
~MixerSnapshot();
void snap();
@ -42,7 +43,25 @@ class MixerSnapshot //: public PBD::Stateful
void recall();
void clear();
void write();
void load();
void load(std::string);
struct State {
std::string id;
std::string name;
XMLNode node;
};
bool empty() {
return (
route_states.empty() &&
group_states.empty() &&
vca_states.empty()
);
};
std::vector<State> get_routes() {return route_states;};
std::vector<State> get_groups() {return group_states;};
std::vector<State> get_vcas() {return vca_states;};
int id;
std::string label;
@ -52,12 +71,9 @@ class MixerSnapshot //: public PBD::Stateful
ARDOUR::Session* _session;
void reassign_masters(boost::shared_ptr<ARDOUR::Slavable>, XMLNode);
void load_from_session(std::string);
void load_from_session(XMLNode&);
struct State {
std::string id;
std::string name;
XMLNode node;
};
std::vector<State> route_states;
std::vector<State> group_states;

View file

@ -3,11 +3,15 @@
#include "ardour/mixer_snapshot.h"
#include "ardour/route_group.h"
#include "ardour/vca_manager.h"
#include "ardour/session_state.h"
#include "ardour/filename_extensions.h"
#include "ardour/filesystem_paths.h"
#include "ardour/session_state_utils.h"
#include "pbd/i18n.h"
#include "pbd/xml++.h"
#include "pbd/memento_command.h"
#include "pbd/file_utils.h"
#include <glibmm.h>
#include <glibmm/fileutils.h>
@ -24,6 +28,17 @@ MixerSnapshot::MixerSnapshot(Session* s)
_session = s;
}
MixerSnapshot::MixerSnapshot(Session* s, string file_path)
: id(0)
, label("snapshot")
, timestamp(time(0))
{
if(s)
_session = s;
load_from_session(file_path);
}
MixerSnapshot::~MixerSnapshot()
{
}
@ -233,10 +248,12 @@ void MixerSnapshot::recall()
void MixerSnapshot::write()
{
//_session->mixer_settings_dir()
XMLNode* node = new XMLNode("MixerSnapshot");
XMLNode* child;
child = node->add_child ("Routes");
child = node->add_child("Routes");
for(vector<State>::iterator i = route_states.begin(); i != route_states.end(); i++) {
child->add_child_copy((*i).node);
}
@ -257,13 +274,15 @@ void MixerSnapshot::write()
tree.write(snap.c_str());
}
void MixerSnapshot::load()
void MixerSnapshot::load(string path)
{
clear();
string snap = Glib::build_filename(user_config_directory(-1), label + ".xml");
if(!Glib::file_test(path.c_str(), Glib::FILE_TEST_EXISTS))
return;
XMLTree tree;
tree.read(snap);
tree.read(path);
XMLNode* root = tree.root();
if(!root) {
@ -309,4 +328,99 @@ void MixerSnapshot::load()
vca_states.push_back(state);
}
}
}
void MixerSnapshot::load_from_session(string path)
{
clear();
vector<string> states;
if(Glib::file_test(path.c_str(), Glib::FILE_TEST_IS_DIR))
get_state_files_in_directory(path, states);
if(!states.empty())
load_from_session(states.front());
//final sanity check
if(!("." + PBD::get_suffix(path) == statefile_suffix))
return;
XMLTree tree;
tree.read(path);
XMLNode* root = tree.root();
if(!root) {
return;
}
}
void MixerSnapshot::load_from_session(XMLNode& node)
{
clear();
XMLNode* route_node = find_named_node(node, "Routes");
XMLNode* group_node = find_named_node(node, "RouteGroups");
XMLNode* vca_node = find_named_node(node, "VCAManager");
vector<pair<int,string>> number_name_pairs;
if(vca_node) {
XMLNodeList nlist = vca_node->children();
for(XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); niter++) {
string name, number, id;
(*niter)->get_property(X_("name"), name);
(*niter)->get_property(X_("number"), number);
(*niter)->get_property(X_("id"), id);
pair<int, string> pair (atoi(number.c_str()), name) ;
number_name_pairs.push_back(pair);
State state {id, name, (**niter)};
vca_states.push_back(state);
}
}
if(route_node) {
XMLNodeList nlist = route_node->children();
for(XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); niter++) {
string name, id;
(*niter)->get_property(X_("name"), name);
(*niter)->get_property(X_("id"), id);
/* ugly workaround - recall() expects
that a route's Slavable children has
the "name" property. Normal session state
files don't have this. So we stash it,
reverse look-up the "number", and then
add it to a copy of the node. */
XMLNode copy (**niter);
XMLNode* slavable = find_named_node(copy, "Slavable");
if(slavable) {
XMLNodeList nlist = slavable->children();
for(XMLNodeConstIterator siter = nlist.begin(); siter != nlist.end(); siter++) {
string number;
(*siter)->get_property(X_("number"), number);
for(vector<pair<int,string>>::const_iterator p = number_name_pairs.begin(); p != number_name_pairs.end(); p++) {
if((*p).first == atoi(number.c_str()))
(*siter)->set_property(X_("name"), (*p).second);
}
}
}
State state {id, name, copy};
route_states.push_back(state);
}
}
if(group_node) {
XMLNodeList nlist = group_node->children();
for(XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); niter++) {
string name, id;
(*niter)->get_property(X_("name"), name);
(*niter)->get_property(X_("id"), id);
State state {id, name, (**niter)};
group_states.push_back(state);
}
}
}