cleanup up cleanup at session destruction; clarify the meaning of 3 signals (DropRefe...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 22 Dec 2009 20:21:43 +0000 (20:21 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 22 Dec 2009 20:21:43 +0000 (20:21 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6389 d708f5d6-7413-0410-9779-e7cbd77b26cf

90 files changed:
gtk2_ardour/ardour_ui.cc
gtk2_ardour/audio_region_view.cc
gtk2_ardour/audio_streamview.cc
gtk2_ardour/automation_streamview.cc
gtk2_ardour/axis_view.cc
gtk2_ardour/axis_view.h
gtk2_ardour/crossfade_view.cc
gtk2_ardour/crossfade_view.h
gtk2_ardour/editor.cc
gtk2_ardour/editor_imageframe.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/editor_mixer.cc
gtk2_ardour/editor_route_groups.cc
gtk2_ardour/editor_routes.cc
gtk2_ardour/editor_routes.h
gtk2_ardour/editor_selection_list.cc
gtk2_ardour/editor_tempodisplay.cc
gtk2_ardour/ghostregion.cc
gtk2_ardour/ghostregion.h
gtk2_ardour/gui_thread.h
gtk2_ardour/imageframe_time_axis.cc
gtk2_ardour/imageframe_time_axis_group.cc
gtk2_ardour/imageframe_time_axis_group.h
gtk2_ardour/imageframe_time_axis_view.cc
gtk2_ardour/imageframe_view.cc
gtk2_ardour/imageframe_view.h
gtk2_ardour/io_selector.cc
gtk2_ardour/marker.cc
gtk2_ardour/marker.h
gtk2_ardour/marker_time_axis.cc
gtk2_ardour/marker_time_axis_view.cc
gtk2_ardour/marker_view.cc
gtk2_ardour/marker_view.h
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_streamview.cc
gtk2_ardour/mixer_strip.cc
gtk2_ardour/mixer_ui.cc
gtk2_ardour/plugin_ui.cc
gtk2_ardour/processor_box.cc
gtk2_ardour/region_view.cc
gtk2_ardour/return_ui.cc
gtk2_ardour/route_params_ui.cc
gtk2_ardour/route_processor_selection.cc
gtk2_ardour/route_time_axis.cc
gtk2_ardour/route_ui.cc
gtk2_ardour/selection.cc
gtk2_ardour/send_ui.cc
gtk2_ardour/time_axis_view.cc
gtk2_ardour/time_axis_view_item.h
gtk2_ardour/visual_time_axis.h
libs/ardour/ardour/session.h
libs/ardour/ardour/session_handle.h
libs/ardour/audio_diskstream.cc
libs/ardour/audio_playlist.cc
libs/ardour/automation_list.cc
libs/ardour/coreaudiosource.cc
libs/ardour/diskstream.cc
libs/ardour/internal_send.cc
libs/ardour/ladspa_plugin.cc
libs/ardour/lv2_plugin.cc
libs/ardour/midi_diskstream.cc
libs/ardour/midi_playlist.cc
libs/ardour/midi_ui.cc
libs/ardour/named_selection.cc
libs/ardour/plugin_insert.cc
libs/ardour/port_insert.cc
libs/ardour/region.cc
libs/ardour/return.cc
libs/ardour/route.cc
libs/ardour/route_group.cc
libs/ardour/send.cc
libs/ardour/session.cc
libs/ardour/session_handle.cc
libs/ardour/session_playlists.cc
libs/ardour/session_state.cc
libs/ardour/sndfilesource.cc
libs/ardour/vst_plugin.cc
libs/gtkmm2ext/gtk_ui.cc
libs/midi++2/parser.cc
libs/pbd/controllable.cc
libs/pbd/pbd/abstract_ui.cc
libs/pbd/pbd/abstract_ui.h
libs/pbd/pbd/controllable.h
libs/pbd/pbd/destructible.h
libs/pbd/pbd/memento_command.h
libs/pbd/pbd/pthread_utils.h
libs/pbd/pbd/signals.h
libs/pbd/pthread_utils.cc
libs/pbd/undo.cc
libs/surfaces/osc/osc.cc

index 23df74e6fd07f9342a978efb8b64d19fa225947c..e58e1a2f509cece714484848e233270882e7b875 100644 (file)
@@ -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];
 
index b8f08456d49f782993601726e7504fa75c9a3f9a..c52d71c780cd9bbd829f8e7c35ce9707bd32e099 100644 (file)
@@ -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;
 }
index b95377a58c2e8b878984cfd5a8de2bfbb38a5a76..fe4d601e3f0df5568f7a18d3e2a17abbf1908a81 100644 (file)
@@ -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);
 
index c8dc0ae3c4bd11972e451cb61e39ae7662ab937b..2591f6d8dd2a932e5a042e14aeb4e44012e12f9c 100644 (file)
@@ -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);
 
index d645a518735c51a0fb54b1df8a815a750b615c2a..9bd91822018200ab2591cec704c2ab53e53ae616 100644 (file)
@@ -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
index 3d2591a9774c67d3174307febab474f3b5a8851f..29f167d85e4583421c49a3633118b203066e1fa9 100644 (file)
@@ -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;
 
index 41134e5096b327f052e88d41a4bf07451006daff..514daa4f3ef6ecb7b828eec0642d33d9bb12048e 100644 (file)
@@ -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
index 8e8c50e323635fbb0e3fa3ce73935c3cb78a3e35..2376f81edcd8343e0640e8f3bff9d946e324c11e 100644 (file)
@@ -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;
 
index ae466eef63fac0d298cdc0c4b6a225a5f6b5dee4..c38a1995d4b62c7911f508105bb52b08bfe89dc0 100644 (file)
@@ -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
index 4b0601fceacbcee650257c492c5bfd386f2ac5ed..2d6e23fbd5005bfc74bddaeaa0aedac72dec26bf 100644 (file)
@@ -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());
  }
 
 
index 79fd056126c580339a43dfe962c1bdcd4c107612..c976507cfea9fa853cb4504bfe93c64b09d57412 100644 (file)
@@ -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)
 
index 64d9e97ac6f63d4d7250b2b2e44444c5e5337df4..56c5662690f51b35d8b3577e862d1e5a5beaa91e 100644 (file)
@@ -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);
 
index 9cbb2725c2ee790119863d1cb49cb8af0afedf70..9cd845ca08ed458f8273c7b460a8c0f0a200b8b2 100644 (file)
@@ -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)
 
index b18d35a5e33cf3c6cb7b623268dbbf620bb54db5..2ee8927fd2bbcd24a7b3868a61ebce3103a6e179 100644 (file)
@@ -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)
 
index 73a10c046c3c0628b1645989fa0a229cbd687a89..a872e49012f1d02c158137c4026ac261ca963d17 100644 (file)
@@ -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 ();
index f3d11343bc11096d9f790cd9d3b68375588d48f2..62b04d8efa231a49b355ef3533f67b16863392f9 100644 (file)
@@ -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;
        }
index 438f18b91e6c5264b4d453cb77d5a0b8c2308900..9995c50a711e35d642958ac7283cd2d850b3fc16 100644 (file)
@@ -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
index edf1e0e139568607bc1fd86a850d2d6a4290d342..5f07f1388f26baa9fed8ef4e07f540350e4664d2 100644 (file)
@@ -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;
 }
index b2050996a67aff9a451ad51001392b0f881d197e..3939c46a4b897f3e4e8b0dd0029128d0454747fd 100644 (file)
@@ -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 {
index edea9b9d21d887674c23faa4a34ef73379441abc..cb9c1860f2486fbea705646610136b6c2f8069f7 100644 (file)
 #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__))
index 270dd0145401fef05b695d8df514dda727c7b457..96939218b1295867e7b4bcdc3f167e50026c6bb8 100644 (file)
@@ -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 ;
index a555d5254b084286f1f2a73bfc8efd1e9264de78..5cdbf2d3afd6d18ac5bbdd74d826b19a1d6c3fab 100644 (file)
@@ -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 */
        }
index 714d8515f751bbed339cd4d8b02e02b4024f491a..c1ec26e912b8a391e919221bc163f52436a6c07e 100644 (file)
@@ -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
index 5c00bc1e599d5ee2262563ef7cfa46b1c3dcb835..a1c211995b86a2abe1e829df4b4e67fae07f05c9 100644 (file)
@@ -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 */
        }
index 1d8f5ceab780fe05b262950a5dfeadd0ddb53615..6feca44a8521e45f68b70f287b7b6072f0188d31 100644 (file)
@@ -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 */
 }
index 281e09ebb8bb78f5764c4346713239fafb12afe8..1ef2af980acf58a4477b0515232c9c4f65f4c81f 100644 (file)
@@ -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
index bc8f3b88906c856a517116c00012a99b9e1c3b9c..aa0d1c57ad55e01ad8b0ed3c23579e2a2374c9e3 100644 (file)
@@ -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
index 50ef135f415bf6338b097b6b8ac7adbcf08d5b66..f4848228f8286ac13e89263ffea60d2e92069fbd 100644 (file)
@@ -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;
index 3802348567c7c8b78860fd180ed2c8b229062249..05db900c80287dc7d23d26133e7103ebbe71e604 100644 (file)
 #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);
index c58f607be67173979b6d769f6d74b0bbaf375016..cf4ba58823136d2ebcb86294652274dafae1b689 100644 (file)
@@ -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
index 6e955146a2c1c257fcc4dbad873d565279064198..3da442e89d3639e9ab5b4ceaf938aa9bf3e53baf 100644 (file)
@@ -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)
 
index 60a8cb26dbbe665877675d27ef531b5aa1f7d859..23397d6776e96597264e0ee0d28c21091775c8e7 100644 (file)
@@ -27,7 +27,7 @@
 
 using namespace ARDOUR ;
 
-sigc::signal<void,MarkerView*> MarkerView::GoingAway;
+PBD::Signal1<void,MarkerView*> MarkerView::CatchDeletion
 
 //---------------------------------------------------------------------------------------//
 // Constructor / Desctructor
index 80ab8e60a7781727d5be68d2cf2a40738b656a38..38088b078a093478df419f51028d3dc9eb06b0a5 100644 (file)
@@ -73,7 +73,7 @@ class MarkerView : public TimeAxisViewItem
                 */
                ~MarkerView() ;
 
-               static sigc::signal<void,MarkerView*> GoingAway;
+               static PBD::Signal1<void,MarkerView*> CatchDeletion;
 
                //---------------------------------------------------------------------------------------//
                // Marker Type Methods
index 8d186eac9bf9088da60e2ccb443e120166147926..d85ca3cad68979f7fe1779b2e6ca55b00f27be0f 100644 (file)
@@ -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;
 }
index 0d50c8910f2275400aa503954573e209953a502f..a8eb1c762b9722668ac8eca9c80dfbe92f1531c4 100644 (file)
@@ -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);
 
index 9578e8dd0cab9ff5e05988c1ad023308f49ca4f2..38d60233de02fa8b76c53030df28c2db9bcb194a 100644 (file)
@@ -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 ();
index 799352c87d5d4d290e43503bdc8c1eb948d59f19..f5b997bd63c2f5a159eb8f51dad0f66fb6120cd7 100644 (file)
@@ -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");
index 209904dea1000d2fdbecb1c9393b65389f74051c..1273682083bf7b6945315f893f85bf6bd58e5e29 100644 (file)
@@ -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()
index 400063c2b677ec03f96b13429ea78f4eb8aabbbf..96305ab19dafbf4ca5926c36c11e1eec49a2e0ea 100644 (file)
@@ -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 ();
index 770057687a05d4fc69e08cb3e02ebc42257d5639..b6f0cda8f1b7f9c32f62a38945263750873f907c 100644 (file)
@@ -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
index 67e05dc47acae901f422adfe0424f1055fea20fe..9e9318543460794f0b863e2252fd07d1704b89b2 100644 (file)
@@ -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)));
 }
 
index bfa209d81e6c750c10ac777fefdea32be7813707..fbd7af9f7ced00f848da38d65e8f4f91cdf38c25 100644 (file)
@@ -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);
index 4e934b0a3c7008fa8a17ad635e2df4357a5874cc..ae0ac380a4d8d15bbc76027d70efbea0743dd30b 100644 (file)
@@ -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();
        }
 }
index fe4038323d35b4ad7f4af9008de4c80d3d27dbe8..3e6edd65e1b631335322bccd021804ae4240d641 100644 (file)
@@ -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;
index d84cc8ba3605e99049a787fe03b20c31ab206863..60683855879ec50aa65ebc2d0225cd63002bb93e 100644 (file)
@@ -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());
 
index edba77140d1fc6c057799911a5ac6826c2b57ec4..b2cb88a008c6215d64ec2f66c1b5d7658593dbb3 100644 (file)
@@ -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();
index 0b245876519b8f0e2c0a308ee967afbcb1a35998..f97da8f41f122470a61681db1316f28e96c71e00 100644 (file)
@@ -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),
index cac49687a3166c6592f244fc61d5e2fbc195418f..2c241ee283b89a04a4553027e7689f46c7eab124 100644 (file)
@@ -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());
        }
 }
 
index 2e36f29fcf2bd6d0f484c3ff286d624063cc1e69..5f97ddcf4f2e55883e91ef37f6e17502a52e1179 100644 (file)
@@ -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
index 9bc98fc345d20bebbb9542ed899cb2f0a0f60c0c..5e9c4df0c2042b16f4a8ced920b427e624997d74 100644 (file)
@@ -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
index 59a282fe1d72e77ce6c7bbdae5d689801184910c..ae9c1f58a577dcfadd6d9c11745ea1f732ee8f94 100644 (file)
@@ -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&);
index 87c6fb6670dacb7bd3edd78b9ea1ec66267fa905..87de244e421bd2cbadd53f1d8fb1415cc25940ad 100644 (file)
@@ -34,6 +34,7 @@ class SessionHandleRef : public PBD::ScopedConnectionList
   protected:
        ARDOUR::Session&          _session;
        virtual void session_going_away ();
+       virtual void insanity_check ();
 };
 
 class SessionHandlePtr
index f8dc553ae0631fe3b67d9e7750551db3660b13e3..fb225671e9ba8198ea1a8bb557803c2946d0a7c8 100644 (file)
@@ -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);
 
index 3379868d608999ea43150c9a55e04d9525d36e45..1ecba28653f615f44838ed73c4a0c83c42bd8a45 100644 (file)
@@ -102,10 +102,6 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nfra
 
 AudioPlaylist::~AudioPlaylist ()
 {
-       drop_references ();
-
-       /* drop connections to signals */
-
        _crossfades.clear ();
 }
 
index 3543f8b51f142565c570bd79ed3750de768d81c5..3ecf3f0172309e0dae8f779f905a14542874a7ef 100644 (file)
@@ -112,7 +112,6 @@ AutomationList::AutomationList (const XMLNode& node, Evoral::Parameter id)
 
 AutomationList::~AutomationList()
 {
-       drop_references ();
 }
 
 boost::shared_ptr<Evoral::ControlList>
index bbb0d8ca8987149ccb6e938b582dd3f4f6903d3b..1b3a77bc39ad3aa6c26293eb66bbb19016dcd688 100644 (file)
@@ -90,7 +90,6 @@ CoreAudioSource::init_cafile ()
 
 CoreAudioSource::~CoreAudioSource ()
 {
-       drop_references ();
 }
 
 int
index a37323de84e8faf64a0c77b04465c75653e1a159..7004ef1ed5036bda416584e255107cd7df4a7b35 100644 (file)
@@ -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));
        }
 
index 368eff2be40542af7128ca1208bcddec32cadb0f..4a4823a29f0b7efbbebbe18b688f8e987080abc0 100644 (file)
@@ -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));
 }
 
index bbd29e960ed710cafa6953b7614aea6a33214b73..7abcca27189e8aa7214eee657bf115e07880fe24 100644 (file)
@@ -144,8 +144,6 @@ LadspaPlugin::~LadspaPlugin ()
        deactivate ();
        cleanup ();
 
-       drop_references ();
-
        /* XXX who should close a plugin? */
 
         // dlclose (module);
index 6c593a869aa8ed741a026a1478f3dbe51fae2d10..39bd8d75a7676b9e20f9528ef72318bf4cbdc7ed 100644 (file)
@@ -181,8 +181,6 @@ LV2Plugin::~LV2Plugin ()
        deactivate ();
        cleanup ();
 
-       drop_references ();
-
        slv2_instance_free(_instance);
        slv2_value_free(_name);
        slv2_value_free(_author);
index 17c14043588d2eb58b5ea778872a52549555d9c5..18d3bc5ce30681fe5d7df762a970b7247f3d2601 100644 (file)
@@ -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);
 
index a8e60ec86695c7e214019a4d51bcd545fdc00ec7..789c91b2363114a6b50d48cc8f0105b5044e281e 100644 (file)
@@ -71,9 +71,6 @@ MidiPlaylist::MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, nframes
 
 MidiPlaylist::~MidiPlaylist ()
 {
-       drop_references ();
-
-       /* drop connections to signals */
 }
 
 template<typename Time>
index 70be1f345d075c05ec63e1f579c17f2f70db0a1d..aa81ff206860f1cc178c5100f72858aa54315678 100644 (file)
@@ -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;
        }
index a829c44a501af56edad8827c4b8c897c27bdbcd8..4bcc3f3b726da25f3e9b0dd9d43aa17a7488716a 100644 (file)
@@ -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 ();
        }
 }
 
index c2bf7f3562728389ecb773b73ee9b7fa55bc1e59..a85cc1ee8692f8fb920aead27cb876cc4e7c8ca9 100644 (file)
@@ -130,7 +130,6 @@ PluginInsert::set_count (uint32_t num)
 
 PluginInsert::~PluginInsert ()
 {
-       drop_references ();
 }
 
 void
index 044230e1f7b31dc070a4b279cbed94594f81cdcd..dee661db4157c5e05e7bd781aca1b16066b2a41b 100644 (file)
@@ -61,7 +61,6 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLN
 
 PortInsert::~PortInsert ()
 {
-       drop_references ();
 }
 
 void
index d706421c39382689ce8b2c86f449eccdc985e6cd..57d887f6a6be3ae21d1b421e7b47b69e7f1fae40 100644 (file)
@@ -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)));
                }
        }
 }
index 991c6ae7d1dd27d90570f07a184a6807fbedd7df..c2c227769d932c1670ec801f3685c67208122c43 100644 (file)
@@ -67,7 +67,6 @@ Return::Return (Session& s, const XMLNode& node, bool internal)
 
 Return::~Return ()
 {
-       drop_references ();
 }
 
 XMLNode&
index c652023e2cc4978daec1ce30e19bf9da921c306c..09e38eaa862c491479f279694749c8526b5b6236 100644 (file)
@@ -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);
index 2f946dd62067499c9c12eb31812ef7566551e4a8..d59ec82236328d1fde86715daaeb4ec97a49249c 100644 (file)
@@ -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 */
index 1bb03642d070612698e8205484afd2e311f591fa..e4fbf3efba6bb5bf11ce6d6534146bb780a0d8fa 100644 (file)
@@ -64,7 +64,6 @@ Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node, i
 
 Send::~Send ()
 {
-       drop_references ();
 }
 
 void
index a062efee8dfb796e973440ceafdb6ad1c385b6be..2e48ed0215492f16f66c34d80f310cfbf7821fe2 100644 (file)
@@ -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) {
-                       returni;
+                       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;
index 1cd78c8aac0d821b181d366123bcdef44b95682b..36515505ac52ee40ca191ef8557d2f033fce9a46 100644 (file)
@@ -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;
 }
index 238bd724045a0934cee36740fc086febff954d92..17ed6a4e30f6f4213309baeb4fd38cfc0bdb54f0 100644 (file)
@@ -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 ();
        }
 
index 22486634788a6e91c923ae0e4f7d5375eb40f09a..1742feaab1755e878c8b7b4c3edc2349b2119fd9 100644 (file)
@@ -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;
                        }
                }
index 185cb15e79ea89dbc82c28325a846b428c5b709f..d9d428a4cb8ae098e6827d67e635904b037f6e73 100644 (file)
@@ -246,8 +246,6 @@ SndFileSource::open ()
 
 SndFileSource::~SndFileSource ()
 {
-       drop_references ();
-
        if (sf) {
                sf_close (sf);
                sf = 0;
index ee3ebd2ee3f2d83f2949152176781529cbebe4ce..80631ac840d35200c1f2e2a8abdff418304db332 100644 (file)
@@ -102,7 +102,6 @@ VSTPlugin::VSTPlugin (const VSTPlugin &other)
 VSTPlugin::~VSTPlugin ()
 {
        deactivate ();
-       drop_references ();
        fst_close (_fst);
 }
 
index 38512d70f5d69a7b14c11c1d9c8ed8dc7a4ff753..318dedd1fc450a4513ea232b61f6f845f5e04b3d 100644 (file)
@@ -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) {
index af9cfafaca9876d114cd4de98cd8de8c4c62f49e..60a321cefb2e1ea2ca6dcaae17fcff1f9a8f036c 100644 (file)
@@ -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 */
                        
index d751c3c80b365582122c4fb4cb4eb238ec946813..be487a0a87659ae6dffa84c6398f12dfb0185bb5 100644 (file)
@@ -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);
                }
index 98ef094a0088ed2b2da9a5d3813f610e0841b162..cc7010a4155770983116a9668c2478d62baa71ef 100644 (file)
@@ -1,4 +1,5 @@
 #include <unistd.h>
+#include <iostream>
 
 #include "pbd/stacktrace.h"
 #include "pbd/abstract_ui.h"
 
 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);
 }      
 
index 39fe83b0fec4505bd7f67487c937fcb09254b7e2..d04d62c4637cf3eea9a64fde2d771ab28f91dd43 100644 (file)
 #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__ */
index d94c58d54f80790ea1a196b3d743719a32126a37..28dd4b7a31293d738c55873474569be1aa7535d5 100644 (file)
@@ -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;
index 8cc0113ff7f714a50341a495a0d4848725b0ef24..8881b45c55116d9f6523d06e6a997c68c780a6ac 100644 (file)
@@ -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();  }
 };
 
 }
index a08d3bb717287463834303ad814c818fbfa99260..8c3d1a18702fa9f828a49da6baa3e66cefa2e459 100644 (file)
@@ -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 () {
index e6c5a376df413bafaa0aabfd63da329b64b58fca..b8f99ba1440257475fe4cf6775fc68a363bc676e 100644 (file)
@@ -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__ */
index 0b44ee80515b1464471cab567fb90d527a97516d..ffb0dcebb66ba2d1f38a37795e17f08351871847 100644 (file)
@@ -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;
 };
index 495214a481364d0db1e41f1bfbcdb67121e4c044..ca636034468d68021cb6b70d96d0c82be120391f 100644 (file)
@@ -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  
index 81e31f3a88402febfa9e19d2463753088015a21b..c3594b16584cf10c6b56f57c7aae068d2678afb6 100644 (file)
@@ -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
index 6054d01334dbb8472fd8d104146dc14a007ce3c4..9e64667ce7cffe04ab9f023ce220774c121b52b8 100644 (file)
@@ -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);
        }
 }