Fixes to bundle manager to make it vaguely usable.
Rework signal handling for bundles so that all changes should now be noticed by port matrices. git-svn-id: svn://localhost/ardour2/branches/3.0@4501 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -57,24 +57,9 @@ class Bundle : public sigc::trackable
|
||||
PortList ports;
|
||||
};
|
||||
|
||||
/** Construct an audio bundle.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle (bool i = true) : _type (DataType::AUDIO), _ports_are_inputs (i) {}
|
||||
|
||||
/** Construct an audio bundle.
|
||||
* @param n Name.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {}
|
||||
|
||||
/** Construct a bundle.
|
||||
* @param n Name.
|
||||
* @param t Type.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle (std::string const & n, DataType t, bool i = true) : _name (n), _type (t), _ports_are_inputs (i) {}
|
||||
|
||||
Bundle (bool i = true);
|
||||
Bundle (std::string const &, bool i = true);
|
||||
Bundle (std::string const &, DataType, bool i = true);
|
||||
Bundle (boost::shared_ptr<Bundle>);
|
||||
|
||||
virtual ~Bundle() {}
|
||||
@@ -93,6 +78,8 @@ class Bundle : public sigc::trackable
|
||||
void add_port_to_channel (uint32_t, std::string);
|
||||
void set_port (uint32_t, std::string);
|
||||
void remove_port_from_channel (uint32_t, std::string);
|
||||
void remove_ports_from_channel (uint32_t);
|
||||
void remove_ports_from_channels ();
|
||||
bool port_attached_to_channel (uint32_t, std::string);
|
||||
bool uses_port (std::string) const;
|
||||
bool offers_port_alone (std::string) const;
|
||||
@@ -107,7 +94,7 @@ class Bundle : public sigc::trackable
|
||||
*/
|
||||
void set_name (std::string const & n) {
|
||||
_name = n;
|
||||
NameChanged ();
|
||||
Changed (NameChanged);
|
||||
}
|
||||
|
||||
/** @return Bundle name */
|
||||
@@ -126,14 +113,17 @@ class Bundle : public sigc::trackable
|
||||
bool ports_are_inputs () const { return _ports_are_inputs; }
|
||||
bool ports_are_outputs () const { return !_ports_are_inputs; }
|
||||
|
||||
bool operator== (Bundle const &) const;
|
||||
void suspend_signals ();
|
||||
void resume_signals ();
|
||||
|
||||
/** Emitted when the bundle name or a channel name has changed */
|
||||
sigc::signal<void> NameChanged;
|
||||
/** The number of channels has changed */
|
||||
sigc::signal<void> ConfigurationChanged;
|
||||
/** The port list associated with one of our channels has changed */
|
||||
sigc::signal<void, int> PortsChanged;
|
||||
/** Things that might change about this bundle */
|
||||
enum Change {
|
||||
NameChanged = 0x1, ///< the bundle name or a channel name has changed
|
||||
ConfigurationChanged = 0x2, ///< the number of channels has changed
|
||||
PortsChanged = 0x4 ///< the port list associated with one of our channels has changed
|
||||
};
|
||||
|
||||
sigc::signal<void, Change> Changed;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -145,10 +135,14 @@ class Bundle : public sigc::trackable
|
||||
private:
|
||||
int set_channels (std::string const &);
|
||||
int parse_io_string (std::string const &, std::vector<std::string> &);
|
||||
void emit_changed (Change);
|
||||
|
||||
std::string _name;
|
||||
DataType _type;
|
||||
bool _ports_are_inputs;
|
||||
|
||||
bool _signals_suspended;
|
||||
Change _pending_change;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <ardour/latent.h>
|
||||
#include <ardour/automation_control.h>
|
||||
#include <ardour/session_object.h>
|
||||
#include <ardour/bundle.h>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
@@ -53,8 +54,8 @@ namespace ARDOUR {
|
||||
|
||||
class Session;
|
||||
class AudioEngine;
|
||||
class Bundle;
|
||||
class UserBundle;
|
||||
class Bundle;
|
||||
class Panner;
|
||||
class PeakMeter;
|
||||
class Port;
|
||||
@@ -62,7 +63,6 @@ class AudioPort;
|
||||
class MidiPort;
|
||||
class BufferSet;
|
||||
|
||||
|
||||
/** A collection of input and output ports with connections.
|
||||
*
|
||||
* An IO can contain ports of varying types, making routes/inserts/etc with
|
||||
@@ -336,8 +336,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||
UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b);
|
||||
|
||||
boost::shared_ptr<UserBundle> bundle;
|
||||
sigc::connection configuration_changed;
|
||||
sigc::connection ports_changed;
|
||||
sigc::connection changed;
|
||||
};
|
||||
|
||||
std::vector<UserBundleInfo> _bundles_connected_to_outputs; ///< user bundles connected to our outputs
|
||||
@@ -357,8 +356,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||
void check_bundles_connected_to_outputs ();
|
||||
void check_bundles (std::vector<UserBundleInfo>&, const PortSet&);
|
||||
|
||||
void bundle_configuration_changed ();
|
||||
void bundle_ports_changed (int);
|
||||
void bundle_changed (Bundle::Change);
|
||||
|
||||
int create_ports (const XMLNode&);
|
||||
int make_connections (const XMLNode&);
|
||||
@@ -375,6 +373,8 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||
int32_t find_output_port_hole (const char* base);
|
||||
|
||||
void setup_bundles_for_inputs_and_outputs ();
|
||||
void setup_bundle_for_inputs ();
|
||||
void setup_bundle_for_outputs ();
|
||||
std::string bundle_channel_name (uint32_t, uint32_t) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -30,11 +30,57 @@
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
/** Construct an audio bundle.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle::Bundle (bool i)
|
||||
: _type (DataType::AUDIO),
|
||||
_ports_are_inputs (i),
|
||||
_signals_suspended (false),
|
||||
_pending_change (Change (0))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Construct an audio bundle.
|
||||
* @param n Name.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle::Bundle (std::string const & n, bool i)
|
||||
: _name (n),
|
||||
_type (DataType::AUDIO),
|
||||
_ports_are_inputs (i),
|
||||
_signals_suspended (false),
|
||||
_pending_change (Change (0))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Construct a bundle.
|
||||
* @param n Name.
|
||||
* @param t Type.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle::Bundle (std::string const & n, DataType t, bool i)
|
||||
: _name (n),
|
||||
_type (t),
|
||||
_ports_are_inputs (i),
|
||||
_signals_suspended (false),
|
||||
_pending_change (Change (0))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
Bundle::Bundle (boost::shared_ptr<Bundle> other)
|
||||
: _channel (other->_channel),
|
||||
_name (other->_name),
|
||||
_type (other->_type),
|
||||
_ports_are_inputs (other->_ports_are_inputs)
|
||||
_ports_are_inputs (other->_ports_are_inputs),
|
||||
_signals_suspended (other->_signals_suspended),
|
||||
_pending_change (other->_pending_change)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -69,8 +115,8 @@ Bundle::add_port_to_channel (uint32_t ch, string portname)
|
||||
Glib::Mutex::Lock lm (_channel_mutex);
|
||||
_channel[ch].ports.push_back (portname);
|
||||
}
|
||||
|
||||
PortsChanged (ch); /* EMIT SIGNAL */
|
||||
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
|
||||
/** Disassociate a port from one of our channels.
|
||||
@@ -96,20 +142,10 @@ Bundle::remove_port_from_channel (uint32_t ch, string portname)
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
PortsChanged (ch); /* EMIT SIGNAL */
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
}
|
||||
|
||||
/** operator== for Bundles; they are equal if their channels are the same.
|
||||
* @param other Bundle to compare with this one.
|
||||
*/
|
||||
bool
|
||||
Bundle::operator== (const Bundle& other) const
|
||||
{
|
||||
return other._channel == _channel;
|
||||
}
|
||||
|
||||
|
||||
/** Set a single port to be associated with a channel, removing any others.
|
||||
* @param ch Channel.
|
||||
* @param portname Full port name, including prefix.
|
||||
@@ -126,7 +162,7 @@ Bundle::set_port (uint32_t ch, string portname)
|
||||
_channel[ch].ports.push_back (portname);
|
||||
}
|
||||
|
||||
PortsChanged (ch); /* EMIT SIGNAL */
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
|
||||
/** @param n Channel name */
|
||||
@@ -138,7 +174,7 @@ Bundle::add_channel (std::string const & n)
|
||||
_channel.push_back (Channel (n));
|
||||
}
|
||||
|
||||
ConfigurationChanged (); /* EMIT SIGNAL */
|
||||
emit_changed (ConfigurationChanged);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -150,6 +186,9 @@ Bundle::port_attached_to_channel (uint32_t ch, std::string portname)
|
||||
return (std::find (_channel[ch].ports.begin (), _channel[ch].ports.end (), portname) != _channel[ch].ports.end ());
|
||||
}
|
||||
|
||||
/** Remove a channel.
|
||||
* @param ch Channel.
|
||||
*/
|
||||
void
|
||||
Bundle::remove_channel (uint32_t ch)
|
||||
{
|
||||
@@ -159,6 +198,7 @@ Bundle::remove_channel (uint32_t ch)
|
||||
_channel.erase (_channel.begin () + ch);
|
||||
}
|
||||
|
||||
/** Remove all channels */
|
||||
void
|
||||
Bundle::remove_channels ()
|
||||
{
|
||||
@@ -167,6 +207,9 @@ Bundle::remove_channels ()
|
||||
_channel.clear ();
|
||||
}
|
||||
|
||||
/** @param p Port name.
|
||||
* @return true if any channel is associated with p.
|
||||
*/
|
||||
bool
|
||||
Bundle::uses_port (std::string p) const
|
||||
{
|
||||
@@ -200,6 +243,10 @@ Bundle::offers_port_alone (std::string p) const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** @param ch Channel.
|
||||
* @return Channel name.
|
||||
*/
|
||||
std::string
|
||||
Bundle::channel_name (uint32_t ch) const
|
||||
{
|
||||
@@ -209,6 +256,10 @@ Bundle::channel_name (uint32_t ch) const
|
||||
return _channel[ch].name;
|
||||
}
|
||||
|
||||
/** Set the name of a channel.
|
||||
* @param ch Channel.
|
||||
* @param n New name.
|
||||
*/
|
||||
void
|
||||
Bundle::set_channel_name (uint32_t ch, std::string const & n)
|
||||
{
|
||||
@@ -219,7 +270,7 @@ Bundle::set_channel_name (uint32_t ch, std::string const & n)
|
||||
_channel[ch].name = n;
|
||||
}
|
||||
|
||||
NameChanged (); /* EMIT SIGNAL */
|
||||
emit_changed (NameChanged);
|
||||
}
|
||||
|
||||
/** Take the channels from another bundle and add them to this bundle,
|
||||
@@ -245,6 +296,11 @@ Bundle::add_channels_from_bundle (boost::shared_ptr<Bundle> other)
|
||||
}
|
||||
}
|
||||
|
||||
/** Connect the ports associated with our channels to the ports associated
|
||||
* with another bundle's channels.
|
||||
* @param other Other bundle.
|
||||
* @param engine AudioEngine to use to make the connections.
|
||||
*/
|
||||
void
|
||||
Bundle::connect (boost::shared_ptr<Bundle> other, AudioEngine & engine)
|
||||
{
|
||||
@@ -280,3 +336,62 @@ Bundle::disconnect (boost::shared_ptr<Bundle> other, AudioEngine & engine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove all ports from all channels */
|
||||
void
|
||||
Bundle::remove_ports_from_channels ()
|
||||
{
|
||||
{
|
||||
Glib::Mutex::Lock lm (_channel_mutex);
|
||||
for (uint32_t c = 0; c < _channel.size(); ++c) {
|
||||
_channel[c].ports.clear ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
|
||||
/** Remove all ports from a given channel.
|
||||
* @param ch Channel.
|
||||
*/
|
||||
void
|
||||
Bundle::remove_ports_from_channel (uint32_t ch)
|
||||
{
|
||||
assert (ch < nchannels ());
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock lm (_channel_mutex);
|
||||
_channel[ch].ports.clear ();
|
||||
}
|
||||
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
|
||||
void
|
||||
Bundle::suspend_signals ()
|
||||
{
|
||||
_signals_suspended = true;
|
||||
}
|
||||
|
||||
void
|
||||
Bundle::resume_signals ()
|
||||
{
|
||||
if (_pending_change) {
|
||||
Changed (_pending_change);
|
||||
_pending_change = Change (0);
|
||||
}
|
||||
|
||||
_signals_suspended = false;
|
||||
}
|
||||
|
||||
void
|
||||
Bundle::emit_changed (Change c)
|
||||
{
|
||||
if (_signals_suspended) {
|
||||
_pending_change = Change (int (_pending_change) | int (c));
|
||||
} else {
|
||||
Changed (c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -396,8 +396,7 @@ IO::check_bundles (std::vector<UserBundleInfo>& list, const PortSet& ports)
|
||||
if (ok) {
|
||||
new_list.push_back (*i);
|
||||
} else {
|
||||
i->configuration_changed.disconnect ();
|
||||
i->ports_changed.disconnect ();
|
||||
i->changed.disconnect ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,7 +603,7 @@ IO::remove_output_port (Port* port, void* src)
|
||||
}
|
||||
|
||||
if (change == ConfigurationChanged) {
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_outputs ();
|
||||
}
|
||||
|
||||
if (change != NoChange) {
|
||||
@@ -666,7 +665,7 @@ IO::add_output_port (string destination, void* src, DataType type)
|
||||
|
||||
// pan_changed (src); /* EMIT SIGNAL */
|
||||
output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_outputs ();
|
||||
_session.set_dirty ();
|
||||
|
||||
return 0;
|
||||
@@ -708,7 +707,7 @@ IO::remove_input_port (Port* port, void* src)
|
||||
}
|
||||
|
||||
if (change == ConfigurationChanged) {
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_inputs ();
|
||||
}
|
||||
|
||||
if (change != NoChange) {
|
||||
@@ -771,7 +770,7 @@ IO::add_input_port (string source, void* src, DataType type)
|
||||
|
||||
// pan_changed (src); /* EMIT SIGNAL */
|
||||
input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_inputs ();
|
||||
_session.set_dirty ();
|
||||
|
||||
return 0;
|
||||
@@ -1013,16 +1012,17 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
||||
if (out_changed) {
|
||||
check_bundles_connected_to_outputs ();
|
||||
output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundle_for_outputs ();
|
||||
}
|
||||
|
||||
if (in_changed) {
|
||||
check_bundles_connected_to_inputs ();
|
||||
input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundle_for_inputs ();
|
||||
}
|
||||
|
||||
if (in_changed || out_changed) {
|
||||
PortCountChanged (max (n_outputs(), n_inputs())); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
||||
@@ -1050,7 +1050,7 @@ IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src)
|
||||
|
||||
if (changed) {
|
||||
input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_inputs ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
return 0;
|
||||
@@ -1142,7 +1142,7 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
|
||||
|
||||
if (changed) {
|
||||
output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_outputs ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2220,19 +2220,12 @@ IO::reset_panners ()
|
||||
}
|
||||
|
||||
void
|
||||
IO::bundle_configuration_changed ()
|
||||
IO::bundle_changed (Bundle::Change c)
|
||||
{
|
||||
//XXX
|
||||
// connect_input_ports_to_bundle (_input_bundle, this);
|
||||
}
|
||||
|
||||
void
|
||||
IO::bundle_ports_changed (int ignored)
|
||||
{
|
||||
//XXX
|
||||
// connect_output_ports_to_bundle (_output_bundle, this);
|
||||
}
|
||||
|
||||
void
|
||||
IO::GainControl::set_value (float val)
|
||||
{
|
||||
@@ -2614,19 +2607,25 @@ IO::update_port_total_latencies ()
|
||||
|
||||
void
|
||||
IO::setup_bundles_for_inputs_and_outputs ()
|
||||
{
|
||||
setup_bundle_for_inputs ();
|
||||
setup_bundle_for_outputs ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IO::setup_bundle_for_inputs ()
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
if (!_bundle_for_inputs) {
|
||||
_bundle_for_inputs.reset (new Bundle (true));
|
||||
}
|
||||
if (!_bundle_for_outputs) {
|
||||
_bundle_for_outputs.reset (new Bundle (false));
|
||||
}
|
||||
|
||||
_bundle_for_inputs->suspend_signals ();
|
||||
|
||||
_bundle_for_inputs->remove_channels ();
|
||||
_bundle_for_outputs->remove_channels ();
|
||||
|
||||
|
||||
snprintf(buf, sizeof (buf), _("%s in"), _name.c_str());
|
||||
_bundle_for_inputs->set_name (buf);
|
||||
uint32_t const ni = inputs().num_ports();
|
||||
@@ -2635,6 +2634,23 @@ IO::setup_bundles_for_inputs_and_outputs ()
|
||||
_bundle_for_inputs->set_port (i, _session.engine().make_port_name_non_relative (inputs().port(i)->name()));
|
||||
}
|
||||
|
||||
_bundle_for_inputs->resume_signals ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IO::setup_bundle_for_outputs ()
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
if (!_bundle_for_outputs) {
|
||||
_bundle_for_outputs.reset (new Bundle (false));
|
||||
}
|
||||
|
||||
_bundle_for_outputs->suspend_signals ();
|
||||
|
||||
_bundle_for_outputs->remove_channels ();
|
||||
|
||||
snprintf(buf, sizeof (buf), _("%s out"), _name.c_str());
|
||||
_bundle_for_outputs->set_name (buf);
|
||||
uint32_t const no = outputs().num_ports();
|
||||
@@ -2642,8 +2658,11 @@ IO::setup_bundles_for_inputs_and_outputs ()
|
||||
_bundle_for_outputs->add_channel (bundle_channel_name (i, no));
|
||||
_bundle_for_outputs->set_port (i, _session.engine().make_port_name_non_relative (outputs().port(i)->name()));
|
||||
}
|
||||
|
||||
_bundle_for_outputs->resume_signals ();
|
||||
}
|
||||
|
||||
|
||||
/** @return Bundles connected to our inputs */
|
||||
BundleList
|
||||
IO::bundles_connected_to_inputs ()
|
||||
@@ -2711,11 +2730,8 @@ IO::bundles_connected_to_outputs ()
|
||||
IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b)
|
||||
{
|
||||
bundle = b;
|
||||
configuration_changed = b->ConfigurationChanged.connect (
|
||||
sigc::mem_fun (*io, &IO::bundle_configuration_changed)
|
||||
);
|
||||
ports_changed = b->PortsChanged.connect (
|
||||
sigc::mem_fun (*io, &IO::bundle_ports_changed)
|
||||
changed = b->Changed.connect (
|
||||
sigc::mem_fun (*io, &IO::bundle_changed)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,12 @@ ARDOUR::UserBundle::set_state (XMLNode const & node)
|
||||
return -1;
|
||||
}
|
||||
|
||||
add_channel ("XXX");
|
||||
if ((name = (*i)->property ("name")) == 0) {
|
||||
PBD::error << _("Node for Channel has no \"name\" property") << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
add_channel (name->value ());
|
||||
|
||||
XMLNodeList const ports = (*i)->children ();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user