From edad92a9445e0b6efd9c1220dd37f02e27bcdee2 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 28 Apr 2012 01:43:38 +0000 Subject: [PATCH] control surfaces: make it possible to keep display of current GUI/selection state as we bank through tracks/bussses. note careful use of weak_ptr to avoid messing with Route lifetimes. this scheme may change git-svn-id: svn://localhost/ardour2/branches/3.0@12115 d708f5d6-7413-0410-9779-e7cbd77b26cf --- .../control_protocol/control_protocol/types.h | 6 ++- .../mackie/mackie_control_protocol.cc | 37 ++++++++++++++++--- .../surfaces/mackie/mackie_control_protocol.h | 7 +++- libs/surfaces/mackie/strip.cc | 4 +- libs/surfaces/mackie/strip.h | 2 +- libs/surfaces/mackie/surface.cc | 2 +- libs/surfaces/mackie/surface.h | 2 +- 7 files changed, 46 insertions(+), 14 deletions(-) diff --git a/libs/surfaces/control_protocol/control_protocol/types.h b/libs/surfaces/control_protocol/control_protocol/types.h index 0f81d87d0a..9e96383659 100644 --- a/libs/surfaces/control_protocol/control_protocol/types.h +++ b/libs/surfaces/control_protocol/control_protocol/types.h @@ -26,9 +26,11 @@ namespace ARDOUR { class Route; + + typedef std::vector > RouteNotificationList; + typedef boost::shared_ptr RouteNotificationListPtr; - typedef std::vector > RouteNotificationList; - typedef boost::shared_ptr RouteNotificationListPtr; + typedef std::vector > StrongRouteNotificationList; } #endif /* __ardour_control_protocol_types_h__ */ diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index 85b92cbeab..686f868d1b 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -113,7 +113,7 @@ MackieControlProtocol::MackieControlProtocol (Session& session) DeviceInfo::reload_device_info (); DeviceProfile::reload_device_profiles (); - TrackSelectionChanged.connect (gui_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::gui_track_selection_changed, this, _1), this); + TrackSelectionChanged.connect (gui_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::gui_track_selection_changed, this, _1, true), this); _instance = this; @@ -357,7 +357,7 @@ MackieControlProtocol::switch_banks (uint32_t initial, bool force) /* make sure selection is correct */ - // gui_track_selection_changed (_last_selected_routes); + _gui_track_selection_changed (&_last_selected_routes, false); /* current bank has not been saved */ session->set_dirty(); @@ -1204,13 +1204,40 @@ MackieControlProtocol::force_special_route_to_strip (boost::shared_ptr r, } void -MackieControlProtocol::gui_track_selection_changed (ARDOUR::RouteNotificationListPtr rl) +MackieControlProtocol::gui_track_selection_changed (ARDOUR::RouteNotificationListPtr rl, bool save_list) { + _gui_track_selection_changed (rl.get(), save_list); +} + +void +MackieControlProtocol::_gui_track_selection_changed (ARDOUR::RouteNotificationList* rl, bool save_list) +{ + + /* We need to keep a list of the most recently selected routes around, + but we are not allowed to keep shared_ptr unless we want to + handle the complexities of route deletion. So instead, the GUI sends + us a notification using weak_ptr, which we keep a copy + of. For efficiency's sake, however, we convert the weak_ptr's into + shared_ptr before passing them to however many surfaces (and + thus strips) that we have. + */ + + StrongRouteNotificationList srl; + + for (ARDOUR::RouteNotificationList::const_iterator i = rl->begin(); i != rl->end(); ++i) { + boost::shared_ptr r = (*i).lock(); + if (r) { + srl.push_back (r); + } + } + for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) { - (*s)->gui_selection_changed (rl); + (*s)->gui_selection_changed (srl); } - // _last_selected_routes = *rl; + if (save_list) { + _last_selected_routes = *rl; + } } framepos_t diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h index 8bcec0933a..818f44b13c 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.h +++ b/libs/surfaces/mackie/mackie_control_protocol.h @@ -285,7 +285,9 @@ class MackieControlProtocol ButtonMap button_map; int16_t _ipmidi_base; bool needs_ipmidi_restart; - + + ARDOUR::RouteNotificationList _last_selected_routes; + void create_surfaces (); bool periodic(); void build_gui (); @@ -293,7 +295,8 @@ class MackieControlProtocol void clear_ports (); void force_special_route_to_strip (boost::shared_ptr r, uint32_t surface, uint32_t strip_number); void build_button_map (); - void gui_track_selection_changed (ARDOUR::RouteNotificationListPtr); + void gui_track_selection_changed (ARDOUR::RouteNotificationListPtr, bool save_list); + void _gui_track_selection_changed (ARDOUR::RouteNotificationList*, bool save_list); void ipmidi_restart (); /* BUTTON HANDLING */ diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc index 4b0e918785..d7d9acd544 100644 --- a/libs/surfaces/mackie/strip.cc +++ b/libs/surfaces/mackie/strip.cc @@ -756,9 +756,9 @@ Strip::unlock_controls () } void -Strip::gui_selection_changed (ARDOUR::RouteNotificationListPtr rl) +Strip::gui_selection_changed (const ARDOUR::StrongRouteNotificationList& rl) { - for (ARDOUR::RouteNotificationList::iterator i = rl->begin(); i != rl->end(); ++i) { + for (ARDOUR::StrongRouteNotificationList::const_iterator i = rl.begin(); i != rl.end(); ++i) { if ((*i) == _route) { _surface->write (_select->set_state (on)); return; diff --git a/libs/surfaces/mackie/strip.h b/libs/surfaces/mackie/strip.h index d7e80c95e5..99e51ae6e1 100644 --- a/libs/surfaces/mackie/strip.h +++ b/libs/surfaces/mackie/strip.h @@ -82,7 +82,7 @@ public: void unlock_controls (); bool locked() const { return _controls_locked; } - void gui_selection_changed (ARDOUR::RouteNotificationListPtr); + void gui_selection_changed (const ARDOUR::StrongRouteNotificationList&); private: Button* _solo; diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc index fecc4d5a33..2053a963f2 100644 --- a/libs/surfaces/mackie/surface.cc +++ b/libs/surfaces/mackie/surface.cc @@ -793,7 +793,7 @@ Surface::update_view_mode_display () } void -Surface::gui_selection_changed (ARDOUR::RouteNotificationListPtr routes) +Surface::gui_selection_changed (const ARDOUR::StrongRouteNotificationList& routes) { for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) { (*s)->gui_selection_changed (routes); diff --git a/libs/surfaces/mackie/surface.h b/libs/surfaces/mackie/surface.h index 9f3ac0b8c6..f45a61ce6c 100644 --- a/libs/surfaces/mackie/surface.h +++ b/libs/surfaces/mackie/surface.h @@ -146,7 +146,7 @@ public: void update_view_mode_display (); void update_flip_mode_display (); - void gui_selection_changed (ARDOUR::RouteNotificationListPtr); + void gui_selection_changed (const ARDOUR::StrongRouteNotificationList&); MackieControlProtocol& mcp() const { return _mcp; }