more MTC debugging
[ardour.git] / libs / ardour / region.cc
index e037131ae8d8e4bc0b5a98d963cbb0b46fbce32f..1f4d6f0f912221d78d3fc4739ea8840a82d13af4 100644 (file)
 #include <algorithm>
 #include <sstream>
 
-#include <sigc++/bind.h>
-#include <sigc++/class_slot.h>
 
 #include <glibmm/thread.h>
 #include "pbd/xml++.h"
 #include "pbd/stacktrace.h"
 #include "pbd/enumwriter.h"
 
+#include "ardour/debug.h"
 #include "ardour/region.h"
 #include "ardour/playlist.h"
 #include "ardour/session.h"
@@ -55,7 +54,7 @@ Change Region::LockChanged       = ARDOUR::new_change ();
 Change Region::LayerChanged      = ARDOUR::new_change ();
 Change Region::HiddenChanged     = ARDOUR::new_change ();
 
-sigc::signal<void,boost::shared_ptr<ARDOUR::Region> > Region::RegionPropertyChanged;
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Region> > Region::RegionPropertyChanged;
 
 /* derived-from-derived constructor (no sources in constructor) */
 Region::Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
@@ -110,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 (bind (mem_fun (*this, &Region::source_deleted), 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,19 +337,7 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node)
 
 Region::~Region ()
 {
-       boost::shared_ptr<Playlist> pl (playlist());
-
-       if (pl) {
-               for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                       (*i)->remove_playlist (pl);
-               }
-               for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) {
-                       (*i)->remove_playlist (pl);
-               }
-       }
-
-       notify_callbacks ();
-       GoingAway (); /* EMIT SIGNAL */
+       DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 destructor @ %2\n", _name, this));
 }
 
 void
@@ -383,44 +370,7 @@ Region::copy_stuff (boost::shared_ptr<const Region> other, nframes_t /*offset*/,
 void
 Region::set_playlist (boost::weak_ptr<Playlist> wpl)
 {
-       boost::shared_ptr<Playlist> old_playlist = (_playlist.lock());
-
-       boost::shared_ptr<Playlist> pl (wpl.lock());
-
-       if (old_playlist == pl) {
-               return;
-       }
-
-       _playlist = pl;
-
-       if (pl) {
-               if (old_playlist) {
-                       for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                               (*i)->remove_playlist (_playlist);
-                               (*i)->add_playlist (pl);
-                       }
-                       for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) {
-                               (*i)->remove_playlist (_playlist);
-                               (*i)->add_playlist (pl);
-                       }
-               } else {
-                       for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                               (*i)->add_playlist (pl);
-                       }
-                       for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) {
-                               (*i)->add_playlist (pl);
-                       }
-               }
-       } else {
-               if (old_playlist) {
-                       for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                               (*i)->remove_playlist (old_playlist);
-                       }
-                       for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) {
-                               (*i)->remove_playlist (old_playlist);
-                       }
-               }
-       }
+       _playlist = wpl.lock();
 }
 
 bool
@@ -487,7 +437,7 @@ Region::first_edit ()
 
        if (_first_edit != EditChangesNothing && pl) {
 
-               _name = pl->session().new_region_name (_name);
+               _name = _session.new_region_name (_name);
                _first_edit = EditChangesNothing;
 
                send_change (ARDOUR::NameChanged);
@@ -554,7 +504,7 @@ Region::set_position_lock_style (PositionLockStyle ps)
        _positional_lock_style = ps;
 
        if (_positional_lock_style == MusicTime) {
-               pl->session().tempo_map().bbt_time (_position, _bbt_time);
+               _session.tempo_map().bbt_time (_position, _bbt_time);
        }
 
 }
@@ -568,13 +518,13 @@ Region::update_position_after_tempo_map_change ()
                return;
        }
 
-       TempoMap& map (pl->session().tempo_map());
+       TempoMap& map (_session.tempo_map());
        nframes_t pos = map.frame_time (_bbt_time);
        set_position_internal (pos, false);
 }
 
 void
-Region::set_position (nframes_t pos, void */*src*/)
+Region::set_position (nframes_t pos, void/*src*/)
 {
        if (!can_move()) {
                return;
@@ -616,7 +566,7 @@ Region::set_position_internal (nframes_t pos, bool allow_bbt_recompute)
 }
 
 void
-Region::set_position_on_top (nframes_t pos, void */*src*/)
+Region::set_position_on_top (nframes_t pos, void/*src*/)
 {
        if (_flags & Locked) {
                return;
@@ -644,15 +594,12 @@ void
 Region::recompute_position_from_lock_style ()
 {
        if (_positional_lock_style == MusicTime) {
-               boost::shared_ptr<Playlist> pl (playlist());
-               if (pl) {
-                       pl->session().tempo_map().bbt_time (_position, _bbt_time);
-               }
+               _session.tempo_map().bbt_time (_position, _bbt_time);
        }
 }
 
 void
-Region::nudge_position (nframes64_t n, void */*src*/)
+Region::nudge_position (nframes64_t n, void/*src*/)
 {
        if (_flags & Locked) {
                return;
@@ -691,7 +638,7 @@ Region::set_ancestral_data (nframes64_t s, nframes64_t l, float st, float sh)
 }
 
 void
-Region::set_start (nframes_t pos, void */*src*/)
+Region::set_start (nframes_t pos, void/*src*/)
 {
        if (_flags & (Locked|PositionLocked)) {
                return;
@@ -1174,7 +1121,7 @@ Region::get_state ()
 }
 
 int
-Region::set_live_state (const XMLNode& node, int version, Change& what_changed, bool send)
+Region::set_live_state (const XMLNode& node, int /*version*/, Change& what_changed, bool send)
 {
        const XMLNodeList& nlist = node.children();
        const XMLProperty *prop;
@@ -1201,6 +1148,7 @@ Region::set_live_state (const XMLNode& node, int version, Change& what_changed,
                sscanf (prop->value().c_str(), "%" PRIu32, &val);
                if (val != _start) {
                        what_changed = Change (what_changed|StartChanged);
+                       cerr << _name << " start changed\n";
                        _start = val;
                }
        } else {
@@ -1211,6 +1159,7 @@ Region::set_live_state (const XMLNode& node, int version, Change& what_changed,
                sscanf (prop->value().c_str(), "%" PRIu32, &val);
                if (val != _length) {
                        what_changed = Change (what_changed|LengthChanged);
+                       cerr << _name << " length changed\n";
                        _last_length = _length;
                        _length = val;
                }
@@ -1223,6 +1172,7 @@ Region::set_live_state (const XMLNode& node, int version, Change& what_changed,
                sscanf (prop->value().c_str(), "%" PRIu32, &val);
                if (val != _position) {
                        what_changed = Change (what_changed|PositionChanged);
+                       cerr << _name << " position changed\n";
                        _last_position = _position;
                        _position = val;
                }
@@ -1236,6 +1186,7 @@ Region::set_live_state (const XMLNode& node, int version, Change& what_changed,
                x = (layer_t) atoi (prop->value().c_str());
                if (x != _layer) {
                        what_changed = Change (what_changed|LayerChanged);
+                       cerr << _name << " layer changed\n";
                        _layer = x;
                }
        } else {
@@ -1246,6 +1197,7 @@ Region::set_live_state (const XMLNode& node, int version, Change& what_changed,
                sscanf (prop->value().c_str(), "%" PRIu32, &val);
                if (val != _sync_position) {
                        what_changed = Change (what_changed|SyncOffsetChanged);
+                       cerr << _name << " sync changed\n";
                        _sync_position = val;
                }
        } else {
@@ -1334,6 +1286,7 @@ Region::set_live_state (const XMLNode& node, int version, Change& what_changed,
        }
 
        if (send) {
+               cerr << _name << ": final change to be sent: " << hex << what_changed << dec << endl;
                send_change (what_changed);
        }
 
@@ -1399,12 +1352,13 @@ Region::thaw (const string& /*why*/)
                recompute_at_end ();
        }
 
-       StateChanged (what_changed);
+       send_change (what_changed);
 }
 
 void
 Region::send_change (Change what_changed)
 {
+
        {
                Glib::Mutex::Lock lm (_lock);
                if (_frozen) {
@@ -1413,7 +1367,9 @@ Region::send_change (Change what_changed)
                }
        }
 
+       cerr << _name << " actually sends " << hex << what_changed << dec << " @" << get_microseconds() << endl;
        StateChanged (what_changed);
+       cerr << _name << " done with " << hex << what_changed << dec << " @" << get_microseconds() << endl;
 
        if (!(_flags & DoNotSendPropertyChanges)) {
 
@@ -1423,7 +1379,9 @@ Region::send_change (Change what_changed)
 
                try {
                        boost::shared_ptr<Region> rptr = shared_from_this();
+                       cerr << _name << " actually sends prop change " << hex << what_changed << dec <<  " @ " << get_microseconds() << endl;
                        RegionPropertyChanged (rptr);
+                       cerr << _name << " done with prop change  @ " << get_microseconds() << endl;
                } catch (...) {
                        /* no shared_ptr available, relax; */
                }
@@ -1465,10 +1423,21 @@ Region::region_list_equivalent (boost::shared_ptr<const Region> other) const
 }
 
 void
-Region::source_deleted (boost::shared_ptr<Source>)
+Region::source_deleted (boost::weak_ptr<Source>)
 {
        _sources.clear ();
-       drop_references ();
+
+       if (!_session.deletion_in_progress()) {
+               /* this is a very special case: at least one of the region's
+                  sources has bee deleted, so invalidate all references to
+                  ourselves. Do NOT do this during session deletion, because
+                  then we run the risk that this will actually result
+                  in this object being deleted (as refcnt goes to zero)
+                  while emitting DropReferences.
+               */
+
+               drop_references ();
+       }
 }
 
 vector<string>
@@ -1515,6 +1484,17 @@ Region::source_equivalent (boost::shared_ptr<const Region> other) const
        return true;
 }
 
+bool
+Region::uses_source (boost::shared_ptr<const Source> source) const
+{
+       for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
+               if (*i == source) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 sframes_t
 Region::source_length(uint32_t n) const
 {
@@ -1596,7 +1576,7 @@ Region::get_parent() const
                boost::shared_ptr<Region> r;
                boost::shared_ptr<Region const> grrr2 = boost::dynamic_pointer_cast<Region const> (shared_from_this());
 
-               if (grrr2 && (r = pl->session().find_whole_file_parent (grrr2))) {
+               if (grrr2 && (r = _session.find_whole_file_parent (grrr2))) {
                        return boost::static_pointer_cast<Region> (r);
                }
        }
@@ -1626,14 +1606,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 (bind (mem_fun (*this, &Region::source_deleted), *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 (bind (mem_fun (*this, &Region::source_deleted), *i));
+                       (*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i)));
                }
        }
 }