Region::~Region ()
{
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 destructor @ %2\n", _name, this));
+ drop_sources ();
}
void
}
XMLNode&
-Region::state (bool /*full_state*/)
+Region::state (bool full)
{
XMLNode *node = new XMLNode ("Region");
char buf[64];
+ char buf2[64];
+ LocaleGuard lg (X_("POSIX"));
const char* fe = NULL;
add_properties (*node);
node->add_property ("bbt-position", str.str());
}
+ for (uint32_t n=0; n < _sources.size(); ++n) {
+ snprintf (buf2, sizeof(buf2), "source-%d", n);
+ _sources[n]->id().print (buf, sizeof(buf));
+ node->add_property (buf2, buf);
+ }
+
+ for (uint32_t n=0; n < _master_sources.size(); ++n) {
+ snprintf (buf2, sizeof(buf2), "master-source-%d", n);
+ _master_sources[n]->id().print (buf, sizeof (buf));
+ node->add_property (buf2, buf);
+ }
+
+ if (full && _extra_xml) {
+ node->add_child_copy (*_extra_xml);
+ }
+
return *node;
}
}
if (send) {
- cerr << _name << ": final change to be sent: ";
- for (PropertyChange::iterator i = what_changed.begin(); i != what_changed.end(); ++i) {
- cerr << g_quark_to_string ((GQuark) *i) << ' ';
- }
- cerr << endl;
send_change (what_changed);
}
void
Region::source_deleted (boost::weak_ptr<Source>)
{
- _sources.clear ();
+ drop_sources ();
if (!_session.deletion_in_progress()) {
/* this is a very special case: at least one of the region's
void
Region::set_master_sources (const SourceList& srcs)
{
+ for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
+ (*i)->dec_use_count ();
+ }
+
_master_sources = srcs;
assert (_sources.size() == _master_sources.size());
+
+ for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
+ (*i)->inc_use_count ();
+ }
}
bool
sframes_t
Region::source_length(uint32_t n) const
{
+ assert (n < _sources.size());
return _sources[n]->length(_position - _start);
}
framecnt_t maxlen = 0;
- for (uint32_t n=0; n < _sources.size(); ++n) {
+ for (uint32_t n = 0; n < _sources.size(); ++n) {
maxlen = max (maxlen, source_length(n) - _start);
}
framecnt_t maxlen = 0;
- for (uint32_t n=0; n < _sources.size(); ++n) {
+ for (uint32_t n = 0; n < _sources.size(); ++n) {
maxlen = max (maxlen, source_length(n) - new_start);
}
return true;
}
- for (uint32_t n=0; n < _sources.size(); ++n) {
+ for (uint32_t n = 0; n < _sources.size(); ++n) {
if (pos > source_length(n) - _length) {
return false;
}
return true;
}
- for (uint32_t n=0; n < _sources.size(); ++n) {
+ for (uint32_t n = 0; n < _sources.size(); ++n) {
if (new_start > source_length(n) - _length) {
new_start = source_length(n) - _length;
}
_transients.clear ();
}
+void
+Region::drop_sources ()
+{
+ for (SourceList::const_iterator i = _sources.begin (); i != _sources.end(); ++i) {
+ (*i)->dec_use_count ();
+ }
+
+ _sources.clear ();
+
+ for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
+ (*i)->dec_use_count ();
+ }
+
+ _master_sources.clear ();
+}
void
Region::use_sources (SourceList const & s)
set<boost::shared_ptr<Source> > unique_srcs;
for (SourceList::const_iterator i = s.begin (); i != s.end(); ++i) {
- _sources.push_back (*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) {
+ _sources.push_back (*i);
+ (*i)->inc_use_count ();
_master_sources.push_back (*i);
- if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i)));
- }
+ (*i)->inc_use_count ();
+
+ /* connect only once to DropReferences, even if sources are replicated
+ */
+
+ if (unique_srcs.find (*i) == unique_srcs.end ()) {
+ unique_srcs.insert (*i);
+ (*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i)));
+ }
}
}