further efforts at cleaning up the design of the interaction/relationship between route sort order keys and remote control IDs

git-svn-id: svn://localhost/ardour2/branches/3.0@12962 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2012-06-28 22:27:37 +00:00
parent 81de53da1d
commit 7db500301d
7 changed files with 201 additions and 77 deletions

View File

@@ -817,25 +817,14 @@ EditorRoutes::sync_order_keys_from_model ()
bool changed = false;
uint32_t order = 0;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
for (ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
boost::shared_ptr<Route> route = (*ri)[_columns.route];
bool visible = (*ri)[_columns.visible];
uint32_t old_key = route->order_key (EditorSort);
uint32_t new_key;
if (!visible) {
new_key = UINT_MAX;
} else {
new_key = order;
}
if (old_key != new_key) {
route->set_order_key (EditorSort, new_key);
if (order != old_key) {
route->set_order_key (EditorSort, order);
changed = true;
}
order++;
}
if (changed) {
@@ -847,6 +836,10 @@ EditorRoutes::sync_order_keys_from_model ()
void
EditorRoutes::sync_model_from_order_keys (RouteSortOrderKey src)
{
/* Some route order key(s) for `src' has been changed, make sure that
we update out tree/list model and GUI to reflect the change.
*/
if (!_session || _session->deletion_in_progress()) {
return;
}
@@ -880,7 +873,8 @@ EditorRoutes::sync_model_from_order_keys (RouteSortOrderKey src)
vector<int> neworder;
TreeModel::Children rows = _model->children();
uint32_t n = 0;
uint32_t old_order = 0;
bool changed = false;
if (rows.empty()) {
return;
@@ -888,14 +882,22 @@ EditorRoutes::sync_model_from_order_keys (RouteSortOrderKey src)
neworder.assign (rows.size(), 0);
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++n) {
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) {
boost::shared_ptr<Route> route = (*ri)[_columns.route];
neworder[route->order_key (EditorSort)] = n;
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("editor change order for %1 to %2\n",
route->name(), route->order_key (MixerSort)));
uint32_t new_order = route->order_key (EditorSort);
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("editor change order for %1 from %2 to %3\n",
route->name(), old_order, new_order));
neworder[new_order] = old_order;
if (old_order != new_order) {
changed = true;
}
}
{
if (changed) {
Unwinder<bool> uw (_ignore_reorder, true);
_model->reorder (neworder);
}

View File

@@ -413,25 +413,14 @@ Mixer_UI::sync_order_keys_from_model ()
bool changed = false;
uint32_t order = 0;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
for (ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
bool visible = (*ri)[track_columns.visible];
uint32_t old_key = route->order_key (MixerSort);
uint32_t new_key;
if (!visible) {
new_key = UINT_MAX;
} else {
new_key = order;
}
if (old_key != new_key) {
route->set_order_key (MixerSort, new_key);
if (old_key != order) {
route->set_order_key (MixerSort, order);
changed = true;
}
order++;
}
if (changed) {
@@ -477,6 +466,7 @@ Mixer_UI::sync_model_from_order_keys (RouteSortOrderKey src)
vector<int> neworder;
TreeModel::Children rows = track_model->children();
uint32_t n = 0;
bool changed = false;
if (rows.empty()) {
return;
@@ -486,12 +476,19 @@ Mixer_UI::sync_model_from_order_keys (RouteSortOrderKey src)
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++n) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
neworder[route->order_key (MixerSort)] = n;
uint32_t o = route->order_key (MixerSort);
neworder[o] = n;
if (o != n) {
changed = true;
}
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("mixer change order for %1 to %2\n",
route->name(), route->order_key (MixerSort)));
}
{
if (changed) {
Unwinder<bool> uw (ignore_reorder, true);
track_model->reorder (neworder);
}
@@ -985,6 +982,8 @@ Mixer_UI::initial_track_display ()
track_model->clear ();
add_strips (copy);
}
_session->sync_order_keys (MixerSort);
redisplay_track_list ();
}

View File

@@ -423,6 +423,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
void set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
uint32_t remote_control_id () const;
void set_remote_control_id_from_order_key (RouteSortOrderKey);
/* for things concerned about *this* route's RID */
@@ -534,7 +535,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
typedef std::map<RouteSortOrderKey,uint32_t> OrderKeys;
OrderKeys order_keys;
uint32_t* _remote_control_id;
uint32_t _remote_control_id;
void input_change_handler (IOChange, void *src);
void output_change_handler (IOChange, void *src);

View File

@@ -235,6 +235,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
};
void sync_order_keys (RouteSortOrderKey);
void sync_remote_id_from_order_keys (RouteSortOrderKey);
template<class T> void foreach_route (T *obj, void (T::*func)(Route&));
template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>));

View File

@@ -195,8 +195,6 @@ Route::~Route ()
}
_processors.clear ();
delete _remote_control_id;
}
void
@@ -232,11 +230,9 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
}
if (id != remote_control_id()) {
if (!_remote_control_id) {
_remote_control_id = new uint32_t;
}
*_remote_control_id = id;
_remote_control_id = id;
RemoteControlIDChanged ();
if (notify_class_listeners) {
RemoteControlIDChange ();
}
@@ -246,16 +242,6 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
uint32_t
Route::remote_control_id() const
{
switch (Config->get_remote_model()) {
case UserOrdered:
if (_remote_control_id) {
return *_remote_control_id;
}
break;
default:
break;
}
if (is_master()) {
return MasterBusRemoteControlID;
}
@@ -264,16 +250,7 @@ Route::remote_control_id() const
return MonitorBusRemoteControlID;
}
/* order keys are zero-based, remote control ID's are one-based
*/
switch (Config->get_remote_model()) {
case EditorOrdered:
return order_key (EditorSort) + 1;
case MixerOrdered:
default:
return order_key (MixerSort) + 1;
}
return _remote_control_id;
}
bool
@@ -297,6 +274,10 @@ Route::order_key (RouteSortOrderKey key) const
void
Route::sync_order_keys (RouteSortOrderKey base)
{
/* this is called after changes to 1 or more route order keys have been
* made, and we want to sync up.
*/
OrderKeys::iterator i = order_keys.find (base);
if (i == order_keys.end()) {
@@ -305,27 +286,86 @@ Route::sync_order_keys (RouteSortOrderKey base)
for (OrderKeys::iterator k = order_keys.begin(); k != order_keys.end(); ++k) {
if (k->first == MixerSort && (is_master() || is_monitor())) {
/* don't sync the mixer sort keys for master/monitor,
if (is_master() || is_monitor()) {
/* don't sync the sort keys for master/monitor,
* since they are not part of the normal ordering.
*/
continue;
}
if (k->first != base) {
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 set key for %2 to %3 from %4\n",
name(),
enum_2_string (k->first),
i->second,
base));
k->second = i->second;
}
}
}
void
Route::set_remote_control_id_from_order_key (RouteSortOrderKey key)
{
if (is_master() || is_monitor() || is_hidden()) {
return;
}
uint32_t n = order_keys[key];
switch (Config->get_remote_model()) {
case UserOrdered:
break;
case EditorOrdered:
if (key == EditorSort) {
boost::shared_ptr<Route> master = _session.master_out();
if (master && n > 0 && n > master->order_key (EditorSort)) {
--n;
}
_remote_control_id = n + 1;
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: from order key %2, set edit-based RID to %3\n",
name(), n, _remote_control_id));
RemoteControlIDChanged (); /* EMIT SIGNAL * (per-route) */
}
break;
case MixerOrdered:
if (key == MixerSort) {
boost::shared_ptr<Route> master = _session.master_out();
if (master && n > 0 && n > master->order_key (MixerSort)) {
--n;
}
_remote_control_id = n + 1;
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: from order key %2, set mix-based RID to %3\n",
name(), n, _remote_control_id));
RemoteControlIDChanged (); /* EMIT SIGNAL (per-route) */
}
break;
}
/* don't emit class-level RID signals here, leave that to the entity
that changed the order key, so that we don't get lots
of emissions for no good reasons (e.g. when changing all
route order keys)
*/
}
void
Route::set_order_key (RouteSortOrderKey key, uint32_t n)
{
if (order_keys.find (key) == order_keys.end() || order_keys[key] != n) {
order_keys[key] = n;
_session.set_dirty ();
OrderKeys::iterator i = order_keys.find (key);
if (i != order_keys.end() && i->second == n) {
return;
}
order_keys[key] = n;
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 order key %2 set to %3 (chk=%4)\n",
name(), enum_2_string (key), n, order_key (key)));
_session.set_dirty ();
}
string
@@ -1894,12 +1934,10 @@ Route::state(bool full_state)
node->add_child_nocopy (_mute_control->get_state ());
node->add_child_nocopy (_mute_master->get_state ());
if (_remote_control_id) {
XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
snprintf (buf, sizeof (buf), "%d", *_remote_control_id);
remote_control_node->add_property (X_("id"), buf);
node->add_child_nocopy (*remote_control_node);
}
XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
snprintf (buf, sizeof (buf), "%d", _remote_control_id);
remote_control_node->add_property (X_("id"), buf);
node->add_child_nocopy (*remote_control_node);
if (_comment.length()) {
XMLNode *cmt = node->add_child ("Comment");

View File

@@ -2205,7 +2205,22 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output
}
RouteAdded (new_routes); /* EMIT SIGNAL */
Route::RemoteControlIDChange (); /* EMIT SIGNAL */
/* we added at least one new route, and everyone who needs to has now
* handled this event. This means that route order keys are correctly
* set and we can now ensure that remote control IDs are set.
*/
switch (Config->get_remote_model()) {
case UserOrdered:
break;
case MixerOrdered:
sync_remote_id_from_order_keys (MixerSort);
break;
case EditorOrdered:
sync_remote_id_from_order_keys (EditorSort);
break;
}
}
void
@@ -4714,11 +4729,54 @@ Session::sync_order_keys (RouteSortOrderKey sort_key_changed)
/* tell everyone that something has happened to the sort keys
and let them sync up with the change(s)
this will give objects that manage the sort order keys the
opportunity to keep them in sync if they wish to.
*/
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("Sync Order Keys, based on %1\n", enum_2_string (sort_key_changed)));
Route::SyncOrderKeys (sort_key_changed); /* EMIT SIGNAL */
/* ensure that remote control IDs are in sync with the relevant
order keys.
*/
sync_remote_id_from_order_keys (sort_key_changed);
}
void
Session::sync_remote_id_from_order_keys (RouteSortOrderKey sort_key_changed)
{
/* update remote control IDs if that makes sense */
bool do_update = false;
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("sync RID to order key %1\n", enum_2_string (sort_key_changed)));
switch (Config->get_remote_model()) {
case UserOrdered:
break;
case EditorOrdered:
if (sort_key_changed == EditorSort) {
do_update = true;
}
break;
case MixerOrdered:
if (sort_key_changed == MixerSort) {
do_update = true;
}
break;
}
if (do_update) {
DEBUG_TRACE (DEBUG::OrderKeys, "\tactually update + signal\n");
boost::shared_ptr<RouteList> r = routes.reader();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_remote_control_id_from_order_key (sort_key_changed);
}
Route::RemoteControlIDChange (); /* EMIT SIGNAL - static */
}
}
bool

View File

@@ -3506,8 +3506,33 @@ Session::config_changed (std::string p, bool ours)
setup_fpu ();
} else if (p == "history-depth") {
set_history_depth (Config->get_history_depth());
} else if (p == "remote-model") {
switch (Config->get_remote_model()) {
case UserOrdered:
break;
case MixerOrdered:
sync_remote_id_from_order_keys (MixerSort);
break;
case EditorOrdered:
sync_remote_id_from_order_keys (EditorSort);
break;
}
} else if (p == "sync-all-route-ordering") {
/* XXX sync_order_keys (UndefinedSort); */
/* sync to editor order unless mixer is used for remote IDs
*/
switch (Config->get_remote_model()) {
case UserOrdered:
sync_order_keys (EditorSort);
break;
case EditorOrdered:
sync_order_keys (EditorSort);
break;
case MixerOrdered:
sync_order_keys (MixerSort);
}
} else if (p == "initial-program-change") {
if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {