make track templates work, including a fix for the MidiTrack XML constructor

git-svn-id: svn://localhost/ardour2/branches/3.0@4735 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-03-05 17:27:05 +00:00
parent d50b65773a
commit 55a367837a
9 changed files with 102 additions and 40 deletions

View file

@ -71,6 +71,7 @@ class AudioTrack : public Track
private: private:
int set_diskstream (boost::shared_ptr<AudioDiskstream>, void *); int set_diskstream (boost::shared_ptr<AudioDiskstream>, void *);
int deprecated_use_diskstream_connections (); int deprecated_use_diskstream_connections ();
void use_new_diskstream ();
void set_state_part_two (); void set_state_part_two ();
void set_state_part_three (); void set_state_part_three ();
}; };

View file

@ -99,6 +99,7 @@ private:
nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset); nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
int set_diskstream (boost::shared_ptr<MidiDiskstream> ds); int set_diskstream (boost::shared_ptr<MidiDiskstream> ds);
void use_new_diskstream ();
void set_state_part_two (); void set_state_part_two ();
void set_state_part_three (); void set_state_part_three ();

View file

@ -83,6 +83,7 @@ class Track : public Route
XMLNode& get_state(); XMLNode& get_state();
XMLNode& get_template(); XMLNode& get_template();
virtual int set_state(const XMLNode& node) = 0; virtual int set_state(const XMLNode& node) = 0;
static void zero_diskstream_id_in_xml (XMLNode&);
boost::shared_ptr<PBD::Controllable> rec_enable_control() { return _rec_enable_control; } boost::shared_ptr<PBD::Controllable> rec_enable_control() { return _rec_enable_control; }

View file

@ -51,23 +51,7 @@ using namespace PBD;
AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
: Track (sess, name, flag, mode) : Track (sess, name, flag, mode)
{ {
AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0); use_new_diskstream ();
if (_flags & Hidden) {
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
} else {
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
}
if (mode == Destructive) {
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
}
boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, name, dflags));
_session.add_diskstream (ds);
set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
} }
AudioTrack::AudioTrack (Session& sess, const XMLNode& node) AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
@ -80,6 +64,28 @@ AudioTrack::~AudioTrack ()
{ {
} }
void
AudioTrack::use_new_diskstream ()
{
AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
if (_flags & Hidden) {
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
} else {
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
}
if (_mode == Destructive) {
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
}
boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, name(), dflags));
_session.add_diskstream (ds);
set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
}
int int
AudioTrack::set_mode (TrackMode m) AudioTrack::set_mode (TrackMode m)
{ {
@ -265,8 +271,19 @@ AudioTrack::_set_state (const XMLNode& node, bool call_base)
} else { } else {
PBD::ID id (prop->value()); PBD::ID id (prop->value());
PBD::ID zero ("0");
if (use_diskstream (id)) { /* this wierd hack is used when creating tracks from a template. there isn't
a particularly good time to interpose between setting the first part of
the track state (notably Route::set_state() and the track mode), and the
second part (diskstream stuff). So, we have a special ID for the diskstream
that means "you should create a new diskstream here, not look for
an old one.
*/
if (id == zero) {
use_new_diskstream ();
} else if (use_diskstream (id)) {
return -1; return -1;
} }
} }
@ -288,7 +305,11 @@ AudioTrack::_set_state (const XMLNode& node, bool call_base)
pending_state = const_cast<XMLNode*> (&node); pending_state = const_cast<XMLNode*> (&node);
_session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two)); if (_session.state_of_the_state() & Session::Loading) {
_session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two));
} else {
set_state_part_two ();
}
return 0; return 0;
} }

View file

@ -51,20 +51,7 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo
, _immediate_events(1024) // FIXME: size? , _immediate_events(1024) // FIXME: size?
, _note_mode(Sustained) , _note_mode(Sustained)
{ {
MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0); use_new_diskstream ();
if (_flags & Hidden) {
dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
} else {
dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable);
}
assert(mode != Destructive);
boost::shared_ptr<MidiDiskstream> ds (new MidiDiskstream (_session, name, dflags));
_session.add_diskstream (ds);
set_diskstream (boost::dynamic_pointer_cast<MidiDiskstream> (ds));
_declickable = true; _declickable = true;
_freeze_record.state = NoFreeze; _freeze_record.state = NoFreeze;
@ -98,6 +85,24 @@ MidiTrack::~MidiTrack ()
{ {
} }
void
MidiTrack::use_new_diskstream ()
{
MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
if (_flags & Hidden) {
dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
} else {
dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable);
}
assert(_mode != Destructive);
boost::shared_ptr<MidiDiskstream> ds (new MidiDiskstream (_session, name(), dflags));
_session.add_diskstream (ds);
set_diskstream (boost::dynamic_pointer_cast<MidiDiskstream> (ds));
}
int int
MidiTrack::set_diskstream (boost::shared_ptr<MidiDiskstream> ds) MidiTrack::set_diskstream (boost::shared_ptr<MidiDiskstream> ds)
@ -191,13 +196,23 @@ MidiTrack::_set_state (const XMLNode& node, bool call_base)
} else { } else {
PBD::ID id (prop->value()); PBD::ID id (prop->value());
PBD::ID zero ("0");
if (use_diskstream (id)) { /* this wierd hack is used when creating tracks from a template. there isn't
a particularly good time to interpose between setting the first part of
the track state (notably Route::set_state() and the track mode), and the
second part (diskstream stuff). So, we have a special ID for the diskstream
that means "you should create a new diskstream here, not look for
an old one.
*/
if (id == zero) {
use_new_diskstream ();
} else if (use_diskstream (id)) {
return -1; return -1;
} }
} }
XMLNodeList nlist; XMLNodeList nlist;
XMLNodeConstIterator niter; XMLNodeConstIterator niter;
XMLNode *child; XMLNode *child;
@ -214,7 +229,11 @@ MidiTrack::_set_state (const XMLNode& node, bool call_base)
pending_state = const_cast<XMLNode*> (&node); pending_state = const_cast<XMLNode*> (&node);
_session.StateReady.connect (mem_fun (*this, &MidiTrack::set_state_part_two)); if (_session.state_of_the_state() & Session::Loading) {
_session.StateReady.connect (mem_fun (*this, &MidiTrack::set_state_part_two));
} else {
set_state_part_two ();
}
return 0; return 0;
} }

View file

@ -2224,7 +2224,6 @@ Route::_set_state (const XMLNode& node, bool call_base)
child = *niter; child = *niter;
if (child->name() == IO::state_node_name && call_base) { if (child->name() == IO::state_node_name && call_base) {
IO::set_state (*child); IO::set_state (*child);
break; break;
} }

View file

@ -2024,9 +2024,11 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template
/*NOTREACHED*/ /*NOTREACHED*/
} }
IO::set_name_in_state (node_copy, name); IO::set_name_in_state (*node_copy.children().front(), name);
} }
Track::zero_diskstream_id_in_xml (node_copy);
try { try {
shared_ptr<Route> route (XMLRouteFactory (node_copy)); shared_ptr<Route> route (XMLRouteFactory (node_copy));
@ -2035,6 +2037,15 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template
goto out; goto out;
} }
if (boost::dynamic_pointer_cast<Track>(route)) {
/* force input/output change signals so that the new diskstream
picks up the configuration of the route. During session
loading this normally happens in a different way.
*/
route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
}
route->set_remote_control_id (control_id); route->set_remote_control_id (control_id);
++control_id; ++control_id;

View file

@ -1408,8 +1408,10 @@ Session::XMLRouteFactory (const XMLNode& node)
DataType type = DataType::AUDIO; DataType type = DataType::AUDIO;
const XMLProperty* prop = node.property("default-type"); const XMLProperty* prop = node.property("default-type");
if (prop)
if (prop) {
type = DataType(prop->value()); type = DataType(prop->value());
}
assert(type != DataType::NIL); assert(type != DataType::NIL);

View file

@ -50,7 +50,7 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data
} }
Track::Track (Session& sess, const XMLNode& node, DataType default_type) Track::Track (Session& sess, const XMLNode& node, DataType default_type)
: Route (sess, node) : Route (sess, node, default_type)
, _rec_enable_control (new RecEnableControllable(*this)) , _rec_enable_control (new RecEnableControllable(*this))
{ {
_freeze_record.state = NoFreeze; _freeze_record.state = NoFreeze;
@ -228,3 +228,10 @@ Track::set_latency_delay (nframes_t longest_session_latency)
_diskstream->set_roll_delay (_roll_delay); _diskstream->set_roll_delay (_roll_delay);
} }
void
Track::zero_diskstream_id_in_xml (XMLNode& node)
{
if (node.property ("diskstream-id")) {
node.add_property ("diskstream-id", "0");
}
}