fix peak-thread, GUI-thread race condition
[ardour.git] / gtk2_ardour / editor_routes.cc
index c7ad7c54ffa7dee36d3baae45c82f6f1d8e65f5f..b249c0a100364ac4ce631e1336d295286e0411dc 100644 (file)
@@ -72,12 +72,13 @@ EditorRoutes::EditorRoutes (Editor* e)
        , _no_redisplay (false)
        , _adding_routes (false)
        , _route_deletion_in_progress (false)
+       , _redisplay_on_resume (false)
        , _redisplay_active (0)
        , _queue_tv_update (0)
        , _menu (0)
        , old_focus (0)
        , selection_countdown (0)
-               , name_editable (0)
+       , name_editable (0)
 {
        static const int column_width = 22;
 
@@ -203,15 +204,15 @@ EditorRoutes::EditorRoutes (Editor* e)
        Gtk::Label* l;
 
        ColumnInfo ci[] = {
-               { 0, _("Name"), _("Track/Bus Name") },
-               { 1, _("V"), _("Track/Bus visible ?") },
-               { 2, _("A"), _("Track/Bus active ?") },
-               { 3, _("I"), _("MIDI input enabled") },
-               { 4, _("R"), _("Record enabled") },
-               { 5, _("M"), _("Muted") },
-               { 6, _("S"), _("Soloed") },
-               { 7, _("SI"), _("Solo Isolated") },
-               { 8, _("SS"), _("Solo Safe (Locked)") },
+               { 0,  _("Name"),        _("Track/Bus Name") },
+               { 1, S_("Visible|V"),   _("Track/Bus visible ?") },
+               { 2, S_("Active|A"),    _("Track/Bus active ?") },
+               { 3, S_("MidiInput|I"), _("MIDI input enabled") },
+               { 4, S_("Rec|R"),       _("Record enabled") },
+               { 5, S_("Mute|M"),      _("Muted") },
+               { 6, S_("Solo|S"),      _("Soloed") },
+               { 7, S_("SoloIso|SI"),  _("Solo Isolated") },
+               { 8, S_("SoloLock|SS"), _("Solo Safe (Locked)") },
                { -1, 0, 0 }
        };
 
@@ -360,6 +361,13 @@ EditorRoutes::set_session (Session* s)
        if (_session) {
                _session->SoloChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::solo_changed_so_update_mute, this), gui_context());
                _session->RecordStateChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_rec_display, this), gui_context());
+
+               /* TODO: check if these needs to be tied in with DisplaySuspender
+                * Given that the UI is single-threaded and DisplaySuspender is only used
+                * in loops in the UI thread all should be fine.
+                */
+               _session->BatchUpdateStart.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::suspend_redisplay, this), gui_context());
+               _session->BatchUpdateEnd.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::resume_redisplay, this), gui_context());
        }
 }
 
@@ -516,7 +524,7 @@ EditorRoutes::redisplay_real ()
                }
 
                bool visible = tv->marked_for_display ();
-
+               
                /* show or hide the TimeAxisView */
                if (visible) {
                        position += tv->show_at (position, n, &_editor->edit_controls_vbox);
@@ -549,7 +557,12 @@ EditorRoutes::redisplay_real ()
 void
 EditorRoutes::redisplay ()
 {
-       if (_no_redisplay || !_session || _session->deletion_in_progress()) {
+       if (!_session || _session->deletion_in_progress()) {
+               return;
+       }
+
+       if (_no_redisplay) {
+               _redisplay_on_resume = true;
                return;
        }
 
@@ -636,7 +649,6 @@ void
 EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
 {
        PBD::Unwinder<bool> at (_adding_routes, true);
-
        bool from_scratch = (_model->children().size() == 0);
        Gtk::TreeModel::Children::iterator insert_iter = _model->children().end();
 
@@ -649,10 +661,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
                }
        }
 
-       if(!from_scratch) {
-               _editor->selection->tracks.clear();
-       }
-
        DisplaySuspender ds;
 
        _display.set_model (Glib::RefPtr<ListStore>());
@@ -685,10 +693,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
                row[_columns.solo_safe_state] = (*x)->route()->solo_safe();
                row[_columns.name_editable] = true;
 
-               if (!from_scratch) {
-                       _editor->selection->add(*x);
-               }
-
                boost::weak_ptr<Route> wr ((*x)->route());
 
                (*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
@@ -725,8 +729,9 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
        _display.set_model (_model);
 
        /* now update route order keys from the treeview/track display order */
-
-       sync_order_keys_from_treeview ();
+       if (!from_scratch) {
+               sync_order_keys_from_treeview ();
+       }
 }
 
 void
@@ -879,10 +884,19 @@ EditorRoutes::reset_remote_control_ids ()
 
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
 
+               /* skip two special values */
+               
+               if (rid == Route::MasterBusRemoteControlID) {
+                       rid++;
+               }
+               
+               if (rid == Route::MonitorBusRemoteControlID) {
+                       rid++;
+               }
+
                boost::shared_ptr<Route> route = (*ri)[_columns.route];
                bool visible = (*ri)[_columns.visible];
 
-
                if (!route->is_master() && !route->is_monitor()) {
 
                        uint32_t new_rid = (visible ? rid : invisible_key--);
@@ -1393,29 +1407,10 @@ EditorRoutes::initial_display ()
                return;
        }
 
-       boost::shared_ptr<RouteList> routes = _session->get_routes();
-
-       if (ARDOUR_UI::instance()->session_is_new ()) {
-
-               /* new session: stamp all routes with the right editor order
-                * key
-                */
-
-               _editor->add_routes (*(routes.get()));
-
-       } else {
-
-               /* existing session: sort a copy of the route list by
-                * editor-order and add its contents to the display.
-                */
-
-               RouteList r (*routes);
-               EditorOrderRouteSorter sorter;
-
-               r.sort (sorter);
-               _editor->add_routes (r);
-
-       }
+       RouteList r (*_session->get_routes());
+               
+       r.sort (EditorOrderRouteSorter ());
+       _editor->add_routes (r);
 }
 
 void