#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"
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)
_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;
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
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
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);
_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);
}
}
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;
}
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;
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;
}
void
-Region::set_start (nframes_t pos, void */*src*/)
+Region::set_start (nframes_t pos, void* /*src*/)
{
if (_flags & (Locked|PositionLocked)) {
return;
}
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;
sscanf (prop->value().c_str(), "%" PRIu32, &val);
if (val != _start) {
what_changed = Change (what_changed|StartChanged);
+ cerr << _name << " start changed\n";
_start = val;
}
} else {
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;
}
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;
}
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 {
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 {
}
if (send) {
+ cerr << _name << ": final change to be sent: " << hex << what_changed << dec << endl;
send_change (what_changed);
}
recompute_at_end ();
}
- StateChanged (what_changed);
+ send_change (what_changed);
}
void
Region::send_change (Change what_changed)
{
+
{
Glib::Mutex::Lock lm (_lock);
if (_frozen) {
}
}
+ 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)) {
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; */
}
}
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>
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
{
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);
}
}
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)));
}
}
}