diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-22 20:21:43 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-22 20:21:43 +0000 |
commit | c83389b8ec5fef9553a401e6123b7e55702af9e2 (patch) | |
tree | 5580dd13b6275eefe67b9147ce96fa10db4d8674 | |
parent | 87fb46859c5950af7c00111afa81a00a1fad2196 (diff) |
cleanup up cleanup at session destruction; clarify the meaning of 3 signals (DropReferences & Destroyed in libardour ; CatchDeletion in the GTK UI); clarify ownership of objects (session no longer pays attention to DropReferences for objects that it is considered to own, such as routes, sources, etc); fix up MIDI parsing and a couple of other places by correcting syntax for return of values from a boost::signals2::signal (possible danger elsewhere to be checked)
git-svn-id: svn://localhost/ardour2/branches/3.0@6389 d708f5d6-7413-0410-9779-e7cbd77b26cf
90 files changed, 286 insertions, 246 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 23df74e6fd..e58e1a2f50 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -898,7 +898,7 @@ ARDOUR_UI::every_point_zero_one_seconds () } void -ARDOUR_UI::update_sample_rate (nframes_t ignored) +ARDOUR_UI::update_sample_rate (nframes_t) { char buf[32]; diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index b8f08456d4..c52d71c780 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -1186,7 +1186,7 @@ AudioRegionView::add_ghost (TimeAxisView& tv) ghost->set_colors(); ghosts.push_back (ghost); - ghost->GoingAway.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context()); + ghost->CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context()); return ghost; } diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index b95377a58c..fe4d601e3f 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -190,7 +190,7 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai /* catch region going away */ - r->GoingAway.connect (*this, boost::bind (&AudioStreamView::remove_region_view, this, boost::weak_ptr<Region> (r)), gui_context()); + r->DropReferences.connect (*this, boost::bind (&AudioStreamView::remove_region_view, this, boost::weak_ptr<Region> (r)), gui_context()); RegionViewAdded (region_view); diff --git a/gtk2_ardour/automation_streamview.cc b/gtk2_ardour/automation_streamview.cc index c8dc0ae3c4..2591f6d8dd 100644 --- a/gtk2_ardour/automation_streamview.cc +++ b/gtk2_ardour/automation_streamview.cc @@ -129,7 +129,7 @@ AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region display_region(region_view); /* catch regionview going away */ - region->GoingAway.connect (*this, boost::bind (&AutomationStreamView::remove_region_view, this, boost::weak_ptr<Region>(region)), gui_context()); + region->DropReferences.connect (*this, boost::bind (&AutomationStreamView::remove_region_view, this, boost::weak_ptr<Region>(region)), gui_context()); RegionViewAdded (region_view); diff --git a/gtk2_ardour/axis_view.cc b/gtk2_ardour/axis_view.cc index d645a51873..9bd9182201 100644 --- a/gtk2_ardour/axis_view.cc +++ b/gtk2_ardour/axis_view.cc @@ -44,6 +44,7 @@ using namespace Gtkmm2ext; using namespace ARDOUR; list<Gdk::Color> AxisView::used_colors; +PBD::Signal1<void,AxisView*> AxisView::CatchDeletion; AxisView::AxisView (ARDOUR::Session* sess) : SessionHandlePtr (sess) @@ -54,7 +55,6 @@ AxisView::AxisView (ARDOUR::Session* sess) AxisView::~AxisView() { - } Gdk::Color diff --git a/gtk2_ardour/axis_view.h b/gtk2_ardour/axis_view.h index 3d2591a977..29f167d85e 100644 --- a/gtk2_ardour/axis_view.h +++ b/gtk2_ardour/axis_view.h @@ -26,7 +26,7 @@ #include <gdkmm/color.h> #include "pbd/xml++.h" -#include "pbd/destructible.h" +#include "pbd/signals.h" #include "ardour/session_handle.h" @@ -41,7 +41,7 @@ namespace ARDOUR { * AxisView defines the abstract base class for time-axis trackviews and routes. * */ -class AxisView : public virtual Selectable, public PBD::Destructible, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr +class AxisView : public virtual Selectable, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr { public: /** @@ -59,6 +59,8 @@ class AxisView : public virtual Selectable, public PBD::Destructible, public PBD virtual void set_marked_for_display (bool yn) { _marked_for_display = yn; } + + static PBD::Signal1<void,AxisView*> CatchDeletion; sigc::signal<void> Hiding; diff --git a/gtk2_ardour/crossfade_view.cc b/gtk2_ardour/crossfade_view.cc index 41134e5096..514daa4f3e 100644 --- a/gtk2_ardour/crossfade_view.cc +++ b/gtk2_ardour/crossfade_view.cc @@ -40,7 +40,7 @@ using namespace Editing; using namespace Gnome; using namespace Canvas; -PBD::Signal1<void,CrossfadeView*> CrossfadeView::GoingAway; +PBD::Signal1<void,CrossfadeView*> CrossfadeView::CatchDeletion; CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, @@ -90,7 +90,7 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent, CrossfadeView::~CrossfadeView () { - GoingAway (this) ; /* EMIT_SIGNAL */ + CatchDeletion (this) ; /* EMIT_SIGNAL */ } void diff --git a/gtk2_ardour/crossfade_view.h b/gtk2_ardour/crossfade_view.h index 8e8c50e323..2376f81edc 100644 --- a/gtk2_ardour/crossfade_view.h +++ b/gtk2_ardour/crossfade_view.h @@ -52,7 +52,7 @@ struct CrossfadeView : public TimeAxisViewItem bool visible() const { return _visible; } void set_valid (bool yn); - static PBD::Signal1<void,CrossfadeView*> GoingAway; + static PBD::Signal1<void,CrossfadeView*> CatchDeletion; AudioRegionView& upper_regionview () const; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index ae466eef63..c38a1995d4 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -4804,7 +4804,7 @@ Editor::handle_new_route (RouteList& routes) rtv->view()->RegionViewAdded.connect (sigc::mem_fun (*this, &Editor::region_view_added)); rtv->view()->HeightChanged.connect (sigc::mem_fun (*this, &Editor::streamview_height_changed)); - rtv->GoingAway.connect (*this, boost::bind (&Editor::remove_route, this, rtv), gui_context()); + route->DropReferences.connect (*this, boost::bind (&Editor::remove_route, this, rtv), gui_context()); } _routes->routes_added (new_views); @@ -4833,6 +4833,8 @@ Editor::remove_route (TimeAxisView *tv) TimeAxisView* next_tv = 0; + _routes->route_removed (tv); + if (tv == entered_track) { entered_track = 0; } @@ -4862,6 +4864,7 @@ Editor::remove_route (TimeAxisView *tv) ActionManager::uncheck_toggleaction ("<Actions>/Editor/show-editor-mixer"); } } + } void diff --git a/gtk2_ardour/editor_imageframe.cc b/gtk2_ardour/editor_imageframe.cc index 4b0601fcea..2d6e23fbd5 100644 --- a/gtk2_ardour/editor_imageframe.cc +++ b/gtk2_ardour/editor_imageframe.cc @@ -169,11 +169,6 @@ Editor::popup_marker_time_axis_edit_menu(int button, int32_t time, ArdourCanvas: } /* </CMT Additions file="editor.cc"> */ - - - - - /* <CMT Additions file="editor_canvas_events.cc"> */ bool Editor::canvas_imageframe_item_view_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv) @@ -1093,7 +1088,7 @@ Editor::handle_new_imageframe_time_axis_view(const string & track_name, void* sr row[route_display_columns.tv] = iftav; route_list_display.get_selection()->select (row); - iftav->GoingAway.connect (*this, boost::bind (&Editor::remove_route, this, (TimeAxisView*)iftav), gui_context()); + iftav->CatchDeletion.connect (*this, boost::bind (&Editor::remove_route, this, (TimeAxisView*)iftav), gui_context()); iftav->gui_changed.connect(sigc::mem_fun(*this, &Editor::handle_gui_changes)) ; } @@ -1110,7 +1105,7 @@ Editor::handle_new_imageframe_marker_time_axis_view(const string & track_name, T row[route_display_columns.tv] = mta; route_list_display.get_selection()->select (row); - mta->GoingAway.connect (*this, boost::bind (&Editor::remove_route, this, (TimeAxisView*)mta), gui_context()); + mta->CatchDeletion.connect (*this, boost::bind (&Editor::remove_route, this, (TimeAxisView*)mta), gui_context()); } diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 79fd056126..c976507cfe 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -165,7 +165,7 @@ Editor::location_changed (Location *location) } void -Editor::location_flags_changed (Location *location, void *src) +Editor::location_flags_changed (Location *location, void*) { ENSURE_GUI_THREAD (*this, &Editor::location_flags_changed, location, src) @@ -338,7 +338,7 @@ Editor::refresh_location_display () } void -Editor::refresh_location_display_s (Change ignored) +Editor::refresh_location_display_s (Change) { ENSURE_GUI_THREAD (*this, &Editor::refresh_location_display_s, ignored) diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index 64d9e97ac6..56c5662690 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -169,7 +169,7 @@ Editor::create_editor_mixer () _session, false); current_mixer_strip->Hiding.connect (sigc::mem_fun(*this, &Editor::current_mixer_strip_hidden)); - current_mixer_strip->GoingAway.connect (*this, boost::bind (&Editor::current_mixer_strip_removed, this), gui_context()); + current_mixer_strip->CatchDeletion.connect (*this, boost::bind (&Editor::current_mixer_strip_removed, this), gui_context()); #ifdef GTKOSX current_mixer_strip->WidthChanged.connect (sigc::mem_fun(*this, &Editor::ensure_all_elements_drawn)); #endif @@ -349,16 +349,17 @@ Editor::session_going_away () playhead_cursor->canvas_item.hide (); - /* hide all tracks */ - - _routes->hide_all_tracks (false); - /* rip everything out of the list displays */ _regions->clear (); _routes->clear (); _route_groups->clear (); + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + delete *i; + } + track_views.clear (); + zoom_range_clock.set_session (0); nudge_clock.set_session (0); diff --git a/gtk2_ardour/editor_route_groups.cc b/gtk2_ardour/editor_route_groups.cc index 9cbb2725c2..9cd845ca08 100644 --- a/gtk2_ardour/editor_route_groups.cc +++ b/gtk2_ardour/editor_route_groups.cc @@ -610,7 +610,7 @@ EditorRouteGroups::groups_changed () } void -EditorRouteGroups::flags_changed (void* src, RouteGroup* group) +EditorRouteGroups::flags_changed (void*, RouteGroup* group) { ENSURE_GUI_THREAD (*this, &EditorRouteGroups::flags_changed, src, group) diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index b18d35a5e3..2ee8927fd2 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -327,17 +327,24 @@ EditorRoutes::redisplay () void EditorRoutes::route_deleted (Gtk::TreeModel::Path const &) { - /* this could require an order reset & sync */ + if (!_session || _session->deletion_in_progress()) { + return; + } + + /* this could require an order reset & sync */ _session->set_remote_control_ids(); _ignore_reorder = true; redisplay (); _ignore_reorder = false; } - void EditorRoutes::visible_changed (Glib::ustring const & path) { + if (_session && _session->deletion_in_progress()) { + return; + } + TreeIter iter; if ((iter = _model->get_iter (path))) { @@ -385,7 +392,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes) (*x)->route()->gui_changed.connect (*this, ui_bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context()); (*x)->route()->NameChanged.connect (*this, boost::bind (&EditorRoutes::route_name_changed, this, wr), gui_context()); - (*x)->GoingAway.connect (*this, boost::bind (&EditorRoutes::route_removed, this, *x), gui_context()); if ((*x)->is_track()) { boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route()); @@ -403,7 +409,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes) } void -EditorRoutes::handle_gui_changes (string const & what, void *src) +EditorRoutes::handle_gui_changes (string const & what, void*) { ENSURE_GUI_THREAD (*this, &EditorRoutes::handle_gui_changes, what, src) diff --git a/gtk2_ardour/editor_routes.h b/gtk2_ardour/editor_routes.h index 73a10c046c..a872e49012 100644 --- a/gtk2_ardour/editor_routes.h +++ b/gtk2_ardour/editor_routes.h @@ -49,6 +49,7 @@ public: void redisplay (); void update_visibility (); void routes_added (std::list<RouteTimeAxisView*> routes); + void route_removed (TimeAxisView *); void hide_track_in_display (TimeAxisView &); std::list<TimeAxisView*> views () const; void hide_all_tracks (bool); @@ -69,7 +70,6 @@ private: void reordered (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int *); bool button_press (GdkEventButton *); void route_name_changed (boost::weak_ptr<ARDOUR::Route>); - void route_removed (TimeAxisView *); void handle_gui_changes (std::string const &, void *); void update_rec_display (); void update_mute_display (); diff --git a/gtk2_ardour/editor_selection_list.cc b/gtk2_ardour/editor_selection_list.cc index f3d11343bc..62b04d8efa 100644 --- a/gtk2_ardour/editor_selection_list.cc +++ b/gtk2_ardour/editor_selection_list.cc @@ -51,11 +51,11 @@ Editor::handle_new_named_selection () } void -Editor::add_named_selection_to_named_selection_display (NamedSelection& selection) +Editor::add_named_selection_to_named_selection_display (boost::shared_ptr<NamedSelection> selection) { TreeModel::Row row = *(named_selection_model->append()); row[named_selection_columns.text] = selection.name; - row[named_selection_columns.selection] = &selection; + row[named_selection_columns.selection] = selection; } void @@ -195,13 +195,14 @@ Editor::create_named_selection () return; } - new NamedSelection (name, thelist); // creation will add it to the model - + boost::shared_ptr<NamedSelection> ns (new NamedSelection (name, thelist)); + /* make the one we just added be selected */ TreeModel::Children::iterator added = named_selection_model->children().end(); --added; named_selection_display.get_selection()->select (*added); + } else { error << _("No selectable material found in the currently selected time range") << endmsg; } diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 438f18b91e..9995c50a71 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -99,10 +99,11 @@ Editor::tempo_map_changed (Change ignored) return; } - ENSURE_GUI_THREAD (*this, &Editor::tempo_map_changed, ignored) + ENSURE_GUI_THREAD (*this, &Editor::tempo_map_changed ignored); - if (tempo_lines) + if (tempo_lines) { tempo_lines->tempo_map_changed(); + } compute_current_bbt_points(leftmost_frame, leftmost_frame + current_page_frames()); _session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); // redraw metric markers diff --git a/gtk2_ardour/ghostregion.cc b/gtk2_ardour/ghostregion.cc index edf1e0e139..5f07f1388f 100644 --- a/gtk2_ardour/ghostregion.cc +++ b/gtk2_ardour/ghostregion.cc @@ -34,7 +34,7 @@ using namespace Editing; using namespace ArdourCanvas; using namespace ARDOUR; -PBD::Signal1<void,GhostRegion*> GhostRegion::GoingAway; +PBD::Signal1<void,GhostRegion*> GhostRegion::CatchDeletion; GhostRegion::GhostRegion (ArdourCanvas::Group* parent, TimeAxisView& tv, TimeAxisView& source_tv, double initial_pos) : trackview (tv) @@ -63,7 +63,7 @@ GhostRegion::GhostRegion (ArdourCanvas::Group* parent, TimeAxisView& tv, TimeAxi GhostRegion::~GhostRegion () { - GoingAway (this); + CatchDeletion (this); delete base_rect; delete group; } diff --git a/gtk2_ardour/ghostregion.h b/gtk2_ardour/ghostregion.h index b2050996a6..3939c46a4b 100644 --- a/gtk2_ardour/ghostregion.h +++ b/gtk2_ardour/ghostregion.h @@ -37,7 +37,7 @@ namespace Gnome { class MidiStreamView; class TimeAxisView; -class GhostRegion +class GhostRegion { public: GhostRegion(ArdourCanvas::Group* parent, TimeAxisView& tv, TimeAxisView& source_tv, double initial_unit_pos); @@ -57,7 +57,7 @@ public: ArdourCanvas::Group* group; ArdourCanvas::SimpleRect* base_rect; - static PBD::Signal1<void,GhostRegion*> GoingAway; + static PBD::Signal1<void,GhostRegion*> CatchDeletion; }; class AudioGhostRegion : public GhostRegion { diff --git a/gtk2_ardour/gui_thread.h b/gtk2_ardour/gui_thread.h index edea9b9d21..cb9c1860f2 100644 --- a/gtk2_ardour/gui_thread.h +++ b/gtk2_ardour/gui_thread.h @@ -20,15 +20,12 @@ #ifndef __ardour_gtk_gui_thread_h__ #define __ardour_gtk_gui_thread_h__ +#include <cstdlib> #include <gtkmm2ext/gtk_ui.h> #include <boost/bind.hpp> #include <boost/bind/protect.hpp> -#define ENSURE_GUI_THREAD(obj,method, ...) \ - if (!Gtkmm2ext::UI::instance()->caller_is_self()) { \ - Gtkmm2ext::UI::instance()->call_slot (boost::bind ((method), &(obj), ## __VA_ARGS__)); \ - return;\ - } +#define ENSURE_GUI_THREAD(obj,method, ...) if (!Gtkmm2ext::UI::instance()->caller_is_self()) { abort (); } #define gui_context() Gtkmm2ext::UI::instance() /* a UICallback-derived object that specifies the event loop for GUI signal handling */ #define ui_bind(f, ...) boost::protect (boost::bind (f, __VA_ARGS__)) diff --git a/gtk2_ardour/imageframe_time_axis.cc b/gtk2_ardour/imageframe_time_axis.cc index 270dd01454..96939218b1 100644 --- a/gtk2_ardour/imageframe_time_axis.cc +++ b/gtk2_ardour/imageframe_time_axis.cc @@ -89,7 +89,7 @@ ImageFrameTimeAxis::ImageFrameTimeAxis(const string & track_id, PublicEditor& ed */ ImageFrameTimeAxis::~ImageFrameTimeAxis () { - GoingAway ; /* EMIT_SIGNAL */ + CatchDeletion (this); // Destroy all the marker views we may have associaited with this TimeAxis for(MarkerTimeAxisList::iterator iter = marker_time_axis_list.begin(); iter != marker_time_axis_list.end(); ++iter) @@ -322,7 +322,7 @@ ImageFrameTimeAxis::add_marker_time_axis(MarkerTimeAxis* marker_track, void* src else { marker_time_axis_list.push_back(marker_track) ; - marker_track->GoingAway.connect (*this, boost::bind (&ImageFrameTimeAxis::remove_time_axis_view, this, marker_track, (void*)this), gui_context()); + marker_track->CatchDeletion.connect (*this, boost::bind (&ImageFrameTimeAxis::remove_time_axis_view, this, marker_track, (void*)this), gui_context()); MarkerTimeAxisAdded(marker_track, src) ; /* EMIT_SIGNAL */ ret = true ; diff --git a/gtk2_ardour/imageframe_time_axis_group.cc b/gtk2_ardour/imageframe_time_axis_group.cc index a555d5254b..5cdbf2d3af 100644 --- a/gtk2_ardour/imageframe_time_axis_group.cc +++ b/gtk2_ardour/imageframe_time_axis_group.cc @@ -35,6 +35,8 @@ using namespace ARDOUR ; +PBD::Signal1<void,ImageFrameTimeAxisGroup*> ImageFrameTimeAxisGroup::CatchDeletion; + //---------------------------------------------------------------------------------------// // Constructor / Desctructor @@ -74,7 +76,7 @@ ImageFrameTimeAxisGroup::~ImageFrameTimeAxisGroup() iter = next ; } - GoingAway ; /* EMIT_SIGNAL */ + CatchDeletion ; /* EMIT_SIGNAL */ } @@ -216,7 +218,7 @@ ImageFrameTimeAxisGroup::add_imageframe_item(const string & frame_id, nframes_t imageframe_views.push_front(ifv) ; - ifv->GoingAway.connect (*this, boost::bind (&ImageFrameTimeAxisGroup::remove_imageframe_item, this, (void*)this), gui_context()); + ifv->CatchDeletion.connect (*this, boost::bind (&ImageFrameTimeAxisGroup::remove_imageframe_item, this, (void*)this), gui_context()); ImageFrameAdded(ifv, src) ; /* EMIT_SIGNAL */ } diff --git a/gtk2_ardour/imageframe_time_axis_group.h b/gtk2_ardour/imageframe_time_axis_group.h index 714d8515f7..c1ec26e912 100644 --- a/gtk2_ardour/imageframe_time_axis_group.h +++ b/gtk2_ardour/imageframe_time_axis_group.h @@ -235,11 +235,11 @@ class ImageFrameTimeAxisGroup : public sigc::trackable //---------------------------------------------------------------------------------// // Emitted Signals - sigc::signal<void> GoingAway ; + static sigc::signal<void,ImageFrameTimeAxisGroup*> CatchDeletion; /** * Emitted when this Group has been removed - * This is different to the GoingAway signal in that this signal + * This is different to the CatchDeletion signal in that this signal * is emitted during the deletion of this Time Axis, and not during * the destructor, this allows us to capture the source of the deletion * event diff --git a/gtk2_ardour/imageframe_time_axis_view.cc b/gtk2_ardour/imageframe_time_axis_view.cc index 5c00bc1e59..a1c211995b 100644 --- a/gtk2_ardour/imageframe_time_axis_view.cc +++ b/gtk2_ardour/imageframe_time_axis_view.cc @@ -214,7 +214,7 @@ ImageFrameTimeAxisView::add_imageframe_group(std::string group_id, void* src) imageframe_groups.push_front(iftag) ; - iftag->GoingAway.connect (*this, boost::bind (&ImageFrameTimeAxisView::remove_imageframe_group, this, iftag, (void*)this), gui_context()); + iftag->CatchDeletion.connect (*this, boost::bind (&ImageFrameTimeAxisView::remove_imageframe_group, this, iftag, (void*)this), gui_context()); ImageFrameGroupAdded(iftag, src) ; /* EMIT_SIGNAL */ } diff --git a/gtk2_ardour/imageframe_view.cc b/gtk2_ardour/imageframe_view.cc index 1d8f5ceab7..6feca44a85 100644 --- a/gtk2_ardour/imageframe_view.cc +++ b/gtk2_ardour/imageframe_view.cc @@ -111,7 +111,7 @@ ImageFrameView::ImageFrameView(const string & item_id, */ ImageFrameView::~ImageFrameView() { - GoingAway (this); + CatchDeletion (this); // destroy any marker items we have associated with this item @@ -287,7 +287,7 @@ ImageFrameView::add_marker_view_item(MarkerView* item, void* src) { marker_view_list.push_back(item) ; - item->GoingAway.connect (*this, boost::bind (&ImageFrameView::remove_marker_view_item, this, (void*)this), gui_context()); + item->CatchDeletion.connect (*this, boost::bind (&ImageFrameView::remove_marker_view_item, this, (void*)this), gui_context()); MarkerViewAdded(item, src) ; /* EMIT_SIGNAL */ } diff --git a/gtk2_ardour/imageframe_view.h b/gtk2_ardour/imageframe_view.h index 281e09ebb8..1ef2af980a 100644 --- a/gtk2_ardour/imageframe_view.h +++ b/gtk2_ardour/imageframe_view.h @@ -78,7 +78,7 @@ class ImageFrameView : public TimeAxisViewItem */ ~ImageFrameView() ; - static sigc::signal<void,ImageFrameView*> GoingAway; + static PBD::Signal1<void,ImageFrameView*> CatchDeletion; //---------------------------------------------------------------------------------------// // Position and duration Accessors/Mutators diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc index bc8f3b8890..aa0d1c57ad 100644 --- a/gtk2_ardour/io_selector.cc +++ b/gtk2_ardour/io_selector.cc @@ -272,7 +272,7 @@ PortInsertWindow::PortInsertWindow (ARDOUR::Session* sess, boost::shared_ptr<ARD signal_delete_event().connect (sigc::mem_fun (*this, &PortInsertWindow::wm_delete), false); - pi->GoingAway.connect (going_away_connection, boost::bind (&PortInsertWindow::plugin_going_away, this), gui_context()); + pi->DropReferences.connect (going_away_connection, boost::bind (&PortInsertWindow::plugin_going_away, this), gui_context()); } bool diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 50ef135f41..f4848228f8 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -40,6 +40,8 @@ using namespace std; using namespace ARDOUR; +PBD::Signal1<void,Marker*> Marker::CatchDeletion; + Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, const string& annotation, Type type, nframes_t frame, bool handle_events) @@ -285,7 +287,7 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con Marker::~Marker () { - drop_references (); + CatchDeletion (this); /* EMIT SIGNAL */ /* destroying the parent group destroys its contents, namely any polygons etc. that we added */ delete name_pixbuf; diff --git a/gtk2_ardour/marker.h b/gtk2_ardour/marker.h index 3802348567..05db900c80 100644 --- a/gtk2_ardour/marker.h +++ b/gtk2_ardour/marker.h @@ -24,9 +24,10 @@ #include <glib.h> #include <libgnomecanvasmm/pixbuf.h> +#include <sigc++/signal.h> #include "ardour/ardour.h" -#include "pbd/destructible.h" +#include "pbd/signals.h" #include "canvas.h" @@ -37,7 +38,7 @@ namespace ARDOUR { class PublicEditor; -class Marker : public PBD::Destructible +class Marker : public sigc::trackable { public: enum Type { @@ -58,6 +59,8 @@ class Marker : public PBD::Destructible virtual ~Marker (); + static PBD::Signal1<void,Marker*> CatchDeletion; + ArdourCanvas::Item& the_item() const; void add_line (ArdourCanvas::Group*, double y_origin, double initial_height); diff --git a/gtk2_ardour/marker_time_axis.cc b/gtk2_ardour/marker_time_axis.cc index c58f607be6..cf4ba58823 100644 --- a/gtk2_ardour/marker_time_axis.cc +++ b/gtk2_ardour/marker_time_axis.cc @@ -90,7 +90,7 @@ MarkerTimeAxis::MarkerTimeAxis (PublicEditor& ed, ARDOUR::Session* sess, Canvas& */ MarkerTimeAxis::~MarkerTimeAxis() { - GoingAway ; /* EMIT_SIGNAL */ + CatchDeletion (this); /* EMIT_SIGNAL */ // destroy the view helper // this handles removing and destroying individual marker items diff --git a/gtk2_ardour/marker_time_axis_view.cc b/gtk2_ardour/marker_time_axis_view.cc index 6e955146a2..3da442e89d 100644 --- a/gtk2_ardour/marker_time_axis_view.cc +++ b/gtk2_ardour/marker_time_axis_view.cc @@ -211,9 +211,9 @@ MarkerTimeAxisView::add_marker_view(ImageFrameView* ifv, std::string mark_type, ifv->add_marker_view_item(mv, src) ; marker_view_list.push_front(mv) ; - mv->GoingAway.connect (*this, boost::bind (&MarkerTimeAxisView::remove_marker_view, this, (void*)this), gui_context()); - - MarkerViewAdded(mv,src) ; /* EMIT_SIGNAL */ + mv->CatchDeletion.connect (*this, boost::bind (&MarkerTimeAxisView::remove_marker_view, this, _1), gui_context()); + + MarkerViewAdded(mv,src) ; /* EMIT_SIGNAL */ return(mv) ; } @@ -311,7 +311,7 @@ MarkerTimeAxisView::remove_named_marker_view(std::string item_id, void* src) * @param src the identity of the object that initiated the change */ void -MarkerTimeAxisView::remove_marker_view(MarkerView* mv, void* src) +MarkerTimeAxisView::remove_marker_view(MarkerView* mv) { ENSURE_GUI_THREAD (*this, &MarkerTimeAxisView::remove_marker_view, mv, src) diff --git a/gtk2_ardour/marker_view.cc b/gtk2_ardour/marker_view.cc index 60a8cb26db..23397d6776 100644 --- a/gtk2_ardour/marker_view.cc +++ b/gtk2_ardour/marker_view.cc @@ -27,7 +27,7 @@ using namespace ARDOUR ; -sigc::signal<void,MarkerView*> MarkerView::GoingAway; +PBD::Signal1<void,MarkerView*> MarkerView::CatchDeletion //---------------------------------------------------------------------------------------// // Constructor / Desctructor diff --git a/gtk2_ardour/marker_view.h b/gtk2_ardour/marker_view.h index 80ab8e60a7..38088b078a 100644 --- a/gtk2_ardour/marker_view.h +++ b/gtk2_ardour/marker_view.h @@ -73,7 +73,7 @@ class MarkerView : public TimeAxisViewItem */ ~MarkerView() ; - static sigc::signal<void,MarkerView*> GoingAway; + static PBD::Signal1<void,MarkerView*> CatchDeletion; //---------------------------------------------------------------------------------------// // Marker Type Methods diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 8d186eac9b..d85ca3cad6 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -1071,7 +1071,7 @@ MidiRegionView::add_ghost (TimeAxisView& tv) } } - ghost->GoingAway.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context()); + ghost->CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context()); return ghost; } diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc index 0d50c8910f..a8eb1c762b 100644 --- a/gtk2_ardour/midi_streamview.cc +++ b/gtk2_ardour/midi_streamview.cc @@ -180,7 +180,7 @@ MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd, display_region (region_view, wfd); /* catch regionview going away */ - region->GoingAway.connect (*this, boost::bind (&MidiStreamView::remove_region_view, this, region), gui_context()); + region->DropReferences.connect (*this, boost::bind (&MidiStreamView::remove_region_view, this, region), gui_context()); RegionViewAdded (region_view); diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 9578e8dd0c..38d60233de 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -312,7 +312,7 @@ MixerStrip::init () MixerStrip::~MixerStrip () { - drop_references (); + CatchDeletion (this); delete input_selector; delete output_selector; @@ -1693,7 +1693,7 @@ MixerStrip::show_send (boost::shared_ptr<Send> send) _current_delivery = send; send->set_metering (true); - _current_delivery->GoingAway.connect (send_gone_connection, boost::bind (&MixerStrip::revert_to_default_display, this), gui_context()); + _current_delivery->DropReferences.connect (send_gone_connection, boost::bind (&MixerStrip::revert_to_default_display, this), gui_context()); gain_meter().set_controls (_route, send->meter(), send->amp()); gain_meter().setup_meters (); diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 799352c87d..f5b997bd63 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -334,8 +334,8 @@ Mixer_UI::add_strip (RouteList& routes) } route->NameChanged.connect (*this, boost::bind (&Mixer_UI::strip_name_changed, this, strip), gui_context()); + route->DropReferences.connect (*this, boost::bind (&Mixer_UI::remove_strip, this, strip), gui_context()); - strip->GoingAway.connect (*this, boost::bind (&Mixer_UI::remove_strip, this, strip), gui_context()); strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed)); strip->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::strip_button_release_event), strip)); } @@ -497,6 +497,11 @@ Mixer_UI::session_going_away () group_model->clear (); _selection.clear (); + track_model->clear (); + + for (list<MixerStrip *>::iterator i = strips.begin(); i != strips.end(); ++i) { + delete (*i); + } WindowTitle title(Glib::get_application_name()); title += _("Mixer"); diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 209904dea1..1273682083 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -142,7 +142,7 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this)), false); - insert->GoingAway.connect (death_connection, boost::bind (&PluginUIWindow::plugin_going_away, this), gui_context()); + insert->DropReferences.connect (death_connection, boost::bind (&PluginUIWindow::plugin_going_away, this), gui_context()); gint h = _pluginui->get_preferred_height (); gint w = _pluginui->get_preferred_width (); @@ -414,7 +414,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi) plugin_analysis_expander.property_expanded().signal_changed().connect( sigc::mem_fun(*this, &PlugUIBase::toggle_plugin_analysis)); plugin_analysis_expander.set_expanded(false); - insert->GoingAway.connect (death_connection, boost::bind (&PlugUIBase::plugin_going_away, this), gui_context()); + insert->DropReferences.connect (death_connection, boost::bind (&PlugUIBase::plugin_going_away, this), gui_context()); } PlugUIBase::~PlugUIBase() diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index 400063c2b6..96305ab19d 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -327,7 +327,7 @@ ProcessorBox::set_route (boost::shared_ptr<Route> r) _route = r; _route->processors_changed.connect (connections, ui_bind (&ProcessorBox::route_processors_changed, this, _1), gui_context()); - _route->GoingAway.connect (connections, boost::bind (&ProcessorBox::route_going_away, this), gui_context()); + _route->DropReferences.connect (connections, boost::bind (&ProcessorBox::route_going_away, this), gui_context()); _route->NameChanged.connect (connections, boost::bind (&ProcessorBox::route_name_changed, this), gui_context()); redisplay_processors (); diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index 770057687a..b6f0cda8f1 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -80,7 +80,6 @@ RegionView::RegionView (ArdourCanvas::Group* parent, , wait_for_data(false) , _time_converter(r->session().tempo_map(), r->position()) { - cerr << "RV " << this << " has ref on region " << _region->name() << endl; } RegionView::RegionView (const RegionView& other) @@ -95,7 +94,6 @@ RegionView::RegionView (const RegionView& other) valid = false; _pixel_width = other._pixel_width; _height = other._height; - cerr << "RV " << this << " has ref on region " << _region->name() << endl; } RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other_region) @@ -114,7 +112,6 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other valid = false; _pixel_width = other._pixel_width; _height = other._height; - cerr << "RV " << this << " has ref on region " << _region->name() << endl; } RegionView::RegionView (ArdourCanvas::Group* parent, @@ -137,7 +134,6 @@ RegionView::RegionView (ArdourCanvas::Group* parent, , wait_for_data(false) , _time_converter(r->session().tempo_map(), r->position()) { - cerr << "RV " << this << " has ref on region " << _region->name() << endl; } void diff --git a/gtk2_ardour/return_ui.cc b/gtk2_ardour/return_ui.cc index 67e05dc47a..9e93185434 100644 --- a/gtk2_ardour/return_ui.cc +++ b/gtk2_ardour/return_ui.cc @@ -110,7 +110,7 @@ ReturnUIWindow::ReturnUIWindow (boost::shared_ptr<Return> r, ARDOUR::Session* s) set_name ("ReturnUIWindow"); - r->GoingAway.connect (going_away_connection, boost::bind (&ReturnUIWindow::return_going_away, this), gui_context()); + r->DropReferences.connect (going_away_connection, boost::bind (&ReturnUIWindow::return_going_away, this), gui_context()); signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window *> (this))); } diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc index bfa209d81e..fbd7af9f7c 100644 --- a/gtk2_ardour/route_params_ui.cc +++ b/gtk2_ardour/route_params_ui.cc @@ -182,7 +182,7 @@ RouteParams_UI::add_routes (RouteList& routes) //route_select_list.rows().back().select (); route->NameChanged.connect (*this, boost::bind (&RouteParams_UI::route_name_changed, this, boost::weak_ptr<Route>(route)), gui_context()); - route->GoingAway.connect (*this, boost::bind (&RouteParams_UI::route_removed, this, boost::weak_ptr<Route>(route)), gui_context()); + route->DropReferences.connect (*this, boost::bind (&RouteParams_UI::route_removed, this, boost::weak_ptr<Route>(route)), gui_context()); } } @@ -522,7 +522,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> proc) SendUI *send_ui = new SendUI (this, send, _session); cleanup_view(); - send->GoingAway.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor>(proc)), gui_context()); + send->DropReferences.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor>(proc)), gui_context()); _active_view = send_ui; redir_hpane.add2 (*_active_view); @@ -533,7 +533,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> proc) ReturnUI *return_ui = new ReturnUI (this, retrn, _session); cleanup_view(); - retrn->GoingAway.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor>(proc)), gui_context()); + retrn->DropReferences.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor>(proc)), gui_context()); _active_view = return_ui; redir_hpane.add2 (*_active_view); @@ -544,7 +544,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> proc) GenericPluginUI *plugin_ui = new GenericPluginUI (plugin_insert, true); cleanup_view(); - plugin_insert->plugin()->GoingAway.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::plugin_going_away, this, PreFader), gui_context()); + plugin_insert->plugin()->DropReferences.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::plugin_going_away, this, PreFader), gui_context()); plugin_ui->start_updating (0); _active_view = plugin_ui; @@ -556,7 +556,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> proc) PortInsertUI *portinsert_ui = new PortInsertUI (this, _session, port_insert); cleanup_view(); - port_insert->GoingAway.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor> (proc)), gui_context()); + port_insert->DropReferences.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor> (proc)), gui_context()); _active_view = portinsert_ui; redir_hpane.pack2 (*_active_view); diff --git a/gtk2_ardour/route_processor_selection.cc b/gtk2_ardour/route_processor_selection.cc index 4e934b0a3c..ae0ac380a4 100644 --- a/gtk2_ardour/route_processor_selection.cc +++ b/gtk2_ardour/route_processor_selection.cc @@ -94,7 +94,7 @@ RouteRedirectSelection::add (boost::shared_ptr<Route> r) { if (find (routes.begin(), routes.end(), r) == routes.end()) { routes.push_back (r); - r->GoingAway.connect (*this, boost::bind (&RouteRedirectSelection::removed, this, boost::weak_ptr<Route>(r)), gui_context()); + r->DropReferences.connect (*this, boost::bind (&RouteRedirectSelection::removed, this, boost::weak_ptr<Route>(r)), gui_context()); RoutesChanged(); } } diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index fe4038323d..3e6edd65e1 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -269,8 +269,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, boost::sh RouteTimeAxisView::~RouteTimeAxisView () { - drop_references (); - drop_connections (); + CatchDeletion (this); for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) { delete *i; diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index d84cc8ba36..6068385587 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -79,10 +79,6 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session* sess) RouteUI::~RouteUI() { - /* derived classes should emit GoingAway so that they receive the signal - when the object is still a legal derived instance. - */ - delete solo_menu; delete mute_menu; delete sends_menu; @@ -171,7 +167,6 @@ RouteUI::self_delete () cerr << "\n\nExpect to see route " << _route->name() << " be deleted\n"; _route.reset (); /* drop reference to route, so that it can be cleaned up */ - route_connections.drop_connections (); delete_when_idle (this); } @@ -188,9 +183,9 @@ RouteUI::set_route (boost::shared_ptr<Route> rp) } if (self_destruct) { - rp->GoingAway.connect (route_connections, boost::bind (&RouteUI::self_delete, this), gui_context()); + rp->DropReferences.connect (route_connections, boost::bind (&RouteUI::self_delete, this), gui_context()); } - + mute_button->set_controllable (_route->mute_control()); solo_button->set_controllable (_route->solo_control()); diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc index edba77140d..b2cb88a008 100644 --- a/gtk2_ardour/selection.cc +++ b/gtk2_ardour/selection.cc @@ -210,7 +210,7 @@ Selection::toggle (TimeAxisView* track) if ((i = find (tracks.begin(), tracks.end(), track)) == tracks.end()) { void (Selection::*pmf)(TimeAxisView*) = &Selection::remove; - track->GoingAway.connect (*this, boost::bind (pmf, this, track), gui_context()); + track->CatchDeletion.connect (*this, boost::bind (pmf, this, track), gui_context()); tracks.push_back (track); } else { tracks.erase (i); @@ -339,7 +339,7 @@ Selection::add (const TrackViewList& track_list) for (list<TimeAxisView*>::const_iterator i = added.begin(); i != added.end(); ++i) { void (Selection::*pmf)(TimeAxisView*) = &Selection::remove; - (*i)->GoingAway.connect (*this, boost::bind (pmf, this, (*i)), gui_context()); + (*i)->CatchDeletion.connect (*this, boost::bind (pmf, this, (*i)), gui_context()); } if (!added.empty()) { @@ -950,7 +950,7 @@ Selection::add (Marker* m) void (Selection::*pmf)(Marker*) = &Selection::remove; - m->GoingAway.connect (*this, boost::bind (pmf, this, m), gui_context()); + m->CatchDeletion.connect (*this, boost::bind (pmf, this, _1), gui_context()); markers.push_back (m); MarkersChanged(); diff --git a/gtk2_ardour/send_ui.cc b/gtk2_ardour/send_ui.cc index 0b24587651..f97da8f41f 100644 --- a/gtk2_ardour/send_ui.cc +++ b/gtk2_ardour/send_ui.cc @@ -130,7 +130,7 @@ SendUIWindow::SendUIWindow (boost::shared_ptr<Send> s, Session* session) set_name ("SendUIWindow"); - s->GoingAway.connect (going_away_connection, boost::bind (&SendUIWindow::send_going_away, this), gui_context()); + s->DropReferences.connect (going_away_connection, boost::bind (&SendUIWindow::send_going_away, this), gui_context()); signal_delete_event().connect (sigc::bind ( sigc::ptr_fun (just_hide_it), diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index cac49687a3..2c241ee283 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -925,7 +925,7 @@ TimeAxisView::add_ghost (RegionView* rv) if(gr) { ghosts.push_back(gr); - gr->GoingAway.connect (*this, ui_bind (&TimeAxisView::erase_ghost, this, _1), gui_context()); + gr->CatchDeletion.connect (*this, ui_bind (&TimeAxisView::erase_ghost, this, _1), gui_context()); } } diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h index 2e36f29fcf..5f97ddcf4f 100644 --- a/gtk2_ardour/time_axis_view_item.h +++ b/gtk2_ardour/time_axis_view_item.h @@ -296,7 +296,7 @@ class TimeAxisViewItem : public Selectable, public PBD::ScopedConnectionList /** * Emitted when this Group has been removed - * This is different to the GoingAway signal in that this signal + * This is different to the CatchDeletion signal in that this signal * is emitted during the deletion of this Time Axis, and not during * the destructor, this allows us to capture the source of the deletion * event diff --git a/gtk2_ardour/visual_time_axis.h b/gtk2_ardour/visual_time_axis.h index 9bc98fc345..5e9c4df0c2 100644 --- a/gtk2_ardour/visual_time_axis.h +++ b/gtk2_ardour/visual_time_axis.h @@ -117,7 +117,7 @@ class VisualTimeAxis : public TimeAxisView /** * Emitted when this Visual Time Axis has been removed - * This is different to the GoingAway signal in that this signal + * This is different to the CatchDeletion signal in that this signal * is emitted during the deletion of this Time Axis, and not during * the destructor, this allows us to capture the source of the deletion * event diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 59a282fe1d..ae9c1f58a5 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -570,11 +570,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* named selections */ - NamedSelection* named_selection_by_name (std::string name); - void add_named_selection (NamedSelection *); - void remove_named_selection (NamedSelection *); + boost::shared_ptr<NamedSelection> named_selection_by_name (std::string name); + void add_named_selection (boost::shared_ptr<NamedSelection>); + void remove_named_selection (boost::shared_ptr<NamedSelection>); - template<class T> void foreach_named_selection (T& obj, void (T::*func)(NamedSelection&)); + template<class T> void foreach_named_selection (T& obj, void (T::*func)(boost::shared_ptr<NamedSelection>)); PBD::Signal0<void> NamedSelectionAdded; PBD::Signal0<void> NamedSelectionRemoved; @@ -1287,7 +1287,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* NAMED SELECTIONS */ mutable Glib::Mutex named_selection_lock; - typedef std::set<NamedSelection *> NamedSelectionList; + typedef std::set<boost::shared_ptr<NamedSelection> > NamedSelectionList; NamedSelectionList named_selections; int load_named_selections (const XMLNode&); diff --git a/libs/ardour/ardour/session_handle.h b/libs/ardour/ardour/session_handle.h index 87c6fb6670..87de244e42 100644 --- a/libs/ardour/ardour/session_handle.h +++ b/libs/ardour/ardour/session_handle.h @@ -34,6 +34,7 @@ class SessionHandleRef : public PBD::ScopedConnectionList protected: ARDOUR::Session& _session; virtual void session_going_away (); + virtual void insanity_check (); }; class SessionHandlePtr diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index f8dc553ae0..fb225671e9 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -1505,7 +1505,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca continue; /* XXX is this OK? */ } - region->GoingAway.connect_same_thread (*this, boost::bind (&Diskstream::remove_region_from_last_capture, this, boost::weak_ptr<Region>(region))); + region->DropReferences.connect_same_thread (*this, boost::bind (&Diskstream::remove_region_from_last_capture, this, boost::weak_ptr<Region>(region))); _last_capture_regions.push_back (region); diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index 3379868d60..1ecba28653 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -102,10 +102,6 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nfra AudioPlaylist::~AudioPlaylist () { - drop_references (); - - /* drop connections to signals */ - _crossfades.clear (); } diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc index 3543f8b51f..3ecf3f0172 100644 --- a/libs/ardour/automation_list.cc +++ b/libs/ardour/automation_list.cc @@ -112,7 +112,6 @@ AutomationList::AutomationList (const XMLNode& node, Evoral::Parameter id) AutomationList::~AutomationList() { - drop_references (); } boost::shared_ptr<Evoral::ControlList> diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc index bbb0d8ca89..1b3a77bc39 100644 --- a/libs/ardour/coreaudiosource.cc +++ b/libs/ardour/coreaudiosource.cc @@ -90,7 +90,6 @@ CoreAudioSource::init_cafile () CoreAudioSource::~CoreAudioSource () { - drop_references (); } int diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index a37323de84..7004ef1ed5 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -148,7 +148,7 @@ Diskstream::set_route (Route& r) non_realtime_input_change (); set_align_style_from_io (); - _route->GoingAway.connect_same_thread (*this, boost::bind (&Diskstream::route_going_away, this)); + _route->Destroyed.connect_same_thread (*this, boost::bind (&Diskstream::route_going_away, this)); } void @@ -340,7 +340,7 @@ Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist) } _playlist->Modified.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_modified, this)); - _playlist->GoingAway.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_deleted, this, boost::weak_ptr<Playlist>(_playlist))); + _playlist->DropReferences.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_deleted, this, boost::weak_ptr<Playlist>(_playlist))); _playlist->RangesMoved.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_ranges_moved, this, _1)); } diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index 368eff2be4..4a4823a29f 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -43,7 +43,7 @@ InternalSend::InternalSend (Session& s, boost::shared_ptr<MuteMaster> mm, boost: set_name (sendto->name()); - _send_to->GoingAway.connect_same_thread (*this, boost::bind (&InternalSend::send_to_going_away, this)); + _send_to->DropReferences.connect_same_thread (*this, boost::bind (&InternalSend::send_to_going_away, this)); _send_to->NameChanged.connect_same_thread (*this, boost::bind (&InternalSend::send_to_name_changed, this)); } diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index bbd29e960e..7abcca2718 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -144,8 +144,6 @@ LadspaPlugin::~LadspaPlugin () deactivate (); cleanup (); - drop_references (); - /* XXX who should close a plugin? */ // dlclose (module); diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 6c593a869a..39bd8d75a7 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -181,8 +181,6 @@ LV2Plugin::~LV2Plugin () deactivate (); cleanup (); - drop_references (); - slv2_instance_free(_instance); slv2_value_free(_name); slv2_value_free(_author); diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 17c1404358..18d3bc5ce3 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -1024,7 +1024,7 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a continue; /* XXX is this OK? */ } - region->GoingAway.connect_same_thread (*this, boost::bind (&Diskstream::remove_region_from_last_capture, this, boost::weak_ptr<Region>(region))); + region->DropReferences.connect_same_thread (*this, boost::bind (&Diskstream::remove_region_from_last_capture, this, boost::weak_ptr<Region>(region))); _last_capture_regions.push_back (region); diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index a8e60ec866..789c91b236 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -71,9 +71,6 @@ MidiPlaylist::MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, nframes MidiPlaylist::~MidiPlaylist () { - drop_references (); - - /* drop connections to signals */ } template<typename Time> diff --git a/libs/ardour/midi_ui.cc b/libs/ardour/midi_ui.cc index 70be1f345d..aa81ff2068 100644 --- a/libs/ardour/midi_ui.cc +++ b/libs/ardour/midi_ui.cc @@ -89,6 +89,8 @@ MidiControlUI::change_midi_ports () bool MidiControlUI::midi_input_handler (IOCondition ioc, MIDI::Port* port) { + DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", port->name())); + if (ioc & ~IO_IN) { return false; } diff --git a/libs/ardour/named_selection.cc b/libs/ardour/named_selection.cc index a829c44a50..4bcc3f3b72 100644 --- a/libs/ardour/named_selection.cc +++ b/libs/ardour/named_selection.cc @@ -52,8 +52,6 @@ NamedSelection::NamedSelection (string n, PlaylistList& l) (*i)->set_name (new_name); (*i)->use(); } - - NamedSelectionCreated (this); } NamedSelection::NamedSelection (Session& session, const XMLNode& node) @@ -101,8 +99,9 @@ NamedSelection::NamedSelection (Session& session, const XMLNode& node) NamedSelection::~NamedSelection () { for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - (*i)->release (); + /* XXX who really owns these? us or the session? */ (*i)->drop_references (); + (*i)->release (); } } diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index c2bf7f3562..a85cc1ee86 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -130,7 +130,6 @@ PluginInsert::set_count (uint32_t num) PluginInsert::~PluginInsert () { - drop_references (); } void diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc index 044230e1f7..dee661db41 100644 --- a/libs/ardour/port_insert.cc +++ b/libs/ardour/port_insert.cc @@ -61,7 +61,6 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLN PortInsert::~PortInsert () { - drop_references (); } void diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index d706421c39..57d887f6a6 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -109,7 +109,7 @@ Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length _sources.push_back (src); _master_sources.push_back (src); - src->GoingAway.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(src))); + src->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(src))); assert(_sources.size() > 0); _positional_lock_style = AudioTime; @@ -338,7 +338,6 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node) Region::~Region () { DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 destructor @ %2\n", _name, this)); - drop_references (); } void @@ -1416,7 +1415,12 @@ void Region::source_deleted (boost::weak_ptr<Source>) { _sources.clear (); - cerr << "Send drop ref signal from region " << ' ' << this << endl; + + /* this is a very special case: at least one of the region's + sources has bee deleted, so invalidate all references to + ourselves. + */ + drop_references (); } @@ -1586,14 +1590,14 @@ Region::use_sources (SourceList const & s) for (SourceList::const_iterator i = s.begin (); i != s.end(); ++i) { _sources.push_back (*i); - (*i)->GoingAway.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i))); + (*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i))); unique_srcs.insert (*i); } for (SourceList::const_iterator i = s.begin (); i != s.end(); ++i) { _master_sources.push_back (*i); if (unique_srcs.find (*i) == unique_srcs.end()) { - (*i)->GoingAway.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i))); + (*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i))); } } } diff --git a/libs/ardour/return.cc b/libs/ardour/return.cc index 991c6ae7d1..c2c227769d 100644 --- a/libs/ardour/return.cc +++ b/libs/ardour/return.cc @@ -67,7 +67,6 @@ Return::Return (Session& s, const XMLNode& node, bool internal) Return::~Return () { - drop_references (); } XMLNode& diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index c652023e2c..09e38eaa86 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -792,6 +792,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite // XXX: do we want to emit the signal here ? change call order. processor->activate (); } + processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false)); _output->set_user_latency (0); diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc index 2f946dd620..d59ec82236 100644 --- a/libs/ardour/route_group.cc +++ b/libs/ardour/route_group.cc @@ -76,7 +76,7 @@ RouteGroup::add (boost::shared_ptr<Route> r) routes->push_back (r); r->join_route_group (this); - r->GoingAway.connect_same_thread (*this, boost::bind (&RouteGroup::remove_when_going_away, this, boost::weak_ptr<Route> (r))); + r->DropReferences.connect_same_thread (*this, boost::bind (&RouteGroup::remove_when_going_away, this, boost::weak_ptr<Route> (r))); _session.set_dirty (); changed (); /* EMIT SIGNAL */ diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index 1bb03642d0..e4fbf3efba 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -64,7 +64,6 @@ Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node, i Send::~Send () { - drop_references (); } void diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index a062efee8d..2e48ed0215 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -388,32 +388,19 @@ Session::destroy () AudioDiskstream::free_working_buffers(); - DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n"); - for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) { - NamedSelectionList::iterator tmp; + /* tell everyone who is still standing that we're about to die */ + drop_references (); - tmp = i; - ++tmp; + /* tell everyone to drop references and delete objects as we go */ - delete *i; - i = tmp; - } + DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n"); + named_selections.clear (); DEBUG_TRACE (DEBUG::Destruction, "delete regions\n"); - for (RegionList::iterator i = regions.begin(); i != regions.end(); ) { - RegionList::iterator tmp; - - tmp = i; - ++tmp; - - boost::shared_ptr<Region> keep (i->second); - - DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 (%2); pre-ref = %3\n", i->second->name(), i->second.get(), i->second.use_count())); + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count())); i->second->drop_references (); - DEBUG_TRACE(DEBUG::Destruction, string_compose ("region post ref = %1\n", i->second.use_count())); - i = tmp; } - regions.clear (); DEBUG_TRACE (DEBUG::Destruction, "delete routes\n"); @@ -427,10 +414,12 @@ Session::destroy () { RCUWriter<RouteList> writer (routes); boost::shared_ptr<RouteList> r = writer.get_copy (); + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); (*i)->drop_references (); } + r->clear (); /* writer goes out of scope and updates master */ } @@ -444,28 +433,22 @@ Session::destroy () DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); (*i)->drop_references (); } + dsl->clear (); } diskstreams.flush (); DEBUG_TRACE (DEBUG::Destruction, "delete sources\n"); - for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) { - SourceMap::iterator tmp; - - tmp = i; - ++tmp; - + for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) { DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count())); i->second->drop_references (); - - i = tmp; } sources.clear (); - DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n"); for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) { + delete *i; } @@ -476,10 +459,6 @@ Session::destroy () /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */ playlists.reset (); - /* tell everyone who is still standing that we're about to die */ - - drop_references (); - boost_debug_list_ptrs (); DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n"); @@ -2813,8 +2792,6 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions) } region->StateChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr<Region>(region))); - region->GoingAway.connect_same_thread (*this, boost::bind (&Session::remove_region, this, boost::weak_ptr<Region>(region))); - update_region_name_map (region); } @@ -3001,7 +2978,6 @@ Session::add_source (boost::shared_ptr<Source> source) } if (result.second) { - source->GoingAway.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source))); set_dirty(); } @@ -3390,10 +3366,7 @@ Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused) return; } - bool existing = playlists->add (playlist); - if (!existing) { - playlist->GoingAway.connect_same_thread (*this, boost::bind (&Session::remove_playlist, this, boost::weak_ptr<Playlist>(playlist))); - } + playlists->add (playlist); if (unused) { playlist->release(); @@ -3566,7 +3539,11 @@ Session::graph_reordered () void Session::add_processor (Processor* processor) { - processor->GoingAway.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor)); + /* Session does not own Processors (they belong to a Route) but we do want to track + the arrival and departure of port inserts, sends and returns for naming + purposes. + */ + processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor)); set_dirty(); } @@ -3810,37 +3787,33 @@ Session::mark_insert_id (uint32_t id) /* Named Selection management */ -NamedSelection * +boost::shared_ptr<NamedSelection> Session::named_selection_by_name (string name) { Glib::Mutex::Lock lm (named_selection_lock); for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) { if ((*i)->name == name) { - return* i; + return *i; } } - return 0; + return boost::shared_ptr<NamedSelection>(); } void -Session::add_named_selection (NamedSelection* named_selection) +Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection) { { Glib::Mutex::Lock lm (named_selection_lock); named_selections.insert (named_selections.begin(), named_selection); } - for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) { - add_playlist (*i); - } - set_dirty(); NamedSelectionAdded (); /* EMIT SIGNAL */ } void -Session::remove_named_selection (NamedSelection* named_selection) +Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection) { bool removed = false; @@ -3850,7 +3823,6 @@ Session::remove_named_selection (NamedSelection* named_selection) NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection); if (i != named_selections.end()) { - delete (*i); named_selections.erase (i); set_dirty(); removed = true; @@ -4186,6 +4158,10 @@ Session::compute_initial_length () void Session::sync_order_keys (std::string const & base) { + if (deletion_in_progress()) { + return; + } + if (!Config->get_sync_all_route_ordering()) { /* leave order keys as they are */ return; diff --git a/libs/ardour/session_handle.cc b/libs/ardour/session_handle.cc index 1cd78c8aac..36515505ac 100644 --- a/libs/ardour/session_handle.cc +++ b/libs/ardour/session_handle.cc @@ -32,7 +32,7 @@ SessionHandlePtr::SessionHandlePtr (Session* s) : _session (s) { if (_session) { - _session->GoingAway.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this)); + _session->DropReferences.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this)); } } @@ -47,7 +47,7 @@ SessionHandlePtr::set_session (Session* s) if (s) { _session = s; - _session->GoingAway.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this)); + _session->DropReferences.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this)); } } @@ -63,11 +63,19 @@ SessionHandlePtr::session_going_away () SessionHandleRef::SessionHandleRef (Session& s) : _session (s) { - _session.GoingAway.connect_same_thread (*this, boost::bind (&SessionHandleRef::session_going_away, this)); + _session.DropReferences.connect_same_thread (*this, boost::bind (&SessionHandleRef::session_going_away, this)); + _session.Destroyed.connect_same_thread (*this, boost::bind (&SessionHandleRef::insanity_check, this)); } void SessionHandleRef::session_going_away () { - error << string_compose (_("programming error: %1"), "SessionHandleRef exists across sesssion deletion!") << endmsg; + /* a handleRef is allowed to exist at the time of DropReferences, but not at the time of Destroyed + */ +} + +void +SessionHandleRef::insanity_check () +{ + cerr << string_compose (_("programming error: %1"), "SessionHandleRef exists across sesssion deletion!") << endl; } diff --git a/libs/ardour/session_playlists.cc b/libs/ardour/session_playlists.cc index 238bd72404..17ed6a4e30 100644 --- a/libs/ardour/session_playlists.cc +++ b/libs/ardour/session_playlists.cc @@ -43,6 +43,7 @@ SessionPlaylists::~SessionPlaylists () ++tmp; DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for used playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); + boost::shared_ptr<Playlist> keeper (*i); (*i)->drop_references (); i = tmp; @@ -56,6 +57,7 @@ SessionPlaylists::~SessionPlaylists () ++tmp; DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for unused playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); + boost::shared_ptr<Playlist> keeper (*i); (*i)->drop_references (); i = tmp; @@ -291,6 +293,7 @@ SessionPlaylists::maybe_delete_unused (boost::function<int(boost::shared_ptr<Pla /* now delete any that were marked for deletion */ for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) { + boost::shared_ptr<Playlist> keeper (*x); (*x)->drop_references (); } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 2248663478..1742feaab1 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -274,7 +274,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1)); PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2)); Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1)); - NamedSelection::NamedSelectionCreated.connect_same_thread (*this, boost::bind (&Session::add_named_selection, this, _1)); AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1)); Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1)); IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1)); @@ -789,7 +788,7 @@ Session::load_state (string snapshot_name) /* there is pending state from a crashed capture attempt */ - if (AskAboutPendingState()) { + if (*AskAboutPendingState()) { state_was_pending = true; } } @@ -1126,7 +1125,7 @@ Session::set_state (const XMLNode& node, int version) _nominal_frame_rate = atoi (prop->value()); if (_nominal_frame_rate != _current_frame_rate) { - if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) { + if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) { return -1; } } diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 185cb15e79..d9d428a4cb 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -246,8 +246,6 @@ SndFileSource::open () SndFileSource::~SndFileSource () { - drop_references (); - if (sf) { sf_close (sf); sf = 0; diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index ee3ebd2ee3..80631ac840 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -102,7 +102,6 @@ VSTPlugin::VSTPlugin (const VSTPlugin &other) VSTPlugin::~VSTPlugin () { deactivate (); - drop_references (); fst_close (_fst); } diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc index 38512d70f5..318dedd1fc 100644 --- a/libs/gtkmm2ext/gtk_ui.cc +++ b/libs/gtkmm2ext/gtk_ui.cc @@ -359,7 +359,11 @@ UI::do_request (UIRequest* req) do_quit (); } else if (req->type == CallSlot) { - +#ifndef NDEBUG + if (getenv ("DEBUG_THREADED_SIGNALS")) { + cerr << "call slot for " << name() << endl; + } +#endif req->the_slot (); } else if (req->type == TouchDisplay) { diff --git a/libs/midi++2/parser.cc b/libs/midi++2/parser.cc index af9cfafaca..60a321cefb 100644 --- a/libs/midi++2/parser.cc +++ b/libs/midi++2/parser.cc @@ -313,7 +313,6 @@ Parser::trace (bool onoff, ostream *o, const string &prefix) trace_connection.disconnect (); if (onoff) { - cerr << "enabling tracing for port " << _port.name() << endl; trace_stream = o; trace_prefix = prefix; any.connect_same_thread (trace_connection, boost::bind (&Parser::trace_event, this, _1, _2, _3)); @@ -402,8 +401,9 @@ Parser::scanner (unsigned char inbyte) * an EOX. Actually, since EOX is a status byte, this * code ALWAYS handles the end of a VARIABLELENGTH message. */ - + if (state == VARIABLELENGTH && statusbit) { + /* The message has ended, so process it */ /* add EOX to any sysex message */ @@ -419,7 +419,7 @@ Parser::scanner (unsigned char inbyte) } cerr << dec << endl; #endif - if (msgindex > 0 && edit (msgbuf, msgindex) >= 0) { + if (msgindex > 0 && (edit.empty() || !(*edit (msgbuf, msgindex) >= 0))) { if (!possible_mmc (msgbuf, msgindex) || _mmc_forward) { if (!possible_mtc (msgbuf, msgindex) || _mtc_forward) { if (!_offline) { @@ -429,7 +429,7 @@ Parser::scanner (unsigned char inbyte) } if (!_offline) { any (*this, msgbuf, msgindex); - } + } } } @@ -490,8 +490,7 @@ Parser::scanner (unsigned char inbyte) case NEEDONEBYTE: /* We've completed a 1 or 2 byte message. */ - - if (edit (msgbuf, msgindex) == 0) { + if (edit.empty() || !(*edit (msgbuf, msgindex) == 0)) { /* message not cancelled by an editor */ diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc index d751c3c80b..be487a0a87 100644 --- a/libs/pbd/controllable.cc +++ b/libs/pbd/controllable.cc @@ -62,23 +62,23 @@ Controllable::add (Controllable& ctl) /* Controllable::remove() is static - no need to manage this connection */ - ctl.GoingAway.connect_same_thread (registry_connections, boost::bind (&Controllable::remove, ref (ctl))); + ctl.DropReferences.connect_same_thread (registry_connections, boost::bind (&Controllable::remove, &ctl)); } void -Controllable::remove (Controllable& ctl) +Controllable::remove (Controllable* ctl) { Glib::RWLock::WriterLock lm (registry_lock); for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) { - if ((*i) == &ctl) { + if ((*i) == ctl) { registry.erase (i); break; } } - if (!ctl.uri().empty()) { - ControllablesByURI::iterator i = registry_by_uri.find (ctl.uri()); + if (!ctl->uri().empty()) { + ControllablesByURI::iterator i = registry_by_uri.find (ctl->uri()); if (i != registry_by_uri.end()) { registry_by_uri.erase (i); } diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc index 98ef094a00..cc7010a415 100644 --- a/libs/pbd/pbd/abstract_ui.cc +++ b/libs/pbd/pbd/abstract_ui.cc @@ -1,4 +1,5 @@ #include <unistd.h> +#include <iostream> #include "pbd/stacktrace.h" #include "pbd/abstract_ui.h" @@ -9,11 +10,22 @@ using namespace std; +static void do_not_delete_the_request_buffer (void*) { } + +template<typename R> +Glib::StaticPrivate<typename AbstractUI<R>::RequestBuffer> AbstractUI<R>::per_thread_request_buffer; + template <typename RequestObject> AbstractUI<RequestObject>::AbstractUI (const string& name) : BaseUI (name) { - PBD::ThreadCreatedWithRequestSize.connect (mem_fun (*this, &AbstractUI<RequestObject>::register_thread)); + void (AbstractUI<RequestObject>::*pmf)(string,pthread_t,string,uint32_t) = &AbstractUI<RequestObject>::register_thread; + + /* better to make this connect a handler that runs in the UI event loop but the syntax seems hard, and + register_thread() is thread safe anyway. + */ + + PBD::ThreadCreatedWithRequestSize.connect_same_thread (new_thread_connection, boost::bind (pmf, this, _1, _2, _3, _4)); } template <typename RequestObject> void @@ -30,7 +42,7 @@ AbstractUI<RequestObject>::register_thread (string target_gui, pthread_t thread_ request_buffers[thread_id] = b; } - per_thread_request_buffer.set (b); + per_thread_request_buffer.set (b, do_not_delete_the_request_buffer); } template <typename RequestObject> RequestObject* @@ -143,6 +155,11 @@ template<typename RequestObject> void AbstractUI<RequestObject>::call_slot (const boost::function<void()>& f) { if (caller_is_self()) { +#ifndef NDEBUG + if (getenv ("DEBUG_THREADED_SIGNALS")) { + std::cerr << "functor called in correct thread for " << name() << " , execute ...\n"; + } +#endif f (); return; } @@ -154,6 +171,11 @@ AbstractUI<RequestObject>::call_slot (const boost::function<void()>& f) } req->the_slot = f; +#ifndef NDEBUG + if (getenv ("DEBUG_THREADED_SIGNALS")) { + std::cerr << "functor called in wrong thread for " << name() << " (from " << pthread_name() << ") send request ...\n"; + } +#endif send_request (req); } diff --git a/libs/pbd/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h index 39fe83b0fe..d04d62c463 100644 --- a/libs/pbd/pbd/abstract_ui.h +++ b/libs/pbd/pbd/abstract_ui.h @@ -24,12 +24,11 @@ #include <string> #include <pthread.h> -#include <sigc++/sigc++.h> - #include <glibmm/thread.h> #include "pbd/receiver.h" #include "pbd/ringbufferNPT.h" +#include "pbd/signals.h" #include "pbd/base_ui.h" class Touchable; @@ -52,8 +51,8 @@ class AbstractUI : public BaseUI Glib::Mutex request_buffer_map_lock; RequestBufferMap request_buffers; - Glib::Private<RequestBuffer> per_thread_request_buffer; - + static Glib::StaticPrivate<RequestBuffer> per_thread_request_buffer; + Glib::Mutex request_list_lock; std::list<RequestObject*> request_list; @@ -62,6 +61,7 @@ class AbstractUI : public BaseUI void send_request (RequestObject *); virtual void do_request (RequestObject *) = 0; + PBD::ScopedConnection new_thread_connection; }; #endif /* __pbd_abstract_ui_h__ */ diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h index d94c58d54f..28dd4b7a31 100644 --- a/libs/pbd/pbd/controllable.h +++ b/libs/pbd/pbd/controllable.h @@ -73,7 +73,7 @@ class Controllable : public PBD::StatefulDestructible { bool _touching; static void add (Controllable&); - static void remove (Controllable&); + static void remove (Controllable*); typedef std::set<PBD::Controllable*> Controllables; typedef std::map<std::string,PBD::Controllable*> ControllablesByURI; diff --git a/libs/pbd/pbd/destructible.h b/libs/pbd/pbd/destructible.h index 8cc0113ff7..8881b45c55 100644 --- a/libs/pbd/pbd/destructible.h +++ b/libs/pbd/pbd/destructible.h @@ -26,14 +26,13 @@ namespace PBD { class Destructible { public: - Destructible() : refs_dropped (false){} - virtual ~Destructible () {} + Destructible() {} + virtual ~Destructible () { Destroyed(); } - PBD::Signal0<void> GoingAway; - void drop_references () { if (!refs_dropped) { GoingAway(); } refs_dropped = true; } + PBD::Signal0<void> Destroyed; + PBD::Signal0<void> DropReferences; - private: - bool refs_dropped; + void drop_references () { DropReferences(); } }; } diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h index a08d3bb717..8c3d1a1870 100644 --- a/libs/pbd/pbd/memento_command.h +++ b/libs/pbd/pbd/memento_command.h @@ -42,7 +42,7 @@ public: : obj(a_object), before(a_before), after(a_after) { /* if the object dies, make sure that we die and that everyone knows about it */ - obj.GoingAway.connect_same_thread (obj_death_connection, boost::bind (&MementoCommand::object_died, this)); + obj.Destroyed.connect_same_thread (obj_death_connection, boost::bind (&MementoCommand::object_died, this)); } ~MementoCommand () { diff --git a/libs/pbd/pbd/pthread_utils.h b/libs/pbd/pbd/pthread_utils.h index e6c5a376df..b8f99ba144 100644 --- a/libs/pbd/pbd/pthread_utils.h +++ b/libs/pbd/pbd/pthread_utils.h @@ -25,7 +25,7 @@ #include <string> #include <stdint.h> -#include <sigc++/sigc++.h> +#include <pbd/signals.h> int pthread_create_and_store (std::string name, pthread_t *thread, void * (*start_routine)(void *), void * arg); void pthread_cancel_one (pthread_t thread); @@ -36,10 +36,7 @@ std::string pthread_name (); namespace PBD { extern void notify_gui_about_thread_creation (std::string, pthread_t, std::string, int requests = 256); - extern void notify_gui_about_thread_exit (pthread_t); - - extern sigc::signal<void,pthread_t> ThreadLeaving; - extern sigc::signal<void,std::string,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; + extern PBD::Signal4<void,std::string,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; } #endif /* __pbd_pthread_utils__ */ diff --git a/libs/pbd/pbd/signals.h b/libs/pbd/pbd/signals.h index 0b44ee8051..ffb0dcebb6 100644 --- a/libs/pbd/pbd/signals.h +++ b/libs/pbd/pbd/signals.h @@ -102,6 +102,8 @@ public: typename SignalType::result_type operator()() { return _signal (); } + + bool empty() const { return _signal.empty(); } private: SignalType _signal; @@ -144,6 +146,8 @@ public: return _signal (arg1); } + bool empty() const { return _signal.empty(); } + private: SignalType _signal; }; @@ -184,6 +188,8 @@ public: return _signal (arg1, arg2); } + bool empty() const { return _signal.empty(); } + private: SignalType _signal; }; @@ -224,6 +230,50 @@ public: return _signal (arg1, arg2, arg3); } + bool empty() const { return _signal.empty(); } + +private: + SignalType _signal; +}; + +template<typename R, typename A1, typename A2, typename A3, typename A4> +class Signal4 { +public: + Signal4 () {} + typedef boost::signals2::signal<R(A1,A2,A3,A4)> SignalType; + + void connect_same_thread (ScopedConnectionList& clist, + const typename SignalType::slot_function_type& slot) { + clist.add_connection (_signal.connect (slot)); + } + + void connect_same_thread (Connection& c, + const typename SignalType::slot_function_type& slot) { + c = _signal.connect (slot); + } + + static void compositor (typename boost::function<void(A1,A2,A3)> f, PBD::EventLoop* event_loop, A1 arg1, A2 arg2, A3 arg3, A4 arg4) { + event_loop->call_slot (boost::bind (f, arg1, arg2, arg3, arg4)); + } + + void connect (ScopedConnectionList& clist, + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3, _4))); + } + + void connect (Connection& c, + const typename SignalType::slot_function_type& slot, + PBD::EventLoop* event_loop) { + c = _signal.connect (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3, _4))); + } + + typename SignalType::result_type operator()(A1 arg1, A2 arg2, A3 arg3, A4 arg4) { + return _signal (arg1, arg2, arg3, arg4); + } + + bool empty() const { return _signal.empty(); } + private: SignalType _signal; }; diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc index 495214a481..ca63603446 100644 --- a/libs/pbd/pthread_utils.cc +++ b/libs/pbd/pthread_utils.cc @@ -33,11 +33,9 @@ using namespace std; typedef std::map<string,pthread_t> ThreadMap; static ThreadMap all_threads; static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t gui_notify_lock = PTHREAD_MUTEX_INITIALIZER; namespace PBD { - sigc::signal<void,pthread_t> ThreadLeaving; - sigc::signal<void,std::string, pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; + PBD::Signal4<void,std::string, pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; } using namespace PBD; @@ -54,17 +52,7 @@ static int thread_creator (pthread_t* thread_id, const pthread_attr_t* attr, voi void PBD::notify_gui_about_thread_creation (std::string target_gui, pthread_t thread, std::string str, int request_count) { - pthread_mutex_lock (&gui_notify_lock); ThreadCreatedWithRequestSize (target_gui, thread, str, request_count); - pthread_mutex_unlock (&gui_notify_lock); -} - -void -PBD::notify_gui_about_thread_exit (pthread_t thread) -{ - pthread_mutex_lock (&gui_notify_lock); - ThreadLeaving (thread); - pthread_mutex_unlock (&gui_notify_lock); } int diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc index 81e31f3a88..c3594b1658 100644 --- a/libs/pbd/undo.cc +++ b/libs/pbd/undo.cc @@ -83,7 +83,7 @@ UndoTransaction::add_command (Command *const action) so there is no need to manage this connection. */ - action->GoingAway.connect_same_thread (*this, boost::bind (&command_death, this, action)); + action->DropReferences.connect_same_thread (*this, boost::bind (&command_death, this, action)); actions.push_back (action); } @@ -186,7 +186,7 @@ UndoHistory::add (UndoTransaction* const ut) { uint32_t current_depth = UndoList.size(); - ut->GoingAway.connect_same_thread (*this, boost::bind (&UndoHistory::remove, this, ut)); + ut->DropReferences.connect_same_thread (*this, boost::bind (&UndoHistory::remove, this, ut)); /* if the current undo history is larger than or equal to the currently requested depth, then pop off at least 1 element to make space diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 6054d01334..9e64667ce7 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -578,7 +578,7 @@ OSC::listen_to_route (boost::shared_ptr<Route> route, lo_address addr) */ if (!route_exists) { - route->GoingAway.connect (*this, boost::bind (&OSC::drop_route, this, boost::weak_ptr<Route> (route)), this); + route->DropReferences.connect (*this, boost::bind (&OSC::drop_route, this, boost::weak_ptr<Route> (route)), this); } } |