summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-06-23 20:14:07 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-06-23 20:14:07 +0000
commitf4401c59284258c6aa56707da64e3da32756329f (patch)
tree73679199ae43516347d607adad212c10612f7eb9 /libs
parentcac03dbeb6ebdcd406385dd14a746cb8c51dd5f8 (diff)
midway snapshot of work done on managing Region & Source lifetimes correctly. may fix missing MIDI file bug ; save empty playlists because they may be referred to by the history file ; undo commands auto-delete when objects they refer to die (currently not commands built from XML deserialization); Sources now know how many regions are using them for something, meaning that we know if we can delete the files holding any data for the source
git-svn-id: svn://localhost/ardour2/branches/3.0@7291 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/diskstream.h8
-rw-r--r--libs/ardour/ardour/playlist.h3
-rwxr-xr-xlibs/ardour/ardour/public_diskstream.h4
-rw-r--r--libs/ardour/ardour/region.h2
-rw-r--r--libs/ardour/ardour/region_factory.h4
-rw-r--r--libs/ardour/ardour/session.h3
-rw-r--r--libs/ardour/ardour/session_playlists.h3
-rw-r--r--libs/ardour/ardour/source.h12
-rw-r--r--libs/ardour/ardour/track.h3
-rw-r--r--libs/ardour/audio_diskstream.cc14
-rw-r--r--libs/ardour/audio_playlist.cc12
-rw-r--r--libs/ardour/audioregion.cc23
-rw-r--r--libs/ardour/diskstream.cc12
-rw-r--r--libs/ardour/midi_diskstream.cc14
-rw-r--r--libs/ardour/midi_playlist.cc8
-rw-r--r--libs/ardour/midi_region.cc25
-rw-r--r--libs/ardour/playlist.cc14
-rw-r--r--libs/ardour/region.cc79
-rw-r--r--libs/ardour/region_factory.cc43
-rw-r--r--libs/ardour/session.cc88
-rw-r--r--libs/ardour/session_playlists.cc29
-rw-r--r--libs/ardour/session_state.cc15
-rw-r--r--libs/ardour/source.cc2
-rw-r--r--libs/ardour/track.cc6
-rw-r--r--libs/evoral/src/SMF.cpp10
-rw-r--r--libs/pbd/pbd/command.h8
-rw-r--r--libs/pbd/pbd/properties.h4
-rw-r--r--libs/pbd/pbd/property_basics.h6
-rw-r--r--libs/pbd/pbd/stateful.h2
-rw-r--r--libs/pbd/pbd/stateful_diff_command.h8
-rw-r--r--libs/pbd/pbd/undo.h3
-rw-r--r--libs/pbd/stateful.cc4
-rw-r--r--libs/pbd/stateful_diff_command.cc22
-rw-r--r--libs/pbd/undo.cc28
34 files changed, 307 insertions, 214 deletions
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index c089a39736..d0d2bcbc36 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -45,7 +45,7 @@ namespace ARDOUR {
class IO;
class Playlist;
class Processor;
-class Region;
+class Source;
class Session;
class Track;
class Location;
@@ -134,12 +134,10 @@ class Diskstream : public SessionObject, public PublicDiskstream
int set_loop (Location *loc);
- std::list<boost::shared_ptr<Region> >& last_capture_regions () { return _last_capture_regions; }
+ std::list<boost::shared_ptr<Source> >& last_capture_sources () { return _last_capture_sources; }
void handle_input_change (IOChange, void *src);
- void remove_region_from_last_capture (boost::weak_ptr<Region> wregion);
-
void move_processor_automation (boost::weak_ptr<Processor>,
std::list<Evoral::RangeMove<framepos_t> > const &);
@@ -228,7 +226,7 @@ class Diskstream : public SessionObject, public PublicDiskstream
virtual bool realtime_set_speed (double, bool global_change);
- std::list<boost::shared_ptr<Region> > _last_capture_regions;
+ std::list<boost::shared_ptr<Source> > _last_capture_sources;
virtual int use_pending_capture_data (XMLNode& node) = 0;
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 4b42fc0bd6..7afc074b4d 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -65,7 +65,8 @@ class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_
RegionListProperty (Playlist&);
boost::shared_ptr<Region> lookup_id (const PBD::ID& id);
- void diff (PBD::PropertyList& undo, PBD::PropertyList& redo) const;
+ void diff (PBD::PropertyList& undo, PBD::PropertyList& redo, Command*) const;
+ bool involves (boost::shared_ptr<Region>);
private:
friend class Playlist;
diff --git a/libs/ardour/ardour/public_diskstream.h b/libs/ardour/ardour/public_diskstream.h
index c31e88a79b..9e25cb24c6 100755
--- a/libs/ardour/ardour/public_diskstream.h
+++ b/libs/ardour/ardour/public_diskstream.h
@@ -23,7 +23,7 @@
namespace ARDOUR {
class Playlist;
-class Region;
+class Source;
class Location;
/** Public interface to a Diskstream */
@@ -34,7 +34,7 @@ public:
virtual boost::shared_ptr<Playlist> playlist () = 0;
virtual void monitor_input (bool) = 0;
virtual bool destructive () const = 0;
- virtual std::list<boost::shared_ptr<Region> > & last_capture_regions () = 0;
+ virtual std::list<boost::shared_ptr<Source> > & last_capture_sources () = 0;
virtual void set_capture_offset () = 0;
virtual void reset_write_sources (bool, bool force = false) = 0;
virtual float playback_buffer_load () const = 0;
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 2cf9bab97b..a30bb8660c 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -270,6 +270,8 @@ class Region
return _pending_explicit_relayer;
}
+ void drop_sources ();
+
protected:
friend class RegionFactory;
diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h
index c9f387f172..459699d810 100644
--- a/libs/ardour/ardour/region_factory.h
+++ b/libs/ardour/ardour/region_factory.h
@@ -21,6 +21,7 @@
#define __ardour_region_factory_h__
#include <map>
+#include <set>
#include <glibmm/thread.h>
#include "pbd/id.h"
@@ -78,7 +79,10 @@ class RegionFactory {
/** create a region with specified sources @param srcs and XML state */
static boost::shared_ptr<Region> create (SourceList& srcs, const XMLNode&);
+ static void get_regions_using_source (boost::shared_ptr<Source>, std::set<boost::shared_ptr<Region> >& );
+
static void map_remove (boost::shared_ptr<Region>);
+ static void map_remove_with_equivalents (boost::shared_ptr<Region>);
static void delete_all_regions ();
static const RegionMap& regions() { return region_map; }
static uint32_t nregions ();
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index f7692e09cb..bca65c88e4 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -512,8 +512,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int cleanup_sources (CleanupReport&);
int cleanup_trash_sources (CleanupReport&);
- int destroy_region (boost::shared_ptr<Region>);
- int destroy_regions (std::list<boost::shared_ptr<Region> >);
+ int destroy_sources (std::list<boost::shared_ptr<Source> >);
int remove_last_capture ();
diff --git a/libs/ardour/ardour/session_playlists.h b/libs/ardour/ardour/session_playlists.h
index d654595d60..1c83a312a5 100644
--- a/libs/ardour/ardour/session_playlists.h
+++ b/libs/ardour/ardour/session_playlists.h
@@ -53,6 +53,7 @@ public:
template<class T> void foreach (T *obj, void (T::*func)(boost::shared_ptr<Playlist>));
void get (std::vector<boost::shared_ptr<Playlist> >&);
void unassigned (std::list<boost::shared_ptr<Playlist> > & list);
+ void destroy_region (boost::shared_ptr<Region>);
private:
friend class Session;
@@ -69,7 +70,7 @@ private:
int load (Session &, const XMLNode&);
int load_unused (Session &, const XMLNode&);
boost::shared_ptr<Playlist> XMLPlaylistFactory (Session &, const XMLNode&);
-
+
mutable Glib::Mutex lock;
typedef std::set<boost::shared_ptr<Playlist> > List;
List playlists;
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index bf92e5a6e4..16a762eb94 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -23,6 +23,8 @@
#include <string>
#include <set>
+#include <glib.h>
+
#include <boost/utility.hpp>
#include "pbd/statefuldestructible.h"
@@ -102,6 +104,15 @@ class Source : public SessionObject
Glib::Mutex& mutex() { return _lock; }
Flag flags() const { return _flags; }
+ void inc_use_count () { g_atomic_int_inc (&_use_count); }
+ void dec_use_count () {
+ gint oldval = g_atomic_int_exchange_and_add (&_use_count, -1);
+ assert (oldval > 0);
+ }
+
+ int use_count() const { return g_atomic_int_get (&_use_count); }
+ bool used() const { return use_count() > 0; }
+
protected:
DataType _type;
Flag _flags;
@@ -111,6 +122,7 @@ class Source : public SessionObject
mutable Glib::Mutex _lock;
mutable Glib::Mutex _analysis_lock;
Glib::Mutex _playlist_lock;
+ gint _use_count; /* atomic */
private:
void fix_writable_flags ();
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index ac948f12df..d72d29e563 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -29,6 +29,7 @@ namespace ARDOUR {
class Session;
class Playlist;
class RouteGroup;
+class Source;
class Region;
class Diskstream;
@@ -100,7 +101,7 @@ class Track : public Route, public PublicDiskstream
boost::shared_ptr<Playlist> playlist ();
void monitor_input (bool);
bool destructive () const;
- std::list<boost::shared_ptr<Region> > & last_capture_regions ();
+ std::list<boost::shared_ptr<Source> > & last_capture_sources ();
void set_capture_offset ();
void reset_write_sources (bool, bool force = false);
float playback_buffer_load () const;
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index b3204c38b6..ae80690b81 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -480,8 +480,8 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can
was_recording = true;
}
- if (can_record && !_last_capture_regions.empty()) {
- _last_capture_regions.clear ();
+ if (can_record && !_last_capture_sources.empty()) {
+ _last_capture_sources.clear ();
}
if (rec_nframes) {
@@ -1447,7 +1447,6 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
plist.add (Properties::start, c->front()->write_source->last_capture_start_frame());
plist.add (Properties::length, total_capture);
plist.add (Properties::name, whole_file_region_name);
-
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
rx->set_automatic (true);
rx->set_whole_file (true);
@@ -1462,7 +1461,7 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
/* XXX what now? */
}
- _last_capture_regions.push_back (region);
+ _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
// cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
@@ -1494,10 +1493,6 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
continue; /* XXX is this OK? */
}
- 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);
-
i_am_the_modifier++;
_playlist->add_region (region, (*ci)->start, 1, non_layered());
i_am_the_modifier--;
@@ -1914,6 +1909,8 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
boost::shared_ptr<ChannelList> c = channels.reader();
uint32_t n;
+ cerr << name() << " resetting write sources, recrodable " << recordable() << " chans = " << c->size() << endl;
+
if (!_session.writable() || !recordable()) {
return;
}
@@ -2356,6 +2353,7 @@ void
AudioDiskstream::ChannelInfo::resize_capture (nframes_t capture_bufsize)
{
delete capture_buf;
+
capture_buf = new RingBufferNPT<Sample> (capture_bufsize);
memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize());
}
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index bd09af4e1f..6a27541bcd 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -663,17 +663,15 @@ bool
AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
{
boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
+
+ if (!r) {
+ return false;
+ }
+
bool changed = false;
Crossfades::iterator c, ctmp;
set<boost::shared_ptr<Crossfade> > unique_xfades;
- if (r == 0) {
- fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
- << endmsg;
- /*NOTREACHED*/
- return false;
- }
-
{
RegionLock rlock (this);
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 0ef79b7018..80f8baef0e 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -263,6 +263,9 @@ AudioRegion::connect_to_header_position_offset_changed ()
for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
+ /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
+ */
+
if (unique_srcs.find (*i) == unique_srcs.end ()) {
unique_srcs.insert (*i);
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
@@ -520,24 +523,8 @@ AudioRegion::state (bool full)
XMLNode& node (Region::state (full));
XMLNode *child;
char buf[64];
- char buf2[64];
LocaleGuard lg (X_("POSIX"));
-
- // XXX these should move into Region
-
- 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);
- }
-
snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
node.add_property ("channels", buf);
@@ -571,10 +558,6 @@ AudioRegion::state (bool full)
child->add_property ("default", "yes");
}
- if (full && _extra_xml) {
- node.add_child_copy (*_extra_xml);
- }
-
return node;
}
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 40a2714dc0..5dd9a3b306 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -436,18 +436,6 @@ Diskstream::set_name (const string& str)
}
void
-Diskstream::remove_region_from_last_capture (boost::weak_ptr<Region> wregion)
-{
- boost::shared_ptr<Region> region (wregion.lock());
-
- if (!region) {
- return;
- }
-
- _last_capture_regions.remove (region);
-}
-
-void
Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<framepos_t> > const & movements_frames)
{
if (!_track || Config->get_automation_follows_regions () == false) {
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index fa2cdce014..444e4d3788 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -524,8 +524,8 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_
}
- if (can_record && !_last_capture_regions.empty()) {
- _last_capture_regions.clear ();
+ if (can_record && !_last_capture_sources.empty()) {
+ _last_capture_sources.clear ();
}
if (nominally_recording || rec_nframes) {
@@ -975,9 +975,7 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
/* XXX what now? */
}
- _last_capture_regions.push_back (region);
-
- // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
+ _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
_playlist->clear_history ();
_playlist->freeze ();
@@ -1007,10 +1005,6 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
continue; /* XXX is this OK? */
}
- 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);
-
// cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
i_am_the_modifier++;
@@ -1312,6 +1306,8 @@ MidiDiskstream::set_state (const XMLNode& node, int /*version*/)
int
MidiDiskstream::use_new_write_source (uint32_t n)
{
+ cerr << name() << " use new write source for n = " << n << " recordable ? " << recordable() << endl;
+
if (!recordable()) {
return 1;
}
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index 152735de85..6f5dee979a 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -359,15 +359,13 @@ bool
MidiPlaylist::destroy_region (boost::shared_ptr<Region> region)
{
boost::shared_ptr<MidiRegion> r = boost::dynamic_pointer_cast<MidiRegion> (region);
- bool changed = false;
- if (r == 0) {
- PBD::fatal << _("programming error: non-midi Region passed to remove_overlap in midi playlist")
- << endmsg;
- /*NOTREACHED*/
+ if (!r) {
return false;
}
+ bool changed = false;
+
{
RegionLock rlock (this);
RegionList::iterator i;
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc
index fe03e64f72..abb3191463 100644
--- a/libs/ardour/midi_region.cc
+++ b/libs/ardour/midi_region.cc
@@ -193,30 +193,7 @@ MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<nframes_t>&
XMLNode&
MidiRegion::state (bool full)
{
- XMLNode& node (Region::state (full));
- char buf[64];
- char buf2[64];
- LocaleGuard lg (X_("POSIX"));
-
- // XXX these should move into Region
-
- 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;
+ return Region::state (full);
}
int
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 0526d48b11..f07cd645f1 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -134,7 +134,7 @@ RegionListProperty::copy_for_history () const
}
void
-RegionListProperty::diff (PropertyList& undo, PropertyList& redo) const
+RegionListProperty::diff (PropertyList& undo, PropertyList& redo, Command* cmd) const
{
if (changed()) {
/* list of the removed/added regions since clear_history() was last called */
@@ -144,6 +144,18 @@ RegionListProperty::diff (PropertyList& undo, PropertyList& redo) const
RegionListProperty* b = copy_for_history ();
b->invert_changes ();
+ if (cmd) {
+ /* whenever one of the regions emits DropReferences, make sure
+ that the Destructible we've been told to notify hears about
+ it. the Destructible is likely to be the Command being built
+ with this diff().
+ */
+
+ for (set<boost::shared_ptr<Region> >::iterator i = a->change().added.begin(); i != a->change().added.end(); ++i) {
+ (*i)->DropReferences.connect_same_thread (*cmd, boost::bind (&Destructible::drop_references, cmd));
+ }
+ }
+
undo.add (b);
redo.add (a);
}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 2589f94f81..e620319633 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -415,6 +415,7 @@ Region::Region (boost::shared_ptr<const Region> other)
Region::~Region ()
{
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 destructor @ %2\n", _name, this));
+ drop_sources ();
}
void
@@ -1126,10 +1127,12 @@ Region::set_layer (layer_t l)
}
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);
@@ -1164,6 +1167,22 @@ Region::state (bool /*full_state*/)
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;
}
@@ -1237,11 +1256,6 @@ Region::_set_state (const XMLNode& node, int version, PropertyChange& what_chang
}
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);
}
@@ -1335,7 +1349,7 @@ Region::region_list_equivalent (boost::shared_ptr<const Region> other) const
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
@@ -1366,8 +1380,16 @@ Region::master_source_names ()
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
@@ -1408,6 +1430,7 @@ Region::uses_source (boost::shared_ptr<const Source> source) const
sframes_t
Region::source_length(uint32_t n) const
{
+ assert (n < _sources.size());
return _sources[n]->length(_position - _start);
}
@@ -1420,7 +1443,7 @@ Region::verify_length (framecnt_t len)
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);
}
@@ -1438,7 +1461,7 @@ Region::verify_start_and_length (framepos_t new_start, framecnt_t& new_length)
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);
}
@@ -1454,7 +1477,7 @@ Region::verify_start (framepos_t pos)
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;
}
@@ -1469,7 +1492,7 @@ Region::verify_start_mutable (framepos_t& new_start)
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;
}
@@ -1508,6 +1531,21 @@ Region::invalidate_transients ()
_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)
@@ -1515,16 +1553,19 @@ 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)));
+ }
}
}
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
index 5a4b129710..65649ad8f7 100644
--- a/libs/ardour/region_factory.cc
+++ b/libs/ardour/region_factory.cc
@@ -73,6 +73,7 @@ RegionFactory::create (boost::shared_ptr<const Region> region)
}
if (ret) {
+ cerr << "Pure copy constructor region " << ret << " named " << ret->name() << endl;
map_add (ret);
/* pure copy constructor - no property list */
@@ -124,6 +125,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, frameoffset_t offset, b
if (ret) {
ret->set_properties (plist);
+ cerr << "Partial copy constructor region\n";
map_add (ret);
if (announce) {
@@ -163,6 +165,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
if (ret) {
ret->set_properties (plist);
+ cerr << "New sources copy constructor region\n";
map_add (ret);
if (announce) {
@@ -208,6 +211,7 @@ RegionFactory::create (const SourceList& srcs, const PropertyList& plist, bool a
if (ret) {
ret->set_properties (plist);
+ cerr << "de-novo constructor region " << ret << " named " << ret->name() << endl;
map_add (ret);
if (announce) {
@@ -281,6 +285,8 @@ RegionFactory::map_add (boost::shared_ptr<Region> r)
boost::bind (&RegionFactory::region_changed, _1, boost::weak_ptr<Region> (r))
);
+ cerr << "Added region with ID = " << r->id() << " named " << r->name() << endl;
+
update_region_name_map (r);
}
@@ -292,7 +298,32 @@ RegionFactory::map_remove (boost::shared_ptr<Region> r)
if (i != region_map.end()) {
region_map.erase (i);
+ cerr << "Removed region with ID = " << r->id() << " named " << r->name() << endl;;
}
+
+}
+
+void
+RegionFactory::map_remove_with_equivalents (boost::shared_ptr<Region> r)
+{
+ Glib::Mutex::Lock lm (region_map_lock);
+
+ for (RegionMap::iterator i = region_map.begin(); i != region_map.end(); ) {
+ RegionMap::iterator tmp = i;
+ ++tmp;
+
+ if (r->region_list_equivalent (i->second)) {
+ cerr << "Removed equivalent region " << i->second->name() << '/' << i->first << endl;
+ region_map.erase (i);
+ } else if (r == i->second) {
+ cerr << "Removed actual region " << i->second->name() << '/' << i->first << endl;
+ region_map.erase (i);
+ }
+
+ i = tmp;
+ }
+
+
}
boost::shared_ptr<Region>
@@ -487,3 +518,15 @@ RegionFactory::new_region_name (string old)
error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
return old;
}
+
+void
+RegionFactory::get_regions_using_source (boost::shared_ptr<Source> s, std::set<boost::shared_ptr<Region> >& r)
+{
+ Glib::Mutex::Lock lm (region_map_lock);
+
+ for (RegionMap::iterator i = region_map.begin(); i != region_map.end(); ++i) {
+ if (i->second->uses_source (s)) {
+ r.insert (i->second);
+ }
+ }
+}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 3d5430d259..91b1e2a0f9 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1484,6 +1484,7 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m
auto_connect_route (track, existing_inputs, existing_outputs);
track->non_realtime_input_change();
+
if (route_group) {
route_group->add (track);
}
@@ -2483,46 +2484,58 @@ Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
}
int
-Session::destroy_region (boost::shared_ptr<Region> region)
+Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
{
- vector<boost::shared_ptr<Source> > srcs;
-
- {
- if (region->playlist()) {
- region->playlist()->destroy_region (region);
- }
+ set<boost::shared_ptr<Region> > relevant_regions;
- for (uint32_t n = 0; n < region->n_channels(); ++n) {
- srcs.push_back (region->source (n));
- }
+ for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
+ RegionFactory::get_regions_using_source (*s, relevant_regions);
}
- region->drop_references ();
+ cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
+
+ for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
+ set<boost::shared_ptr<Region> >::iterator tmp;
+
+ tmp = r;
+ ++tmp;
+
+ cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
- for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
+ playlists->destroy_region (*r);
+ RegionFactory::map_remove (*r);
- (*i)->mark_for_remove ();
- (*i)->drop_references ();
+ (*r)->drop_sources ();
+ (*r)->drop_references ();
+
+ cerr << "\tdone UC = " << (*r).use_count() << endl;
+
+ relevant_regions.erase (r);
+
+ r = tmp;
+ }
+
+ for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
- cerr << "source was not used by any playlist\n";
- }
+ {
+ Glib::Mutex::Lock ls (source_lock);
+ /* remove from the main source list */
+ sources.erase ((*s)->id());
+ }
- return 0;
-}
+ (*s)->mark_for_remove ();
+ (*s)->drop_references ();
+
+ s = srcs.erase (s);
+ }
-int
-Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
-{
- for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
- destroy_region (*i);
- }
return 0;
}
int
Session::remove_last_capture ()
{
- list<boost::shared_ptr<Region> > r;
+ list<boost::shared_ptr<Source> > srcs;
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
@@ -2531,15 +2544,15 @@ Session::remove_last_capture ()
continue;
}
- list<boost::shared_ptr<Region> >& l = tr->last_capture_regions();
+ list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
if (!l.empty()) {
- r.insert (r.end(), l.begin(), l.end());
+ srcs.insert (srcs.end(), l.begin(), l.end());
l.clear ();
}
}
- destroy_regions (r);
+ destroy_sources (srcs);
save_state (_current_snapshot_name);
@@ -2563,16 +2576,19 @@ Session::add_source (boost::shared_ptr<Source> source)
}
if (result.second) {
- set_dirty();
- }
- boost::shared_ptr<AudioFileSource> afs;
+ /* yay, new source */
- if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
- if (Config->get_auto_analyse_audio()) {
- Analyser::queue_source_for_analysis (source, false);
- }
- }
+ set_dirty();
+
+ boost::shared_ptr<AudioFileSource> afs;
+
+ if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
+ if (Config->get_auto_analyse_audio()) {
+ Analyser::queue_source_for_analysis (source, false);
+ }
+ }
+ }
}
void
diff --git a/libs/ardour/session_playlists.cc b/libs/ardour/session_playlists.cc
index 2f8ae9a8f0..38c6744d06 100644
--- a/libs/ardour/session_playlists.cc
+++ b/libs/ardour/session_playlists.cc
@@ -220,6 +220,21 @@ SessionPlaylists::get (vector<boost::shared_ptr<Playlist> >& s)
}
void
+SessionPlaylists::destroy_region (boost::shared_ptr<Region> r)
+{
+ Glib::Mutex::Lock lm (lock);
+
+ for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ (*i)->destroy_region (r);
+ }
+
+ for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+ (*i)->destroy_region (r);
+ }
+}
+
+
+void
SessionPlaylists::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
{
for (List::iterator i = playlists.begin(); i != playlists.end(); ++i)
@@ -262,14 +277,12 @@ SessionPlaylists::add_state (XMLNode* node, bool full_state)
XMLNode* child = node->add_child ("Playlists");
for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
if (!(*i)->hidden()) {
- if (!(*i)->empty()) {
- if (full_state) {
- child->add_child_nocopy ((*i)->get_state());
- } else {
- child->add_child_nocopy ((*i)->get_template());
- }
- }
- }
+ if (full_state) {
+ child->add_child_nocopy ((*i)->get_state());
+ } else {
+ child->add_child_nocopy ((*i)->get_template());
+ }
+ }
}
child = node->add_child ("UnusedPlaylists");
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index a490bb10c9..0f8583a822 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -1040,13 +1040,18 @@ Session::state(bool full_state)
for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
- /* Don't save information about non-destructive file sources that are empty */
- /* FIXME: MIDI breaks if this is made FileSource like it should be... */
+ /* Don't save information about non-destructive file sources that are empty
+ and unused by any regions.
+ */
- boost::shared_ptr<AudioFileSource> fs;
- if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
+ cerr << "Source " << siter->second->name() << " has UC = " << siter->second->used()
+ << " length = " << siter->second->length (0)
+ << endl;
+
+ boost::shared_ptr<FileSource> fs;
+ if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
if (!fs->destructive()) {
- if (fs->length(fs->timeline_position()) == 0) {
+ if (fs->length(fs->timeline_position()) == 0 && !fs->used()) {
continue;
}
}
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 5ec9631e40..55ce9f8bef 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -52,6 +52,7 @@ Source::Source (Session& s, DataType type, const string& name, Flag flags)
, _type(type)
, _flags(flags)
, _timeline_position(0)
+ , _use_count (0)
{
_analysed = false;
_timestamp = 0;
@@ -63,6 +64,7 @@ Source::Source (Session& s, const XMLNode& node)
, _type(DataType::AUDIO)
, _flags (Flag (Writable|CanRename))
, _timeline_position(0)
+ , _use_count (0)
{
_timestamp = 0;
_analysed = false;
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index ad4c765867..b2079e0a2e 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -425,10 +425,10 @@ Track::destructive () const
return _diskstream->destructive ();
}
-list<boost::shared_ptr<Region> > &
-Track::last_capture_regions ()
+list<boost::shared_ptr<Source> > &
+Track::last_capture_sources ()
{
- return _diskstream->last_capture_regions ();
+ return _diskstream->last_capture_sources ();
}
void
diff --git a/libs/evoral/src/SMF.cpp b/libs/evoral/src/SMF.cpp
index b8705afbf0..cf838455ce 100644
--- a/libs/evoral/src/SMF.cpp
+++ b/libs/evoral/src/SMF.cpp
@@ -275,6 +275,16 @@ SMF::begin_write()
void
SMF::end_write() THROW_FILE_ERROR
{
+#if 0
+ /* don't create empty MIDI files
+ */
+
+ smf_rewind (_smf); // smf_save() would have done this anyway
+ if (smf_peek_next_event (_smf) == 0) {
+ return;
+ }
+#endif
+
PBD::StdioFileDescriptor d (_file_path, "w+");
FILE* f = d.allocate ();
if (f == 0) {
diff --git a/libs/pbd/pbd/command.h b/libs/pbd/pbd/command.h
index 5a7290bc89..c6c3c8d3fd 100644
--- a/libs/pbd/pbd/command.h
+++ b/libs/pbd/pbd/command.h
@@ -22,10 +22,12 @@
#ifndef __lib_pbd_command_h__
#define __lib_pbd_command_h__
+#include <string>
+
+#include "pbd/signals.h"
#include "pbd/statefuldestructible.h"
-#include <boost/utility.hpp>
-class Command : public PBD::StatefulDestructible, public boost::noncopyable
+class Command : public PBD::StatefulDestructible, public PBD::ScopedConnectionList
{
public:
virtual ~Command() { /* NOTE: derived classes must call drop_references() */ }
@@ -34,7 +36,7 @@ public:
void set_name (const std::string& str) { _name = str; }
const std::string& name() const { return _name; }
-
+
virtual void undo() = 0;
virtual void redo() { (*this)(); }
diff --git a/libs/pbd/pbd/properties.h b/libs/pbd/pbd/properties.h
index 784282ee9c..1914344db9 100644
--- a/libs/pbd/pbd/properties.h
+++ b/libs/pbd/pbd/properties.h
@@ -165,7 +165,7 @@ public:
: PropertyTemplate<T> (q, v)
{}
- void diff (PropertyList& undo, PropertyList& redo) const {
+ void diff (PropertyList& undo, PropertyList& redo, Command* /*ignored*/) const {
if (this->_have_old) {
undo.add (new Property<T> (this->property_id(), this->_old));
redo.add (new Property<T> (this->property_id(), this->_current));
@@ -227,7 +227,7 @@ public:
: PropertyTemplate<std::string> (q, v)
{}
- void diff (PropertyList& before, PropertyList& after) const {
+ void diff (PropertyList& before, PropertyList& after, Command* /*ignored*/) const {
if (this->_have_old) {
before.add (new Property<std::string> (PropertyDescriptor<std::string> (this->property_id()), this->_old));
after.add (new Property<std::string> (PropertyDescriptor<std::string> (this->property_id()), this->_current));
diff --git a/libs/pbd/pbd/property_basics.h b/libs/pbd/pbd/property_basics.h
index 5e94abdfc3..2dea20e251 100644
--- a/libs/pbd/pbd/property_basics.h
+++ b/libs/pbd/pbd/property_basics.h
@@ -25,6 +25,8 @@
#include "pbd/xml++.h"
+class Command;
+
namespace PBD {
class PropertyList;
@@ -83,7 +85,7 @@ public:
{}
virtual ~PropertyBase () {}
-
+
/** Forget about any old value for this state */
virtual void clear_history () = 0;
@@ -97,7 +99,7 @@ public:
* the last call to clear_history, and one that allows redo
* of those changes.
*/
- virtual void diff (PropertyList& undo, PropertyList& redo) const = 0;
+ virtual void diff (PropertyList& undo, PropertyList& redo, Command*) const = 0;
virtual PropertyBase* maybe_clone_self_if_found_in_history_node (const XMLNode&) const { return 0; }
diff --git a/libs/pbd/pbd/stateful.h b/libs/pbd/pbd/stateful.h
index 4352e88201..1272a735f9 100644
--- a/libs/pbd/pbd/stateful.h
+++ b/libs/pbd/pbd/stateful.h
@@ -67,7 +67,7 @@ class Stateful {
/* history management */
void clear_history ();
- void diff (PropertyList&, PropertyList&) const;
+ void diff (PropertyList&, PropertyList&, Command*) const;
bool changed() const;
/* create a property list from an XMLNode
diff --git a/libs/pbd/pbd/stateful_diff_command.h b/libs/pbd/pbd/stateful_diff_command.h
index 21245f029a..25cdfbba12 100644
--- a/libs/pbd/pbd/stateful_diff_command.h
+++ b/libs/pbd/pbd/stateful_diff_command.h
@@ -27,7 +27,7 @@
namespace PBD
{
-class Stateful;
+class StatefulDestructible;
class PropertyList;
/** A Command which stores its action as the differences between the before and after
@@ -36,13 +36,13 @@ class PropertyList;
class StatefulDiffCommand : public Command
{
public:
- StatefulDiffCommand (boost::shared_ptr<Stateful>);
- StatefulDiffCommand (boost::shared_ptr<Stateful>, XMLNode const &);
+ StatefulDiffCommand (boost::shared_ptr<StatefulDestructible>);
+ StatefulDiffCommand (boost::shared_ptr<StatefulDestructible>, XMLNode const &);
~StatefulDiffCommand ();
void operator() ();
void undo ();
-
+
XMLNode& get_state ();
private:
diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h
index 6eb9e00056..fb5152c293 100644
--- a/libs/pbd/pbd/undo.h
+++ b/libs/pbd/pbd/undo.h
@@ -27,12 +27,11 @@
#include <sigc++/bind.h>
#include <sys/time.h>
-#include "pbd/signals.h"
#include "pbd/command.h"
typedef sigc::slot<void> UndoAction;
-class UndoTransaction : public Command, public PBD::ScopedConnectionList
+class UndoTransaction : public Command
{
public:
UndoTransaction ();
diff --git a/libs/pbd/stateful.cc b/libs/pbd/stateful.cc
index b486319c4c..1c3d08b3a9 100644
--- a/libs/pbd/stateful.cc
+++ b/libs/pbd/stateful.cc
@@ -167,10 +167,10 @@ Stateful::clear_history ()
}
void
-Stateful::diff (PropertyList& before, PropertyList& after) const
+Stateful::diff (PropertyList& before, PropertyList& after, Command* cmd) const
{
for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
- i->second->diff (before, after);
+ i->second->diff (before, after, cmd);
}
}
diff --git a/libs/pbd/stateful_diff_command.cc b/libs/pbd/stateful_diff_command.cc
index 635fe4829a..2c58acee14 100644
--- a/libs/pbd/stateful_diff_command.cc
+++ b/libs/pbd/stateful_diff_command.cc
@@ -32,15 +32,21 @@ using namespace PBD;
* @param s Stateful object.
*/
-StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<Stateful> s)
- : _object (s)
+StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<StatefulDestructible> s)
+ : _object (s)
, _undo (new PropertyList)
, _redo (new PropertyList)
{
- s->diff (*_undo, *_redo);
+ s->diff (*_undo, *_redo, this);
+
+ /* if the stateful object that this command refers to goes away,
+ be sure to notify owners of this command.
+ */
+
+ s->DropReferences.connect_same_thread (*this, boost::bind (&Destructible::drop_references, this));
}
-StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<Stateful> s, XMLNode const & n)
+StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<StatefulDestructible> s, XMLNode const & n)
: _object (s)
, _undo (0)
, _redo (0)
@@ -57,10 +63,18 @@ StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<Stateful> s, XMLNode
assert (_undo != 0);
assert (_redo != 0);
+
+ /* if the stateful object that this command refers to goes away,
+ be sure to notify owners of this command.
+ */
+
+ s->DropReferences.connect_same_thread (*this, boost::bind (&Destructible::drop_references, this));
}
StatefulDiffCommand::~StatefulDiffCommand ()
{
+ drop_references ();
+
delete _undo;
delete _redo;
}
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index a06127926f..120f62c351 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -39,7 +39,6 @@ UndoTransaction::UndoTransaction ()
UndoTransaction::UndoTransaction (const UndoTransaction& rhs)
: Command(rhs._name)
- , PBD::ScopedConnectionList ()
, _clearing(false)
{
clear ();
@@ -77,15 +76,15 @@ UndoTransaction::operator= (const UndoTransaction& rhs)
}
void
-UndoTransaction::add_command (Command *const action)
+UndoTransaction::add_command (Command *const cmd)
{
/* catch death of command (e.g. caused by death of object to
which it refers. command_death() is a normal static function
so there is no need to manage this connection.
*/
- action->DropReferences.connect_same_thread (*this, boost::bind (&command_death, this, action));
- actions.push_back (action);
+ cmd->DropReferences.connect_same_thread (*this, boost::bind (&command_death, this, cmd));
+ actions.push_back (cmd);
}
void
@@ -250,9 +249,6 @@ UndoHistory::undo (unsigned int n)
return;
}
- struct timeval start, end, diff;
- gettimeofday (&start, 0);
-
{
UndoRedoSignaller exception_safe_signaller (*this);
@@ -265,16 +261,8 @@ UndoHistory::undo (unsigned int n)
ut->undo ();
RedoList.push_back (ut);
}
- gettimeofday (&end, 0);
- timersub (&end, &start, &diff);
- cerr << "Undo-pre-signals took " << diff.tv_sec << '.' << diff.tv_usec << endl;
-
}
- gettimeofday (&end, 0);
- timersub (&end, &start, &diff);
- cerr << "Undo took " << diff.tv_sec << '.' << diff.tv_usec << endl;
-
Changed (); /* EMIT SIGNAL */
}
@@ -285,9 +273,6 @@ UndoHistory::redo (unsigned int n)
return;
}
- struct timeval start, end, diff;
- gettimeofday (&start, 0);
-
{
UndoRedoSignaller exception_safe_signaller (*this);
@@ -300,15 +285,8 @@ UndoHistory::redo (unsigned int n)
ut->redo ();
UndoList.push_back (ut);
}
- gettimeofday (&end, 0);
- timersub (&end, &start, &diff);
- cerr << "Redo-pre-signals took " << diff.tv_sec << '.' << diff.tv_usec << endl;
}
- gettimeofday (&end, 0);
- timersub (&end, &start, &diff);
- cerr << "Redo took " << diff.tv_sec << '.' << diff.tv_usec << endl;
-
Changed (); /* EMIT SIGNAL */
}