From 371bb416a018638564ac1fd78f3df3200b8ae607 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Dec 2025 12:15:13 -0700 Subject: [PATCH] Use shared_ptr to manage RouteGroups everywhere (libs edition) This also drops Session::_all_route_group which was not used, and makes a little more use of PBD::Unwinder in a few route group-related contexts. --- libs/ardour/ardour/route_group.h | 22 ++++---- libs/ardour/ardour/route_group_member.h | 11 ++-- libs/ardour/ardour/selection.h | 4 +- libs/ardour/ardour/session.h | 45 ++++++++-------- libs/ardour/ardour/types.h | 3 ++ libs/ardour/import_pt.cc | 2 +- libs/ardour/luabindings.cc | 10 ++-- libs/ardour/route.cc | 4 +- libs/ardour/route_group.cc | 8 +-- libs/ardour/route_group_member.cc | 2 +- libs/ardour/selection.cc | 16 +++--- libs/ardour/session.cc | 32 ++++++------ libs/ardour/session_midi.cc | 4 +- libs/ardour/session_state.cc | 66 +++++++++++------------- libs/surfaces/osc/osc.cc | 20 ++++--- libs/surfaces/osc/osc_global_observer.cc | 12 ++--- libs/surfaces/osc/osc_global_observer.h | 1 - libs/surfaces/osc/osc_route_observer.cc | 2 +- libs/surfaces/osc/osc_select_observer.cc | 6 +-- libs/surfaces/osc/osc_select_observer.h | 2 +- 20 files changed, 129 insertions(+), 143 deletions(-) diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h index 2deaab4206..be4369039b 100644 --- a/libs/ardour/ardour/route_group.h +++ b/libs/ardour/ardour/route_group.h @@ -69,12 +69,11 @@ class Session; * * A route can at most be in one group. */ -class LIBARDOUR_API RouteGroup : public SessionObject +class LIBARDOUR_API RouteGroup : public SessionObject, public std::enable_shared_from_this { -public: + public: static void make_property_quarks(); - RouteGroup (Session& s, const std::string &n); ~RouteGroup (); bool is_active () const { return _active.val(); } @@ -117,12 +116,7 @@ public: int add (std::shared_ptr); int remove (std::shared_ptr); - template - void foreach_route (Function f) { - for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) { - f (i->get()); - } - } + template void foreach_route (Function f) { for (auto & r : *routes) {f (r); } } /* to use these, #include "ardour/route_group_specialized.h" */ @@ -145,9 +139,9 @@ public: std::shared_ptr route_list() { return routes; } /** Emitted when a route has been added to this group */ - PBD::Signal )> RouteAdded; + PBD::Signal, std::weak_ptr )> RouteAdded; /** Emitted when a route has been removed from this group */ - static PBD::Signal )> RouteRemoved; + static PBD::Signal, std::weak_ptr )> RouteRemoved; XMLNode& get_state () const; @@ -167,7 +161,11 @@ public: * to libardour color */ void migrate_rgba (uint32_t color) { _rgba = color; } -private: + protected: + friend class Session; + RouteGroup (Session& s, const std::string &n); + + private: std::shared_ptr routes; std::shared_ptr _subgroup_bus; std::weak_ptr group_master; diff --git a/libs/ardour/ardour/route_group_member.h b/libs/ardour/ardour/route_group_member.h index ca15398ba8..0b82fbac79 100644 --- a/libs/ardour/ardour/route_group_member.h +++ b/libs/ardour/ardour/route_group_member.h @@ -21,12 +21,15 @@ #pragma once #include "ardour/libardour_visibility.h" + #include "pbd/controllable.h" #include "pbd/signals.h" +#include "ardour/route_group.h" + namespace ARDOUR { -class RouteGroup; +//class RouteGroup; class LIBARDOUR_API RouteGroupMember { @@ -34,18 +37,18 @@ class LIBARDOUR_API RouteGroupMember RouteGroupMember () : _route_group (0) {} virtual ~RouteGroupMember() {} - RouteGroup* route_group () const { return _route_group; } + std::shared_ptr route_group () const { return _route_group ? _route_group : nullptr; } /** Emitted when this member joins or leaves a route group */ PBD::Signal route_group_changed; protected: - RouteGroup* _route_group; + std::shared_ptr _route_group; private: friend class RouteGroup; - void set_route_group (RouteGroup *); + void set_route_group (std::shared_ptr); }; } diff --git a/libs/ardour/ardour/selection.h b/libs/ardour/ardour/selection.h index 33def1df82..0d1f80d01f 100644 --- a/libs/ardour/ardour/selection.h +++ b/libs/ardour/ardour/selection.h @@ -42,7 +42,7 @@ class LIBARDOUR_API CoreSelection : public PBD::Stateful { CoreSelection (Session& s); ~CoreSelection (); - bool select_stripable_and_maybe_group (std::shared_ptr s, SelectionOperation op, bool with_group = true, bool routes_only = true, RouteGroup* = nullptr); + bool select_stripable_and_maybe_group (std::shared_ptr s, SelectionOperation op, bool with_group = true, bool routes_only = true, std::shared_ptr = nullptr); void select_stripable_with_control (std::shared_ptr s, std::shared_ptr, SelectionOperation); void select_next_stripable (bool mixer_order, bool routes_only); @@ -125,7 +125,7 @@ class LIBARDOUR_API CoreSelection : public PBD::Stateful { bool remove (StripableList&, std::shared_ptr); bool set (StripableList&, std::shared_ptr, std::vector > &); - bool do_select (std::shared_ptr s, std::shared_ptr c, SelectionOperation op, bool with_group, bool routes_only, RouteGroup* not_allowed_in_group); + bool do_select (std::shared_ptr s, std::shared_ptr c, SelectionOperation op, bool with_group, bool routes_only, std::shared_ptr not_allowed_in_group); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 845dc504e2..b62c39c8e1 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -467,15 +467,15 @@ public: /** Emitted when a property of one of our route groups changes. * The parameter is the RouteGroup that has changed. */ - PBD::Signal RouteGroupPropertyChanged; + PBD::Signal)> RouteGroupPropertyChanged; /** Emitted when a route is added to one of our route groups. * First parameter is the RouteGroup, second is the route. */ - PBD::Signal )> RouteAddedToRouteGroup; + PBD::Signal, std::weak_ptr )> RouteAddedToRouteGroup; /** Emitted when a route is removed from one of our route groups. * First parameter is the RouteGroup, second is the route. */ - PBD::Signal )> RouteRemovedFromRouteGroup; + PBD::Signal, std::weak_ptr )> RouteRemovedFromRouteGroup; /** Emitted when a foldback send is created or deleted */ @@ -744,26 +744,24 @@ public: bool _reconfigure_on_delete; }; - RouteGroup* new_route_group (const std::string&); - void add_route_group (RouteGroup *); - void remove_route_group (RouteGroup* rg) { if (rg) remove_route_group (*rg); } - void remove_route_group (RouteGroup&); - void reorder_route_groups (std::list); + std::shared_ptr new_route_group (const std::string&); + void add_route_group (std::shared_ptr); + void remove_route_group (std::shared_ptr rg); + void reorder_route_groups (RouteGroupList); - RouteGroup* route_group_by_name (std::string); - RouteGroup& all_route_group() const; + std::shared_ptr route_group_by_name (std::string); - PBD::Signal route_group_added; + PBD::Signal)> route_group_added; PBD::Signal route_group_removed; PBD::Signal route_groups_reordered; - void foreach_route_group (std::function f) { - for (std::list::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) { - f (*i); + void foreach_route_group (std::function)> f) { + for (auto & rg : _route_groups) { + f (rg); } } - std::list const & route_groups () const { + RouteGroupList const & route_groups () const { return _route_groups; } @@ -772,7 +770,7 @@ public: std::list > new_audio_track ( int input_channels, int output_channels, - RouteGroup* route_group, + std::shared_ptr route_group, uint32_t how_many, std::string name_template, PresentationInfo::order_t order, @@ -785,15 +783,15 @@ public: const ChanCount& input, const ChanCount& output, bool strict_io, std::shared_ptr instrument, Plugin::PresetRecord* pset, - RouteGroup* route_group, uint32_t how_many, std::string name_template, + std::shared_ptr route_group, uint32_t how_many, std::string name_template, PresentationInfo::order_t, TrackMode mode, bool input_auto_connect, bool trigger_visibility = false ); - RouteList new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, std::string name_template, PresentationInfo::Flag, PresentationInfo::order_t); - RouteList new_midi_route (RouteGroup* route_group, uint32_t how_many, std::string name_template, bool strict_io, std::shared_ptr instrument, Plugin::PresetRecord*, PresentationInfo::Flag, PresentationInfo::order_t); + RouteList new_audio_route (int input_channels, int output_channels, std::shared_ptr route_group, uint32_t how_many, std::string name_template, PresentationInfo::Flag, PresentationInfo::order_t); + RouteList new_midi_route (std::shared_ptr route_group, uint32_t how_many, std::string name_template, bool strict_io, std::shared_ptr instrument, Plugin::PresetRecord*, PresentationInfo::Flag, PresentationInfo::order_t); void remove_routes (std::shared_ptr); void remove_route (std::shared_ptr); @@ -1947,8 +1945,7 @@ private: int load_route_groups (const XMLNode&, int); - std::list _route_groups; - RouteGroup* _all_route_group; + RouteGroupList _route_groups; /* routes stuff */ @@ -2003,9 +2000,9 @@ private: int load_regions (const XMLNode& node); int load_compounds (const XMLNode& node); - void route_added_to_route_group (RouteGroup *, std::weak_ptr); - void route_removed_from_route_group (RouteGroup *, std::weak_ptr); - void route_group_property_changed (RouteGroup *); + void route_added_to_route_group (std::shared_ptr, std::weak_ptr); + void route_removed_from_route_group (std::shared_ptr, std::weak_ptr); + void route_group_property_changed (std::weak_ptr); /* SOURCES */ diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index e35ee6a047..c5e45da966 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -71,6 +71,7 @@ class Source; class AudioSource; class GraphNode; class Route; +class RouteGroup; class Region; class Playlist; class Stripable; @@ -103,6 +104,8 @@ typedef std::map,AudioIntervalResult> AudioInter typedef std::list > RegionList; typedef std::set > PlaylistSet; +typedef std::list> RouteGroupList; + struct IOChange { diff --git a/libs/ardour/import_pt.cc b/libs/ardour/import_pt.cc index e10643ae74..ad681e3504 100644 --- a/libs/ardour/import_pt.cc +++ b/libs/ardour/import_pt.cc @@ -429,7 +429,7 @@ no_audio_tracks: ChanCount (DataType::MIDI, 1), true, instrument, (Plugin::PresetRecord*) 0, - (RouteGroup*) 0, + nullptr, 1, a->trname, PresentationInfo::max_order, diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc index 42503e4a17..6641ead6f0 100644 --- a/libs/ardour/luabindings.cc +++ b/libs/ardour/luabindings.cc @@ -1376,7 +1376,8 @@ LuaBindings::common (lua_State* L) .addFunction ("set_bypassed", &PannerShell::set_bypassed) .endClass () - .deriveClass ("RouteGroup") + .deriveWSPtrClass ("RouteGroup") + .addNilPtrConstructor () .addFunction ("is_active", &RouteGroup::is_active) .addFunction ("is_relative", &RouteGroup::is_relative) .addFunction ("is_hidden", &RouteGroup::is_hidden) @@ -2317,8 +2318,9 @@ LuaBindings::common (lua_State* L) .beginConstStdList > ("WeakRouteList") .endClass () - // RouteGroupList == std::list - .beginConstStdCPtrList ("RouteGroupList") + // RouteGroupList == std::list> + .beginPtrStdList > ("RouteGroupList") + .addVoidPtrConstructor > > () .endClass () // typedef std::vector > Region::SourceList @@ -3189,7 +3191,7 @@ LuaBindings::common (lua_State* L) .addFunction ("maybe_update_session_range", &Session::maybe_update_session_range) .addFunction ("remove_route", &Session::remove_route) .addFunction ("remove_routes", &Session::remove_routes) - .addFunction ("remove_route_group", (void (Session::*)(RouteGroup*))&Session::remove_route_group) + .addFunction ("remove_route_group", &Session::remove_route_group) .addFunction ("cut_copy_section", &Session::cut_copy_section) .addFunction ("vca_manager", &Session::vca_manager_ptr) .addExtCFunction ("timecode_to_sample_lua", ARDOUR::LuaAPI::timecode_to_sample_lua) diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 5de9df9430..14ea63ceca 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -5121,8 +5121,8 @@ Route::set_active (bool yn, void* src) return; } - if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_route_active()) { - _route_group->foreach_route (std::bind (&Route::set_active, _1, yn, _route_group)); + if (_route_group && src != _route_group.get() && _route_group->is_active() && _route_group->is_route_active()) { + _route_group->foreach_route (std::bind (&Route::set_active, _1, yn, _route_group.get())); return; } diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc index 73392e662a..24b203c480 100644 --- a/libs/ardour/route_group.cc +++ b/libs/ardour/route_group.cc @@ -64,7 +64,7 @@ namespace ARDOUR { } } -PBD::Signal )> RouteGroup::RouteRemoved; +PBD::Signal, std::weak_ptr )> RouteGroup::RouteRemoved; void RouteGroup::make_property_quarks () @@ -200,7 +200,7 @@ RouteGroup::add (std::shared_ptr r) _sursend_enable_group->add_control (r->surround_send ()->send_enable_control ()); } - r->set_route_group (this); + r->set_route_group (shared_from_this()); r->DropReferences.connect_same_thread (*this, std::bind (&RouteGroup::remove_when_going_away, this, std::weak_ptr (r))); std::shared_ptr vca (group_master.lock()); @@ -210,7 +210,7 @@ RouteGroup::add (std::shared_ptr r) } _session.set_dirty (); - RouteAdded (this, std::weak_ptr (r)); /* EMIT SIGNAL */ + RouteAdded (shared_from_this(), std::weak_ptr (r)); /* EMIT SIGNAL */ return 0; } @@ -271,7 +271,7 @@ RouteGroup::remove (std::shared_ptr r) } routes->erase (i); _session.set_dirty (); - RouteRemoved (this, std::weak_ptr (r)); /* EMIT SIGNAL */ + RouteRemoved (shared_from_this(), std::weak_ptr (r)); /* EMIT SIGNAL */ return 0; } diff --git a/libs/ardour/route_group_member.cc b/libs/ardour/route_group_member.cc index 8a80659995..599785f9d5 100644 --- a/libs/ardour/route_group_member.cc +++ b/libs/ardour/route_group_member.cc @@ -27,7 +27,7 @@ namespace ARDOUR { class RouteGroup; } /** Set the route group; it can be set to 0 for `none' */ void -RouteGroupMember::set_route_group (RouteGroup *rg) +RouteGroupMember::set_route_group (std::shared_ptr rg) { if (rg == _route_group) { return; diff --git a/libs/ardour/selection.cc b/libs/ardour/selection.cc index 99117e64f0..bc3baa657a 100644 --- a/libs/ardour/selection.cc +++ b/libs/ardour/selection.cc @@ -36,7 +36,7 @@ using namespace ARDOUR; using namespace PBD; bool -CoreSelection::do_select (std::shared_ptr s, std::shared_ptr c, SelectionOperation op, bool with_group, bool routes_only, RouteGroup* not_allowed_in_group) +CoreSelection::do_select (std::shared_ptr s, std::shared_ptr c, SelectionOperation op, bool with_group, bool routes_only, std::shared_ptr not_allowed_in_group) { std::shared_ptr r; StripableList sl; @@ -68,7 +68,7 @@ CoreSelection::do_select (std::shared_ptr s, std::shared_ptrroute_group() || r->route_group() != not_allowed_in_group) { - RouteGroup* group = r->route_group(); + std::shared_ptr group = r->route_group(); if (group && group->is_select() && group->is_active()) { for (auto & ri : *(group->route_list())) { @@ -129,7 +129,7 @@ CoreSelection::do_select (std::shared_ptr s, std::shared_ptr s, SelectionOperation op, bool with_group, bool routes_only, RouteGroup* not_allowed_in_group) +CoreSelection::select_stripable_and_maybe_group (std::shared_ptr s, SelectionOperation op, bool with_group, bool routes_only, std::shared_ptr not_allowed_in_group) { return do_select (s, nullptr, op, with_group, routes_only, not_allowed_in_group); } @@ -196,7 +196,7 @@ CoreSelection::select_adjacent_stripable (bool mixer_order, bool routes_only, /* Check for a possible selection-affecting route group */ - RouteGroup* group = 0; + std::shared_ptr group; std::shared_ptr r = std::dynamic_pointer_cast (last_selected); if (r && r->route_group() && r->route_group()->is_select() && r->route_group()->is_active()) { @@ -634,9 +634,9 @@ CoreSelection::get_stripables_for_op (StripableList& sl, std::shared_ptrroute_group(); + std::shared_ptr rg = r->route_group(); - if (rg && rg->is_active() && (rg->*group_predicate)()) { + if (rg && rg->is_active() && ((rg.get())->*group_predicate)()) { for (auto & r : *rg->route_list()) { sl.push_back (r); } @@ -671,9 +671,9 @@ CoreSelection::get_stripables_for_op (StripableList& sl, std::shared_ptrroute_group(); + std::shared_ptr rg = r->route_group(); - if (rg && rg->is_active() && (rg->*group_predicate)()) { + if (rg && rg->is_active() && ((rg.get())->*group_predicate)()) { for (auto & r : *rg->route_list()) { sl.push_back (r); } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index b97f7b686b..71602ab3b5 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -307,7 +307,6 @@ Session::Session (AudioEngine &eng, , ltc_timecode_negative_offset (false) , midi_control_ui (0) , _punch_or_loop (NoConstraint) - , _all_route_group (new RouteGroup (*this, "all")) , routes (new RouteList) , _adding_routes_in_progress (false) , _reconnecting_routes_in_progress (false) @@ -750,12 +749,8 @@ Session::destroy () delete _butler; _butler = 0; - delete _all_route_group; - DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n"); - for (list::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) { - delete *i; - } + _route_groups.clear (); if (click_data != default_click) { delete [] click_data; @@ -2749,7 +2744,7 @@ Session::default_track_name_pattern (DataType t) list > Session::new_midi_track (const ChanCount& input, const ChanCount& output, bool strict_io, std::shared_ptr instrument, Plugin::PresetRecord* pset, - RouteGroup* route_group, uint32_t how_many, + std::shared_ptr route_group, uint32_t how_many, string name_template, PresentationInfo::order_t order, TrackMode mode, bool input_auto_connect, bool trigger_visibility) @@ -2838,7 +2833,7 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, bool s } RouteList -Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, bool strict_io, +Session::new_midi_route (std::shared_ptr route_group, uint32_t how_many, string name_template, bool strict_io, std::shared_ptr instrument, Plugin::PresetRecord* pset, PresentationInfo::Flag flag, PresentationInfo::order_t order) { @@ -3010,7 +3005,7 @@ Session::ensure_route_presentation_info_gap (PresentationInfo::order_t first_new * @param name_template string to use for the start of the name, or "" to use "Audio". */ list< std::shared_ptr > -Session::new_audio_track (int input_channels, int output_channels, RouteGroup* route_group, +Session::new_audio_track (int input_channels, int output_channels, std::shared_ptr route_group, uint32_t how_many, string name_template, PresentationInfo::order_t order, TrackMode mode, bool input_auto_connect, bool trigger_visibility) @@ -3102,7 +3097,7 @@ Session::new_audio_track (int input_channels, int output_channels, RouteGroup* r * @param name_template string to use for the start of the name, or "" to use "Bus". */ RouteList -Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template, +Session::new_audio_route (int input_channels, int output_channels, std::shared_ptr route_group, uint32_t how_many, string name_template, PresentationInfo::Flag flags, PresentationInfo::order_t order) { string bus_name; @@ -3964,7 +3959,7 @@ Session::route_listen_changed (Controllable::GroupControlDisposition group_overr _engine.monitor_port().clear_ports (false); - RouteGroup* rg = route->route_group (); + std::shared_ptr rg (route->route_group ()); const bool group_already_accounted_for = (group_override == Controllable::ForGroup); std::shared_ptr r = routes.reader (); @@ -4073,7 +4068,7 @@ Session::route_solo_changed (bool self_solo_changed, Controllable::GroupControlD * belongs to. */ - RouteGroup* rg = route->route_group (); + std::shared_ptr rg = route->route_group (); const bool group_already_accounted_for = (group_override == Controllable::ForGroup); DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate to session, group accounted for ? %1\n", group_already_accounted_for)); @@ -6812,27 +6807,30 @@ Session::solo_control_mode_changed () /** Called when a property of one of our route groups changes */ void -Session::route_group_property_changed (RouteGroup* rg) +Session::route_group_property_changed (std::weak_ptr wrg) { - RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */ + std::shared_ptr rg (wrg.lock()); + if (rg) { + RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */ + } } /** Called when a route is added to one of our route groups */ void -Session::route_added_to_route_group (RouteGroup* rg, std::weak_ptr r) +Session::route_added_to_route_group (std::shared_ptr rg, std::weak_ptr r) { RouteAddedToRouteGroup (rg, r); } /** Called when a route is removed from one of our route groups */ void -Session::route_removed_from_route_group (RouteGroup* rg, std::weak_ptr r) +Session::route_removed_from_route_group (std::shared_ptr rg, std::weak_ptr r) { update_route_record_state (); RouteRemovedFromRouteGroup (rg, r); /* EMIT SIGNAL */ if (!rg->has_control_master () && !rg->has_subgroup () && rg->empty()) { - remove_route_group (*rg); + remove_route_group (rg); } } diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 1c89c7cab5..4bf64ab2a3 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -815,7 +815,7 @@ Session::rewire_selected_midi (std::shared_ptr new_midi_target) /* connect it to the new target */ new_midi_target->input()->connect (new_midi_target->input()->nth(0), (*p), this); /* and grouped tracks */ - RouteGroup* group = new_midi_target->route_group (); + std::shared_ptr group = new_midi_target->route_group (); if (group && group->is_active () && group->is_select ()) { for (auto const& r : *group->route_list ()) { if (dynamic_pointer_cast (r)) { @@ -859,7 +859,7 @@ Session::rewire_midi_selection_ports () disconnect_port_for_rewire (*p); target->input()->connect (target->input()->nth (0), (*p), this); - RouteGroup* group = target->route_group (); + std::shared_ptr group = target->route_group (); if (group && group->is_active () && group->is_select ()) { for (auto const& r : *group->route_list ()) { if (dynamic_pointer_cast (r)) { diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 075a67a1fd..f2a58eaa78 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -184,7 +184,6 @@ Session::pre_engine_init (string fullpath) _playback_load.store (100); _capture_load.store (100); set_next_event (); - _all_route_group->set_active (true, this); if (config.get_use_video_sync()) { waiting_for_sync_offset = true; @@ -1399,16 +1398,16 @@ Session::import_route_state (const string& path, std::map cons } /* set route-group */ if (r && route_groupname.find (src) != route_groupname.end ()) { - RouteGroup* rg; + std::shared_ptr rg; switch (rgim) { case IgnoreRouteGroup: - rg = nullptr; break; case UseRouteGroup: rg = route_group_by_name (route_groupname[src]); break; case CreateRouteGroup: rg = new_route_group (route_groupname[src]); + add_route_group (rg); break; } if (rg) { @@ -1800,8 +1799,8 @@ Session::state (bool save_template, snapshot_t snapshot_type, bool for_archive, _playlists->add_state (node, save_template, !only_used_assets); child = node->add_child ("RouteGroups"); - for (list::const_iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) { - child->add_child_nocopy ((*i)->get_state()); + for (auto const & rg : _route_groups) { + child->add_child_nocopy (rg->get_state()); } if (_click_io) { @@ -2052,7 +2051,7 @@ Session::set_state (const XMLNode& node, int version) if ((child = find_named_node (node, "ProgramVersion")) != 0) { child->get_property (X_("created-with"), created_with); - child->get_property (X_("modified-with"), modified_with); + child->get_property (X_("modified-with"), modified_with); #if 0 if (modified_with.rfind (PROGRAM_NAME, 0) != 0) { throw WrongProgram (modified_with); @@ -3482,7 +3481,7 @@ Session::load_route_groups (const XMLNode& node, int version) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { if ((*niter)->name() == "RouteGroup") { - RouteGroup* rg = new RouteGroup (*this, ""); + std::shared_ptr rg (new RouteGroup (*this, "")); add_route_group (rg); rg->set_state (**niter, version); } @@ -3492,7 +3491,7 @@ Session::load_route_groups (const XMLNode& node, int version) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") { - RouteGroup* rg = new RouteGroup (*this, ""); + std::shared_ptr rg (new RouteGroup (*this, "")); add_route_group (rg); rg->set_state (**niter, version); } @@ -3547,46 +3546,49 @@ Session::possible_states () const return possible_states(_path); } -RouteGroup* +std::shared_ptr Session::new_route_group (const std::string& name) { - RouteGroup* rg = NULL; + std::shared_ptr rg; - for (std::list::const_iterator i = _route_groups.begin (); i != _route_groups.end (); ++i) { - if ((*i)->name () == name) { - rg = *i; + for (auto const & grp : _route_groups) { + if (grp->name () == name) { + rg = grp; break; } } if (!rg) { - rg = new RouteGroup (*this, name); - add_route_group (rg); + rg.reset (new RouteGroup (*this, name)); } - return (rg); + + return rg; } void -Session::add_route_group (RouteGroup* g) +Session::add_route_group (std::shared_ptr g) { _route_groups.push_back (g); route_group_added (g); /* EMIT SIGNAL */ g->RouteAdded.connect_same_thread (*this, std::bind (&Session::route_added_to_route_group, this, _1, _2)); - g->PropertyChanged.connect_same_thread (*this, std::bind (&Session::route_group_property_changed, this, g)); + + + /* Cannot bind std::shared_ptr<> to a signal connection because of lifetime issues */ + std::weak_ptr wrg (g); + g->PropertyChanged.connect_same_thread (*this, std::bind (&Session::route_group_property_changed, this, wrg)); set_dirty (); } void -Session::remove_route_group (RouteGroup& rg) +Session::remove_route_group (std::shared_ptr rg) { - list::iterator i; + list>::iterator i; - if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) { + if ((i = find (_route_groups.begin(), _route_groups.end(), rg)) != _route_groups.end()) { _route_groups.erase (i); - delete &rg; - + rg->drop_references (); route_group_removed (); /* EMIT SIGNAL */ } } @@ -3595,7 +3597,7 @@ Session::remove_route_group (RouteGroup& rg) * @param groups Route group list in the new order. */ void -Session::reorder_route_groups (list groups) +Session::reorder_route_groups (RouteGroupList groups) { _route_groups = groups; @@ -3604,25 +3606,17 @@ Session::reorder_route_groups (list groups) } -RouteGroup * +std::shared_ptr Session::route_group_by_name (string name) { - list::iterator i; - - for (i = _route_groups.begin(); i != _route_groups.end(); ++i) { - if ((*i)->name() == name) { - return* i; + for (auto & rg : _route_groups) { + if (rg->name() == name) { + return rg; } } return 0; } -RouteGroup& -Session::all_route_group() const -{ - return *_all_route_group; -} - static bool accept_all_audio_files (const string& path, void* /*arg*/) { diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 9347486dd1..861753b4a6 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -2478,7 +2478,7 @@ OSC::parse_sel_group (const char *path, const char* types, lo_arg **argv, int ar PBD::warning << "OSC: VCAs can not be part of a group." << endmsg; return ret; } - RouteGroup *rg = rt->route_group(); + std::shared_ptr rg = rt->route_group(); if (!rg) { PBD::warning << "OSC: This strip is not part of a group." << endmsg; } @@ -2621,7 +2621,7 @@ OSC::set_temp_mode (lo_address addr) if (sur->temp_mode == GroupOnly) { std::shared_ptr rt = std::dynamic_pointer_cast (s); if (rt) { - RouteGroup *rg = rt->route_group(); + std::shared_ptr rg = rt->route_group(); if (rg) { sur->temp_strips.clear(); std::shared_ptr rl = rg->route_list(); @@ -3257,9 +3257,8 @@ OSC::send_group_list (lo_address addr) lo_message_add_string (reply, X_("none")); - std::list groups = session->route_groups (); - for (std::list::iterator i = groups.begin(); i != groups.end(); ++i) { - RouteGroup *rg = *i; + RouteGroupList groups = session->route_groups (); + for (auto const & rg : groups) { lo_message_add_string (reply, rg->name().c_str()); } lo_send_message (addr, X_("/group/list"), reply); @@ -3996,7 +3995,7 @@ OSC::_strip_parse (const char *path, const char *sub_path, const char* types, lo else if (!strncmp (sub_path, X_("group"), 5)) { if (!control_disabled) { if (rt) { - RouteGroup *rg = rt->route_group(); + std::shared_ptr rg = rt->route_group(); if (argc > (param_1)) { if (types[param_1] == 's') { @@ -4005,12 +4004,12 @@ OSC::_strip_parse (const char *path, const char *sub_path, const char* types, lo strng = "none"; } - RouteGroup* new_rg = session->route_group_by_name (strng); + std::shared_ptr new_rg = session->route_group_by_name (strng); if (rg) { string old_group = rg->name(); if (strng == "none") { if (rg->size () == 1) { - session->remove_route_group (*rg); + session->remove_route_group (rg); } else { rg->remove (rt); } @@ -4040,8 +4039,7 @@ OSC::_strip_parse (const char *path, const char *sub_path, const char* types, lo ret = 0; } else { // create new group with this strip in it - RouteGroup* new_rg = new RouteGroup (*session, strng); - session->add_route_group (new_rg); + std::shared_ptr new_rg (session->new_route_group (strng)); new_rg->add (rt); ret = 0; } @@ -4606,7 +4604,7 @@ OSC::spill (const char *path, const char* types, lo_arg **argv, int argc, lo_mes if (strstr (path, X_("/group"))) { //strp must be in a group if (rt) { - RouteGroup *rg = rt->route_group(); + std::shared_ptr rg = rt->route_group(); if (rg) { new_mode = GroupOnly; } else { diff --git a/libs/surfaces/osc/osc_global_observer.cc b/libs/surfaces/osc/osc_global_observer.cc index e827aebaa1..cf8ba40cff 100644 --- a/libs/surfaces/osc/osc_global_observer.cc +++ b/libs/surfaces/osc/osc_global_observer.cc @@ -137,9 +137,9 @@ OSCGlobalObserver::OSCGlobalObserver (OSC& o, Session& s, ArdourSurface::OSC::OS send_change_message (X_("/click/level"), click_controllable); } - session->route_group_added.connect (session_connections, MISSING_INVALIDATOR, std::bind (static_cast(&OSCGlobalObserver::group_changed), this, _1), &_osc); - session->route_group_removed.connect (session_connections, MISSING_INVALIDATOR, std::bind (static_cast(&OSCGlobalObserver::group_changed), this), &_osc); - session->route_groups_reordered.connect (session_connections, MISSING_INVALIDATOR, std::bind (static_cast(&OSCGlobalObserver::group_changed), this), &_osc); + session->route_group_added.connect (session_connections, MISSING_INVALIDATOR, std::bind (&OSCGlobalObserver::group_changed, this), &_osc); + session->route_group_removed.connect (session_connections, MISSING_INVALIDATOR, std::bind (&OSCGlobalObserver::group_changed, this), &_osc); + session->route_groups_reordered.connect (session_connections, MISSING_INVALIDATOR, std::bind (&OSCGlobalObserver::group_changed, this), &_osc); _osc.send_group_list (addr); extra_check (); @@ -588,12 +588,6 @@ OSCGlobalObserver::jog_mode (uint32_t jogmode) _osc.int_message (X_("/jog/mode"), jogmode, addr); } -void -OSCGlobalObserver::group_changed (ARDOUR::RouteGroup *rg) -{ - _osc.send_group_list (addr); -} - void OSCGlobalObserver::group_changed () { diff --git a/libs/surfaces/osc/osc_global_observer.h b/libs/surfaces/osc/osc_global_observer.h index 2e205eb572..5292c3c4f0 100644 --- a/libs/surfaces/osc/osc_global_observer.h +++ b/libs/surfaces/osc/osc_global_observer.h @@ -110,7 +110,6 @@ class OSCGlobalObserver void extra_check (void); void marks_changed (void); void mark_update (void); - void group_changed (ARDOUR::RouteGroup*); void group_changed (void); }; diff --git a/libs/surfaces/osc/osc_route_observer.cc b/libs/surfaces/osc/osc_route_observer.cc index 700796db39..0582bd7f5c 100644 --- a/libs/surfaces/osc/osc_route_observer.cc +++ b/libs/surfaces/osc/osc_route_observer.cc @@ -497,7 +497,7 @@ OSCRouteObserver::group_name () { std::shared_ptr rt = std::dynamic_pointer_cast (_strip); - RouteGroup *rg = rt->route_group(); + std::shared_ptr rg = rt->route_group(); if (rg) { _osc.text_message_with_id (X_("/strip/group"), ssid, rg->name(), in_line, addr); } else { diff --git a/libs/surfaces/osc/osc_select_observer.cc b/libs/surfaces/osc/osc_select_observer.cc index 0a8b2a43b5..09743513d7 100644 --- a/libs/surfaces/osc/osc_select_observer.cc +++ b/libs/surfaces/osc/osc_select_observer.cc @@ -736,17 +736,17 @@ void OSCSelectObserver::group_name () { std::shared_ptr rt = std::dynamic_pointer_cast (_strip); - RouteGroup *rg = rt->route_group(); + std::shared_ptr rg = rt->route_group(); group_sharing (rg); } void -OSCSelectObserver::group_sharing (RouteGroup *rgc) +OSCSelectObserver::group_sharing (std::shared_ptr rgc) { _group_sharing[15] = 1; std::shared_ptr rt = std::dynamic_pointer_cast (_strip); string new_name = "none"; - RouteGroup* rg = NULL; + std::shared_ptr rg = NULL; if (rt) { rg = rt->route_group(); } diff --git a/libs/surfaces/osc/osc_select_observer.h b/libs/surfaces/osc/osc_select_observer.h index 9691d3fe53..5f15874e68 100644 --- a/libs/surfaces/osc/osc_select_observer.h +++ b/libs/surfaces/osc/osc_select_observer.h @@ -104,7 +104,7 @@ class OSCSelectObserver void name_changed (const PBD::PropertyChange& what_changed); void panner_changed (); void group_name (); - void group_sharing (ARDOUR::RouteGroup *rg_c); + void group_sharing (std::shared_ptr rg_c); void comment_changed (); void pi_changed (PBD::PropertyChange const&); void change_message (std::string path, std::shared_ptr controllable);