X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fregion.cc;h=1f4d6f0f912221d78d3fc4739ea8840a82d13af4;hb=7d96960b162d25da87c388a3083775e8770bba56;hp=e037131ae8d8e4bc0b5a98d963cbb0b46fbce32f;hpb=9155aca8c2b39daa98ff12cbb748809a99af67a3;p=ardour.git diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index e037131ae8..1f4d6f0f91 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -23,14 +23,13 @@ #include #include -#include -#include #include #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 > Region::RegionPropertyChanged; +PBD::Signal1 > 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 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(src))); assert(_sources.size() > 0); _positional_lock_style = AudioTime; @@ -338,19 +337,7 @@ Region::Region (boost::shared_ptr src, const XMLNode& node) Region::~Region () { - boost::shared_ptr 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 other, nframes_t /*offset*/, void Region::set_playlist (boost::weak_ptr wpl) { - boost::shared_ptr old_playlist = (_playlist.lock()); - - boost::shared_ptr 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 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 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 other) const } void -Region::source_deleted (boost::shared_ptr) +Region::source_deleted (boost::weak_ptr) { _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 @@ -1515,6 +1484,17 @@ Region::source_equivalent (boost::shared_ptr other) const return true; } +bool +Region::uses_source (boost::shared_ptr 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 r; boost::shared_ptr grrr2 = boost::dynamic_pointer_cast (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 (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(*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(*i))); } } }