summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-08-25 01:07:15 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-08-25 01:07:15 +0000
commitce234f363e95c38fc92728e520bf5ba240a89aa7 (patch)
tree96ce8c4734bdd564ec1f2ad0c36bc32f0b108204 /libs
parent7e95f29ce95edf01d6d451f96fae03f3d3451ff8 (diff)
use shared_ptr<> for all region handling
git-svn-id: svn://localhost/ardour2/trunk@852 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/audio_diskstream.h2
-rw-r--r--libs/ardour/ardour/audiofilter.h8
-rw-r--r--libs/ardour/ardour/audioplaylist.h14
-rw-r--r--libs/ardour/ardour/audioregion.h23
-rw-r--r--libs/ardour/ardour/auditioner.h4
-rw-r--r--libs/ardour/ardour/automation_event.h5
-rw-r--r--libs/ardour/ardour/crossfade.h29
-rw-r--r--libs/ardour/ardour/diskstream.h8
-rw-r--r--libs/ardour/ardour/io.h6
-rw-r--r--libs/ardour/ardour/location.h6
-rw-r--r--libs/ardour/ardour/playlist.h75
-rw-r--r--libs/ardour/ardour/playlist_templates.h4
-rw-r--r--libs/ardour/ardour/plugin.h6
-rw-r--r--libs/ardour/ardour/redirect.h1
-rw-r--r--libs/ardour/ardour/region.h44
-rw-r--r--libs/ardour/ardour/region_factory.h28
-rw-r--r--libs/ardour/ardour/reverse.h2
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/ardour/session.h60
-rw-r--r--libs/ardour/ardour/session_region.h2
-rw-r--r--libs/ardour/ardour/source.h5
-rw-r--r--libs/ardour/ardour/tempo.h6
-rw-r--r--libs/ardour/ardour/types.h4
-rw-r--r--libs/ardour/audio_diskstream.cc50
-rw-r--r--libs/ardour/audio_playlist.cc145
-rw-r--r--libs/ardour/audio_track.cc12
-rw-r--r--libs/ardour/audiofilter.cc23
-rw-r--r--libs/ardour/audioregion.cc95
-rw-r--r--libs/ardour/auditioner.cc15
-rw-r--r--libs/ardour/automation_event.cc2
-rw-r--r--libs/ardour/control_protocol_manager.cc2
-rw-r--r--libs/ardour/coreaudiosource.cc2
-rw-r--r--libs/ardour/crossfade.cc38
-rw-r--r--libs/ardour/diskstream.cc4
-rw-r--r--libs/ardour/import.cc18
-rw-r--r--libs/ardour/insert.cc4
-rw-r--r--libs/ardour/ladspa_plugin.cc2
-rw-r--r--libs/ardour/location.cc34
-rw-r--r--libs/ardour/osc.cc2
-rw-r--r--libs/ardour/playlist.cc221
-rw-r--r--libs/ardour/playlist_factory.cc46
-rw-r--r--libs/ardour/region.cc73
-rw-r--r--libs/ardour/reverse.cc16
-rw-r--r--libs/ardour/send.cc2
-rw-r--r--libs/ardour/session.cc115
-rw-r--r--libs/ardour/session_command.cc7
-rw-r--r--libs/ardour/session_events.cc2
-rw-r--r--libs/ardour/session_state.cc48
-rw-r--r--libs/ardour/session_timefx.cc23
-rw-r--r--libs/ardour/sndfilesource.cc11
-rw-r--r--libs/ardour/vst_plugin.cc2
-rw-r--r--libs/pbd/pbd/command.h3
-rw-r--r--libs/pbd/pbd/memento_command.h39
-rw-r--r--libs/pbd/pbd/statefuldestructible.h13
-rw-r--r--libs/pbd/pbd/undo.h34
-rw-r--r--libs/pbd/undo.cc78
57 files changed, 789 insertions, 737 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 44cec8638c..09fd5e9b8e 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -70,6 +70,7 @@ port.cc
recent_sessions.cc
redirect.cc
region.cc
+region_factory.cc
reverse.cc
route.cc
route_group.cc
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 18f8328cfd..eaa69e00d8 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -141,8 +141,6 @@ class AudioDiskstream : public Diskstream
}
}
- std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
-
XMLNode* deprecated_io_node;
protected:
diff --git a/libs/ardour/ardour/audiofilter.h b/libs/ardour/ardour/audiofilter.h
index 02e5e6f061..c8762dbf69 100644
--- a/libs/ardour/ardour/audiofilter.h
+++ b/libs/ardour/ardour/audiofilter.h
@@ -36,14 +36,14 @@ class AudioFilter {
: session (s){}
virtual ~AudioFilter() {}
- virtual int run (ARDOUR::AudioRegion&) = 0;
- std::vector<ARDOUR::AudioRegion*> results;
+ virtual int run (boost::shared_ptr<ARDOUR::AudioRegion>) = 0;
+ std::vector<boost::shared_ptr<ARDOUR::AudioRegion> > results;
protected:
ARDOUR::Session& session;
- int make_new_sources (ARDOUR::AudioRegion&, ARDOUR::AudioRegion::SourceList&);
- int finish (ARDOUR::AudioRegion&, ARDOUR::AudioRegion::SourceList&);
+ int make_new_sources (boost::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::SourceList&);
+ int finish (boost::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::SourceList&);
};
} /* namespace */
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
index bd76c30289..0426208ba1 100644
--- a/libs/ardour/ardour/audioplaylist.h
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -58,7 +58,7 @@ class AudioPlaylist : public ARDOUR::Playlist
AudioPlaylist (const AudioPlaylist&, string name, bool hidden = false);
AudioPlaylist (const AudioPlaylist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
- void clear (bool with_delete = false, bool with_save = true);
+ void clear (bool with_save = true);
jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0);
@@ -75,7 +75,7 @@ class AudioPlaylist : public ARDOUR::Playlist
(obj.*method) (states, _current_state_id);
}
- bool destroy_region (Region*);
+ bool destroy_region (boost::shared_ptr<Region>);
void drop_all_states ();
@@ -91,11 +91,11 @@ class AudioPlaylist : public ARDOUR::Playlist
void notify_crossfade_added (Crossfade *);
void flush_notifications ();
- void finalize_split_region (Region *orig, Region *left, Region *right);
+ void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
- void refresh_dependents (Region& region);
- void check_dependents (Region& region, bool norefresh);
- void remove_dependents (Region& region);
+ void refresh_dependents (boost::shared_ptr<Region> region);
+ void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
+ void remove_dependents (boost::shared_ptr<Region> region);
protected:
~AudioPlaylist (); /* public should use unref() */
@@ -108,7 +108,7 @@ class AudioPlaylist : public ARDOUR::Playlist
XMLNode& state (bool full_state);
void dump () const;
- bool region_changed (Change, Region*);
+ bool region_changed (Change, boost::shared_ptr<Region>);
void crossfade_changed (Change);
void add_crossfade (Crossfade&);
};
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index 0c08392325..ad8672a269 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -57,8 +57,6 @@ struct AudioRegionState : public RegionState
class AudioRegion : public Region
{
public:
- typedef vector<AudioSource *> SourceList;
-
static Change FadeInChanged;
static Change FadeOutChanged;
static Change FadeInActiveChanged;
@@ -67,16 +65,9 @@ class AudioRegion : public Region
static Change ScaleAmplitudeChanged;
static Change EnvelopeChanged;
- AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, bool announce = true);
- AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- AudioRegion (const AudioRegion&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- AudioRegion (const AudioRegion&);
- AudioRegion (AudioSource&, const XMLNode&);
- AudioRegion (SourceList &, const XMLNode&);
~AudioRegion();
- bool source_equivalent (const Region&) const;
+ bool source_equivalent (boost::shared_ptr<const Region>) const;
bool speed_mismatch (float) const;
@@ -152,7 +143,7 @@ class AudioRegion : public Region
int exportme (ARDOUR::Session&, ARDOUR::AudioExportSpecification&);
- Region* get_parent();
+ boost::shared_ptr<Region> get_parent();
/* xfade/fade interactions */
@@ -162,7 +153,15 @@ class AudioRegion : public Region
void resume_fade_out ();
private:
- friend class Playlist;
+ friend class RegionFactory;
+
+ AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length);
+ AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (boost::shared_ptr<const AudioRegion>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (boost::shared_ptr<const AudioRegion>);
+ AudioRegion (AudioSource&, const XMLNode&);
+ AudioRegion (SourceList &, const XMLNode&);
private:
void set_default_fades ();
diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h
index 434ec32f97..c693589864 100644
--- a/libs/ardour/ardour/auditioner.h
+++ b/libs/ardour/ardour/auditioner.h
@@ -40,7 +40,7 @@ class Auditioner : public AudioTrack
Auditioner (Session&);
~Auditioner ();
- void audition_region (AudioRegion&);
+ void audition_region (boost::shared_ptr<AudioRegion>);
ARDOUR::AudioPlaylist& prepare_playlist ();
void audition_current_playlist ();
@@ -54,7 +54,7 @@ class Auditioner : public AudioTrack
bool active() const { return g_atomic_int_get (&_active); }
private:
- AudioRegion *the_region;
+ boost::shared_ptr<AudioRegion> the_region;
jack_nframes_t current_frame;
mutable gint _active;
Glib::Mutex lock;
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
index dad94161d0..a3b84289c1 100644
--- a/libs/ardour/ardour/automation_event.h
+++ b/libs/ardour/ardour/automation_event.h
@@ -27,8 +27,11 @@
#include <sigc++/signal.h>
#include <glibmm/thread.h>
+
#include <pbd/undo.h>
#include <pbd/xml++.h>
+#include <pbd/statefuldestructible.h>
+
#include <ardour/ardour.h>
#include <ardour/state_manager.h>
@@ -51,7 +54,7 @@ struct ControlEvent {
};
-class AutomationList : public StateManager, public Stateful
+ class AutomationList : public StateManager, public PBD::StatefulDestructible
{
public:
typedef std::list<ControlEvent*> AutomationEventList;
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
index aea7b31852..ded41bbfda 100644
--- a/libs/ardour/ardour/crossfade.h
+++ b/libs/ardour/ardour/crossfade.h
@@ -23,10 +23,12 @@
#include <vector>
#include <algorithm>
+#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
#include <pbd/undo.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/curve.h>
@@ -51,7 +53,7 @@ struct CrossfadeState : public StateManager::State {
bool active;
};
-class Crossfade : public Stateful, public StateManager
+class Crossfade : public PBD::StatefulDestructible, public StateManager
{
public:
@@ -62,7 +64,7 @@ class Crossfade : public Stateful, public StateManager
/* constructor for "fixed" xfades at each end of an internal overlap */
- Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out,
+ Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out,
jack_nframes_t position,
jack_nframes_t initial_length,
AnchorPoint);
@@ -71,12 +73,12 @@ class Crossfade : public Stateful, public StateManager
except the "internal" case.
*/
- Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out, CrossfadeModel, bool active);
+ Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out, CrossfadeModel, bool active);
/* copy constructor to copy a crossfade with new regions. used (for example)
when a playlist copy is made */
- Crossfade (const Crossfade &, ARDOUR::AudioRegion *, ARDOUR::AudioRegion *);
+ Crossfade (const Crossfade &, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>);
/* the usual XML constructor */
@@ -88,8 +90,8 @@ class Crossfade : public Stateful, public StateManager
XMLNode& get_state (void);
int set_state (const XMLNode&);
- ARDOUR::AudioRegion& in() const { return *_in; }
- ARDOUR::AudioRegion& out() const { return *_out; }
+ boost::shared_ptr<ARDOUR::AudioRegion> in() const { return _in; }
+ boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; }
jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
@@ -107,12 +109,12 @@ class Crossfade : public Stateful, public StateManager
return std::min (_in->layer(), _out->layer());
}
- bool involves (ARDOUR::AudioRegion& region) const {
- return _in == &region || _out == &region;
+ bool involves (boost::shared_ptr<ARDOUR::AudioRegion> region) const {
+ return _in == region || _out == region;
}
- bool involves (ARDOUR::AudioRegion& a, ARDOUR::AudioRegion& b) const {
- return (_in == &a && _out == &b) || (_in == &b && _out == &a);
+ bool involves (boost::shared_ptr<ARDOUR::AudioRegion> a, boost::shared_ptr<ARDOUR::AudioRegion> b) const {
+ return (_in == a && _out == b) || (_in == b && _out == a);
}
jack_nframes_t length() const { return _length; }
@@ -120,7 +122,6 @@ class Crossfade : public Stateful, public StateManager
jack_nframes_t position() const { return _position; }
sigc::signal<void,Crossfade*> Invalidated;
- sigc::signal<void> GoingAway;
bool covers (jack_nframes_t frame) const {
return _position <= frame && frame < _position + _length;
@@ -155,8 +156,8 @@ class Crossfade : public Stateful, public StateManager
static jack_nframes_t _short_xfade_length;
- ARDOUR::AudioRegion* _in;
- ARDOUR::AudioRegion* _out;
+ boost::shared_ptr<ARDOUR::AudioRegion> _in;
+ boost::shared_ptr<ARDOUR::AudioRegion> _out;
bool _active;
bool _in_update;
OverlapType overlap_type;
@@ -172,7 +173,7 @@ class Crossfade : public Stateful, public StateManager
static Sample* crossfade_buffer_in;
void initialize (bool savestate=true);
- int compute (ARDOUR::AudioRegion&, ARDOUR::AudioRegion&, CrossfadeModel);
+ int compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel);
bool update (bool force);
StateManager::State* state_factory (std::string why) const;
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index bcd418b452..f9463a3320 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -34,7 +34,7 @@
#include <pbd/fastlog.h>
#include <pbd/ringbufferNPT.h>
#include <pbd/stateful.h>
-#include <pbd/destructible.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/configuration.h>
@@ -54,7 +54,7 @@ class Session;
class Playlist;
class IO;
- class Diskstream : public Stateful, public sigc::trackable, public PBD::Destructible
+ class Diskstream : public sigc::trackable, public PBD::StatefulDestructible
{
public:
enum Flag {
@@ -135,7 +135,7 @@ class IO;
int set_loop (Location *loc);
- std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
+ std::list<boost::shared_ptr<Region> >& last_capture_regions () { return _last_capture_regions; }
void handle_input_change (IOChange, void *src);
@@ -225,7 +225,7 @@ class IO;
virtual bool realtime_set_speed (double, bool global_change);
- std::list<Region*> _last_capture_regions;
+ std::list<boost::shared_ptr<Region> > _last_capture_regions;
virtual int use_pending_capture_data (XMLNode& node) = 0;
virtual void get_input_sources () = 0;
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index b116a58b97..1248f60e0f 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -31,7 +31,7 @@
#include <pbd/fastlog.h>
#include <pbd/undo.h>
-#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <pbd/controllable.h>
#include <ardour/ardour.h>
@@ -59,7 +59,7 @@ class Panner;
* An IO can contain ports of varying types, making routes/inserts/etc with
* varied combinations of types (eg MIDI and audio) possible.
*/
-class IO : public Stateful, public ARDOUR::StateManager
+class IO : public PBD::StatefulDestructible, public ARDOUR::StateManager
{
public:
@@ -70,7 +70,7 @@ class IO : public Stateful, public ARDOUR::StateManager
int output_min = -1, int output_max = -1,
DataType default_type = DataType::AUDIO);
- virtual ~IO();
+virtual ~IO();
int input_minimum() const { return _input_minimum; }
int input_maximum() const { return _input_maximum; }
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
index beae4a6e07..1052b74bd4 100644
--- a/libs/ardour/ardour/location.h
+++ b/libs/ardour/ardour/location.h
@@ -33,6 +33,7 @@
#include <pbd/undo.h>
#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/state_manager.h>
@@ -41,7 +42,7 @@ using std::string;
namespace ARDOUR {
-class Location : public Stateful, public sigc::trackable
+class Location : public sigc::trackable, public PBD::StatefulDestructible
{
public:
enum Flags {
@@ -72,6 +73,7 @@ class Location : public Stateful, public sigc::trackable
}
Location (const Location& other);
+ Location (const XMLNode&);
Location* operator= (const Location& other);
jack_nframes_t start() { return _start; }
@@ -132,7 +134,7 @@ class Location : public Stateful, public sigc::trackable
bool set_flag_internal (bool yn, Flags flag);
};
-class Locations : public Stateful, public StateManager
+class Locations : public StateManager, public PBD::StatefulDestructible
{
public:
typedef std::list<Location *> LocationList;
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index b389258860..36c3ae3492 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -25,6 +25,7 @@
#include <set>
#include <map>
#include <list>
+#include <boost/shared_ptr.hpp>
#include <sys/stat.h>
@@ -34,6 +35,7 @@
#include <pbd/undo.h>
#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/crossfade_compare.h>
@@ -45,16 +47,16 @@ namespace ARDOUR {
class Session;
class Region;
-class Playlist : public Stateful, public StateManager {
+class Playlist : public StateManager, public PBD::StatefulDestructible {
public:
- typedef list<Region*> RegionList;
+ typedef list<boost::shared_ptr<Region> > RegionList;
Playlist (Session&, const XMLNode&, bool hidden = false);
Playlist (Session&, string name, bool hidden = false);
Playlist (const Playlist&, string name, bool hidden = false);
Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
- virtual void clear (bool with_delete = false, bool with_save = true);
+ virtual void clear (bool with_save = true);
virtual void dump () const;
virtual UndoAction get_memento() const = 0;
@@ -79,17 +81,17 @@ class Playlist : public Stateful, public StateManager {
PBD::ID id() { return _id; }
/* Editing operations */
- void add_region (const Region&, jack_nframes_t position, float times = 1, bool with_save = true);
- void remove_region (Region *);
- void get_equivalent_regions (const Region&, std::vector<Region*>&);
- void get_region_list_equivalent_regions (const Region&, std::vector<Region*>&);
- void replace_region (Region& old, Region& newr, jack_nframes_t pos);
- void split_region (Region&, jack_nframes_t position);
+ void add_region (boost::shared_ptr<Region>, jack_nframes_t position, float times = 1, bool with_save = true);
+ void remove_region (boost::shared_ptr<Region>);
+ void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
+ void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
+ void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, jack_nframes_t pos);
+ void split_region (boost::shared_ptr<Region>, jack_nframes_t position);
void partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level);
- void duplicate (Region&, jack_nframes_t position, float times);
+ void duplicate (boost::shared_ptr<Region>, jack_nframes_t position, float times);
void nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwards);
- Region* find_region (const PBD::ID&) const;
+ boost::shared_ptr<Region> find_region (const PBD::ID&) const;
Playlist* cut (list<AudioRange>&, bool result_is_hidden = true);
Playlist* copy (list<AudioRange>&, bool result_is_hidden = true);
@@ -99,25 +101,24 @@ class Playlist : public Stateful, public StateManager {
RegionList* regions_at (jack_nframes_t frame);
RegionList* regions_touched (jack_nframes_t start, jack_nframes_t end);
- Region* top_region_at (jack_nframes_t frame);
+ boost::shared_ptr<Region> top_region_at (jack_nframes_t frame);
- Region* find_next_region (jack_nframes_t frame, RegionPoint point, int dir);
+ boost::shared_ptr<Region> find_next_region (jack_nframes_t frame, RegionPoint point, int dir);
- template<class T> void foreach_region (T *t, void (T::*func)(Region *, void *), void *arg);
- template<class T> void foreach_region (T *t, void (T::*func)(Region *));
+ template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg);
+ template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>));
XMLNode& get_state ();
int set_state (const XMLNode&);
XMLNode& get_template ();
- sigc::signal<void,Region *> RegionAdded;
- sigc::signal<void,Region *> RegionRemoved;
+ sigc::signal<void,boost::shared_ptr<Region> > RegionAdded;
+ sigc::signal<void,boost::shared_ptr<Region> > RegionRemoved;
sigc::signal<void,Playlist*,bool> InUse;
sigc::signal<void> Modified;
sigc::signal<void> NameChanged;
sigc::signal<void> LengthChanged;
sigc::signal<void> LayeringChanged;
- sigc::signal<void,Playlist *> GoingAway;
sigc::signal<void> StatePushed;
static sigc::signal<void,Playlist*> PlaylistCreated;
@@ -128,10 +129,10 @@ class Playlist : public Stateful, public StateManager {
void freeze ();
void thaw ();
- void raise_region (Region&);
- void lower_region (Region&);
- void raise_region_to_top (Region&);
- void lower_region_to_bottom (Region&);
+ void raise_region (boost::shared_ptr<Region>);
+ void lower_region (boost::shared_ptr<Region>);
+ void raise_region_to_top (boost::shared_ptr<Region>);
+ void lower_region_to_bottom (boost::shared_ptr<Region>);
uint32_t read_data_count() const { return _read_data_count; }
@@ -142,7 +143,7 @@ class Playlist : public Stateful, public StateManager {
/* destructive editing */
- virtual bool destroy_region (Region *) = 0;
+ virtual bool destroy_region (boost::shared_ptr<Region>) = 0;
protected:
friend class Session;
@@ -212,8 +213,8 @@ class Playlist : public Stateful, public StateManager {
void release_notifications ();
virtual void flush_notifications ();
- void notify_region_removed (Region *);
- void notify_region_added (Region *);
+ void notify_region_removed (boost::shared_ptr<Region>);
+ void notify_region_added (boost::shared_ptr<Region>);
void notify_length_changed ();
void notify_layering_changed ();
void notify_modified ();
@@ -221,11 +222,11 @@ class Playlist : public Stateful, public StateManager {
void mark_session_dirty();
- void region_changed_proxy (Change, Region*);
- virtual bool region_changed (Change, Region*);
+ void region_changed_proxy (Change, boost::shared_ptr<Region>);
+ virtual bool region_changed (Change, boost::shared_ptr<Region>);
- void region_bounds_changed (Change, Region *);
- void region_deleted (Region *);
+ void region_bounds_changed (Change, boost::shared_ptr<Region>);
+ void region_deleted (boost::shared_ptr<Region>);
void sort_regions ();
@@ -236,11 +237,11 @@ class Playlist : public Stateful, public StateManager {
void splice_unlocked ();
- virtual void finalize_split_region (Region *original, Region *left, Region *right) {}
+ virtual void finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right) {}
- virtual void check_dependents (Region& region, bool norefresh) {}
- virtual void refresh_dependents (Region& region) {}
- virtual void remove_dependents (Region& region) {}
+ virtual void check_dependents (boost::shared_ptr<Region> region, bool norefresh) {}
+ virtual void refresh_dependents (boost::shared_ptr<Region> region) {}
+ virtual void remove_dependents (boost::shared_ptr<Region> region) {}
virtual XMLNode& state (bool);
@@ -249,9 +250,9 @@ class Playlist : public Stateful, public StateManager {
void save_state (std::string why);
void maybe_save_state (std::string why);
- void add_region_internal (Region *, jack_nframes_t position, bool delay_sort = false);
+ void add_region_internal (boost::shared_ptr<Region>, jack_nframes_t position, bool delay_sort = false);
- int remove_region_internal (Region *, bool delay_sort = false);
+ int remove_region_internal (boost::shared_ptr<Region>, bool delay_sort = false);
RegionList *find_regions_at (jack_nframes_t frame);
void copy_regions (RegionList&) const;
void partition_internal (jack_nframes_t start, jack_nframes_t end, bool cutting, RegionList& thawlist);
@@ -264,7 +265,7 @@ class Playlist : public Stateful, public StateManager {
Playlist *copy (jack_nframes_t start, jack_nframes_t cnt, bool result_is_hidden);
- int move_region_to_layer (layer_t, Region& r, int dir);
+ int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir);
void relayer ();
static Playlist* copyPlaylist (const Playlist&, jack_nframes_t start, jack_nframes_t length,
@@ -273,7 +274,7 @@ class Playlist : public Stateful, public StateManager {
void unset_freeze_parent (Playlist*);
void unset_freeze_child (Playlist*);
- void timestamp_layer_op (Region&);
+ void timestamp_layer_op (boost::shared_ptr<Region>);
PBD::ID _id;
};
diff --git a/libs/ardour/ardour/playlist_templates.h b/libs/ardour/ardour/playlist_templates.h
index d3d682b8c5..7ce6c1818c 100644
--- a/libs/ardour/ardour/playlist_templates.h
+++ b/libs/ardour/ardour/playlist_templates.h
@@ -30,14 +30,14 @@ template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(C
}
}
-template<class T> void Playlist::foreach_region (T *t, void (T::*func)(Region *, void *), void *arg) {
+template<class T> void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg) {
RegionLock rlock (this, false);
for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) {
(t->*func) ((*i), arg);
}
}
-template<class T> void Playlist::foreach_region (T *t, void (T::*func)(Region *)) {
+template<class T> void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>)) {
RegionLock rlock (this, false);
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); i++) {
(t->*func) (*i);
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index e5a81f1ef9..4800bc35fc 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -24,7 +24,7 @@
#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
-#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <pbd/controllable.h>
#include <jack/types.h>
@@ -77,8 +77,7 @@ class PluginInfo {
typedef boost::shared_ptr<PluginInfo> PluginInfoPtr;
typedef std::list<PluginInfoPtr> PluginInfoList;
-class Plugin : public Stateful, public sigc::trackable
-
+class Plugin : public PBD::StatefulDestructible, public sigc::trackable
{
public:
Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&);
@@ -140,7 +139,6 @@ class Plugin : public Stateful, public sigc::trackable
virtual bool has_editor() const = 0;
sigc::signal<void,uint32_t,float> ParameterChanged;
- sigc::signal<void,Plugin *> GoingAway;
PBD::Controllable *get_nth_control (uint32_t);
diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h
index 658cab5d3b..5f63fad8c8 100644
--- a/libs/ardour/ardour/redirect.h
+++ b/libs/ardour/ardour/redirect.h
@@ -92,7 +92,6 @@ class Redirect : public IO
sigc::signal<void,Redirect*,void*> placement_changed;
sigc::signal<void,Redirect*,bool> AutomationPlaybackChanged;
sigc::signal<void,Redirect*,uint32_t> AutomationChanged;
- sigc::signal<void,Redirect*> GoingAway;
static sigc::signal<void,Redirect*> RedirectCreated;
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 3773a3b893..958b4d419c 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -21,7 +21,10 @@
#ifndef __ardour_region_h__
#define __ardour_region_h__
+#include <boost/shared_ptr.hpp>
+
#include <pbd/undo.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/state_manager.h>
@@ -53,7 +56,7 @@ struct RegionState : public StateManager::State
mutable RegionEditState _first_edit;
};
-class Region : public Stateful, public StateManager
+class Region : public PBD::StatefulDestructible, public StateManager
{
public:
enum Flag {
@@ -89,11 +92,6 @@ class Region : public Stateful, public StateManager
static Change LayerChanged;
static Change HiddenChanged;
- Region (jack_nframes_t start, jack_nframes_t length,
- const string& name, layer_t = 0, Flag flags = DefaultFlags);
- Region (const Region&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
- Region (const Region&);
- Region (const XMLNode&);
virtual ~Region();
const PBD::ID& id() const { return _id; }
@@ -139,11 +137,11 @@ class Region : public Stateful, public StateManager
return ARDOUR::coverage (_position, _position + _length - 1, start, end);
}
- bool equivalent (const Region&) const;
- bool size_equivalent (const Region&) const;
- bool overlap_equivalent (const Region&) const;
- bool region_list_equivalent (const Region&) const;
- virtual bool source_equivalent (const Region&) const = 0;
+ bool equivalent (boost::shared_ptr<const Region>) const;
+ bool size_equivalent (boost::shared_ptr<const Region>) const;
+ bool overlap_equivalent (boost::shared_ptr<const Region>) const;
+ bool region_list_equivalent (boost::shared_ptr<const Region>) const;
+ virtual bool source_equivalent (boost::shared_ptr<const Region>) const = 0;
virtual bool speed_mismatch (float) const = 0;
@@ -193,24 +191,22 @@ class Region : public Stateful, public StateManager
virtual XMLNode& state (bool);
virtual int set_state (const XMLNode&);
- sigc::signal<void,Region*> GoingAway;
-
- /* This is emitted only when a new id is assigned. Therefore,
- in a pure Region copy, it will not be emitted.
-
- It must be emitted by derived classes, not Region
- itself, to permit dynamic_cast<> to be used to
- infer the type of Region.
- */
-
- static sigc::signal<void,Region*> CheckNewRegion;
-
- virtual Region* get_parent() = 0;
+ virtual boost::shared_ptr<Region> get_parent() = 0;
uint64_t last_layer_op() const { return _last_layer_op; }
void set_last_layer_op (uint64_t when);
protected:
+ friend class RegionFactory;
+
+ Region (jack_nframes_t start, jack_nframes_t length,
+ const string& name, layer_t = 0, Flag flags = DefaultFlags);
+ Region (boost::shared_ptr<const Region>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
+ Region (boost::shared_ptr<const Region>);
+ Region (const XMLNode&);
+
+
+ protected:
XMLNode& get_short_state (); /* used only by Session */
/* state management */
diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h
index f72c0a52d8..d4033680ee 100644
--- a/libs/ardour/ardour/region_factory.h
+++ b/libs/ardour/ardour/region_factory.h
@@ -10,12 +10,28 @@ namespace ARDOUR {
class Session;
-Region* createRegion (const Region&, jack_nframes_t start,
- jack_nframes_t length, std::string name,
- layer_t = 0, Region::Flag flags = Region::DefaultFlags);
-// Region* createRegion (const Region&, std::string name);
-Region* createRegion (const Region&);
-Region* createRegion (Session&, XMLNode&, bool);
+class RegionFactory {
+
+ public:
+ /* This is emitted only when a new id is assigned. Therefore,
+ in a pure Region copy, it will not be emitted.
+
+ It must be emitted by derived classes, not Region
+ itself, to permit dynamic_cast<> to be used to
+ infer the type of Region.
+ */
+
+ static sigc::signal<void,boost::shared_ptr<Region> > CheckNewRegion;
+
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, jack_nframes_t start,
+ jack_nframes_t length, std::string name,
+ layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (Source&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Region>);
+ static boost::shared_ptr<Region> create (Session&, XMLNode&, bool);
+ static boost::shared_ptr<Region> create (SourceList &, const XMLNode&);
+};
}
diff --git a/libs/ardour/ardour/reverse.h b/libs/ardour/ardour/reverse.h
index 05ea8a1353..c60df990f2 100644
--- a/libs/ardour/ardour/reverse.h
+++ b/libs/ardour/ardour/reverse.h
@@ -30,7 +30,7 @@ class Reverse : public AudioFilter {
Reverse (ARDOUR::Session&);
~Reverse ();
- int run (ARDOUR::AudioRegion&);
+ int run (boost::shared_ptr<ARDOUR::AudioRegion>);
};
} /* namespace */
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index ff7aa6184c..2191439744 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -56,7 +56,7 @@ enum mute_type {
MAIN_OUTS = 0x8
};
- class Route : public IO, public PBD::Destructible
+class Route : public IO
{
protected:
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 78f6011369..2a29b0e56e 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -37,11 +37,13 @@
#include <pbd/undo.h>
#include <pbd/pool.h>
#include <pbd/rcu.h>
+#include <pbd/statefuldestructible.h>
#include <midi++/types.h>
#include <midi++/mmc.h>
#include <pbd/stateful.h>
+#include <pbd/destructible.h>
#include <ardour/ardour.h>
#include <ardour/configuration.h>
@@ -94,11 +96,10 @@ struct RouteGroup;
using std::vector;
using std::string;
-using std::list;
using std::map;
using std::set;
-class Session : public sigc::trackable, public Stateful
+class Session : public sigc::trackable, public StatefulDestructible
{
private:
@@ -324,11 +325,9 @@ class Session : public sigc::trackable, public Stateful
void disable_record (bool rt_context, bool force = false);
void step_back_from_record ();
- sigc::signal<void> going_away;
-
/* Proxy signal for region hidden changes */
- sigc::signal<void,Region*> RegionHiddenChange;
+ sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange;
/* Emitted when all i/o connections are complete */
@@ -366,7 +365,7 @@ class Session : public sigc::trackable, public Stateful
int wipe ();
- int remove_region_from_region_list (Region&);
+ int remove_region_from_region_list (boost::shared_ptr<Region>);
jack_nframes_t get_maximum_extent () const;
jack_nframes_t current_end_frame() const { return end_location->start(); }
@@ -615,19 +614,19 @@ class Session : public sigc::trackable, public Stateful
/* region info */
- sigc::signal<void,AudioRegion *> AudioRegionAdded;
- sigc::signal<void,AudioRegion *> AudioRegionRemoved;
+ sigc::signal<void,boost::shared_ptr<AudioRegion> > AudioRegionAdded;
+ sigc::signal<void,boost::shared_ptr<AudioRegion> > AudioRegionRemoved;
int region_name (string& result, string base = string(""), bool newlevel = false) const;
string new_region_name (string);
string path_from_region_name (string name, string identifier);
- AudioRegion* find_whole_file_parent (AudioRegion&);
- void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result);
+ boost::shared_ptr<AudioRegion> find_whole_file_parent (boost::shared_ptr<AudioRegion>);
+ void find_equivalent_playlist_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >& result);
- AudioRegion *XMLRegionFactory (const XMLNode&, bool full);
+ boost::shared_ptr<AudioRegion> XMLRegionFactory (const XMLNode&, bool full);
- template<class T> void foreach_audio_region (T *obj, void (T::*func)(AudioRegion *));
+ template<class T> void foreach_audio_region (T *obj, void (T::*func)(boost::shared_ptr<AudioRegion>));
/* source management */
@@ -641,7 +640,7 @@ class Session : public sigc::trackable, public Stateful
string pathname;
/* result */
- std::vector<AudioRegion*> new_regions;
+ std::vector<boost::shared_ptr<AudioRegion> > new_regions;
};
@@ -667,8 +666,8 @@ class Session : public sigc::trackable, public Stateful
int cleanup_sources (cleanup_report&);
int cleanup_trash_sources (cleanup_report&);
- int destroy_region (Region*);
- int destroy_regions (list<Region*>);
+ int destroy_region (boost::shared_ptr<Region>);
+ int destroy_regions (std::list<boost::shared_ptr<Region> >);
int remove_last_capture ();
@@ -728,7 +727,7 @@ class Session : public sigc::trackable, public Stateful
boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; }
void audition_playlist ();
- void audition_region (Region&);
+ void audition_region (boost::shared_ptr<Region>);
void cancel_audition ();
bool is_auditioning () const;
@@ -840,12 +839,15 @@ class Session : public sigc::trackable, public Stateful
void commit_reversible_command (Command* cmd = 0);
void add_command (Command *const cmd) {
- current_trans.add_command (cmd);
+ current_trans->add_command (cmd);
}
+ std::map<PBD::ID, PBD::StatefulDestructible*> registry;
+
// these commands are implemented in libs/ardour/session_command.cc
Command *memento_command_factory(XMLNode *n);
- void register_with_memento_command_factory(PBD::ID, Stateful *);
+ void register_with_memento_command_factory(PBD::ID, PBD::StatefulDestructible *);
+
class GlobalSoloStateCommand : public Command
{
GlobalRouteBooleanState before, after;
@@ -915,17 +917,17 @@ class Session : public sigc::trackable, public Stateful
/* tempo FX */
struct TimeStretchRequest {
- ARDOUR::AudioRegion* region;
+ boost::shared_ptr<ARDOUR::AudioRegion> region;
float fraction; /* session: read ; GUI: write */
float progress; /* session: write ; GUI: read */
bool running; /* read/write */
bool quick_seek; /* GUI: write */
bool antialias; /* GUI: write */
- TimeStretchRequest () : region (0) {}
+ TimeStretchRequest () {}
};
- AudioRegion* tempoize_region (TimeStretchRequest&);
+ boost::shared_ptr<AudioRegion> tempoize_region (TimeStretchRequest&);
string raid_path() const;
void set_raid_path(string);
@@ -1540,13 +1542,13 @@ class Session : public sigc::trackable, public Stateful
/* REGION MANAGEMENT */
mutable Glib::Mutex region_lock;
- typedef map<PBD::ID,AudioRegion *> AudioRegionList;
+ typedef map<PBD::ID,boost::shared_ptr<AudioRegion> > AudioRegionList;
AudioRegionList audio_regions;
- void region_renamed (Region *);
- void region_changed (Change, Region *);
- void add_region (Region *);
- void remove_region (Region *);
+ void region_renamed (boost::shared_ptr<Region>);
+ void region_changed (Change, boost::shared_ptr<Region>);
+ void add_region (boost::shared_ptr<Region>);
+ void remove_region (boost::shared_ptr<Region>);
int load_regions (const XMLNode& node);
@@ -1603,9 +1605,9 @@ class Session : public sigc::trackable, public Stateful
/* AUDITIONING */
boost::shared_ptr<Auditioner> auditioner;
- void set_audition (AudioRegion*);
+ void set_audition (boost::shared_ptr<AudioRegion>);
void non_realtime_set_audition ();
- AudioRegion *pending_audition_region;
+ boost::shared_ptr<AudioRegion> pending_audition_region;
/* EXPORT */
@@ -1674,7 +1676,7 @@ class Session : public sigc::trackable, public Stateful
void reverse_diskstream_buffers ();
UndoHistory history;
- UndoTransaction current_trans;
+ UndoTransaction* current_trans;
GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
GlobalRouteMeterState get_global_route_metering ();
diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h
index 4f0fb92e3b..9217d4cb41 100644
--- a/libs/ardour/ardour/session_region.h
+++ b/libs/ardour/ardour/session_region.h
@@ -6,7 +6,7 @@
namespace ARDOUR {
-template<class T> void Session::foreach_audio_region (T *obj, void (T::*func)(AudioRegion *))
+template<class T> void Session::foreach_audio_region (T *obj, void (T::*func)(boost::shared_ptr<AudioRegion>))
{
Glib::Mutex::Lock lm (region_lock);
for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); i++) {
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index f57ea79854..dee75a2300 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -25,13 +25,13 @@
#include <sigc++/signal.h>
-#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
namespace ARDOUR {
-class Source : public Stateful, public sigc::trackable
+class Source : public PBD::StatefulDestructible, public sigc::trackable
{
public:
Source (std::string name);
@@ -53,7 +53,6 @@ class Source : public Stateful, public sigc::trackable
XMLNode& get_state ();
int set_state (const XMLNode&);
- sigc::signal<void,Source *> GoingAway;
protected:
string _name;
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index bfd3e429c3..a365717417 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -26,8 +26,11 @@
#include <vector>
#include <cmath>
#include <glibmm/thread.h>
+
#include <pbd/undo.h>
#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
+
#include <sigc++/signal.h>
#include <ardour/ardour.h>
@@ -169,7 +172,8 @@ class TempoMapState : public StateManager::State {
Metrics *metrics;
};
-class TempoMap : public Stateful, public StateManager {
+class TempoMap : public StateManager, public PBD::StatefulDestructible
+{
public:
TempoMap (jack_nframes_t frame_rate);
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 0a3a7b731c..9c92b49ed0 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -26,6 +26,7 @@
#endif
#include <istream>
+#include <vector>
#include <inttypes.h>
#include <jack/types.h>
@@ -42,6 +43,7 @@ typedef int intptr_t;
namespace ARDOUR {
class Source;
+ class AudioSource;
typedef jack_default_audio_sample_t Sample;
typedef float pan_t;
@@ -250,6 +252,8 @@ namespace ARDOUR {
VST
};
+ typedef std::vector<AudioSource *> SourceList;
+
} // namespace ARDOUR
std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index baefeff377..24363e3594 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -44,6 +44,7 @@
#include <ardour/audiofilesource.h>
#include <ardour/destructive_filesource.h>
#include <ardour/send.h>
+#include <ardour/region_factory.h>
#include <ardour/audioplaylist.h>
#include <ardour/cycle_timer.h>
#include <ardour/audioregion.h>
@@ -188,8 +189,8 @@ AudioDiskstream::allocate_working_buffers()
void
AudioDiskstream::free_working_buffers()
{
- delete _mixdown_buffer;
- delete _gain_buffer;
+ delete [] _mixdown_buffer;
+ delete [] _gain_buffer;
_working_buffers_size = 0;
_mixdown_buffer = 0;
_gain_buffer = 0;
@@ -367,7 +368,7 @@ AudioDiskstream::use_copy_playlist ()
void
AudioDiskstream::setup_destructive_playlist ()
{
- AudioRegion::SourceList srcs;
+ SourceList srcs;
for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
srcs.push_back ((*chan).write_source);
@@ -377,8 +378,8 @@ AudioDiskstream::setup_destructive_playlist ()
cerr << "setup DS using " << srcs.front()->natural_position () << endl;
- AudioRegion* region = new AudioRegion (srcs, 0, max_frames, _name);
- _playlist->add_region (*region, srcs.front()->natural_position());
+ boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, max_frames, _name));
+ _playlist->add_region (region, srcs.front()->natural_position());
}
void
@@ -393,7 +394,7 @@ AudioDiskstream::use_destructive_playlist ()
return;
}
- AudioRegion* region = dynamic_cast<AudioRegion*> (rl->front());
+ boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (rl->front());
if (region == 0) {
throw failed_constructor();
@@ -1449,10 +1450,10 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
uint32_t buffer_position;
bool more_work = true;
int err = 0;
- AudioRegion* region = 0;
+ boost::shared_ptr<AudioRegion> region;
jack_nframes_t total_capture;
- AudioRegion::SourceList srcs;
- AudioRegion::SourceList::iterator src;
+ SourceList srcs;
+ SourceList::iterator src;
ChannelList::iterator chan;
vector<CaptureInfo*>::iterator ci;
uint32_t n = 0;
@@ -1561,10 +1562,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
*/
try {
- region = new AudioRegion (srcs, channels[0].write_source->last_capture_start_frame(), total_capture,
- region_name_from_path (channels[0].write_source->name()),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
-
+ boost::shared_ptr<Region> rx (RegionFactory::create (srcs, channels[0].write_source->last_capture_start_frame(), total_capture,
+ region_name_from_path (channels[0].write_source->name()),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
+
+ region = boost::dynamic_pointer_cast<AudioRegion> (rx);
region->special_set_position (capture_info.front()->start);
}
@@ -1586,10 +1588,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
string region_name;
_session.region_name (region_name, channels[0].write_source->name(), false);
- // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
+ cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl;
try {
- region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
+ boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name));
+ region = boost::dynamic_pointer_cast<AudioRegion> (rx);
}
catch (failed_constructor& err) {
@@ -1602,7 +1605,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
// cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
i_am_the_modifier++;
- _playlist->add_region (*region, (*ci)->start);
+ _playlist->add_region (region, (*ci)->start);
i_am_the_modifier--;
buffer_position += (*ci)->frames;
@@ -2165,7 +2168,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
XMLNodeIterator niter;
AudioFileSource* fs;
AudioFileSource* first_fs = 0;
- AudioRegion::SourceList pending_sources;
+ SourceList pending_sources;
jack_nframes_t position;
if ((prop = node.property (X_("at"))) == 0) {
@@ -2218,13 +2221,12 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
return -1;
}
- AudioRegion* region;
+ boost::shared_ptr<AudioRegion> region;
try {
- region = new AudioRegion (pending_sources, 0, first_fs->length(),
- region_name_from_path (first_fs->name()),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
-
+ region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(),
+ region_name_from_path (first_fs->name()),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
region->special_set_position (0);
}
@@ -2237,7 +2239,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
}
try {
- region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
+ region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name())));
}
catch (failed_constructor& err) {
@@ -2248,7 +2250,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
return -1;
}
- _playlist->add_region (*region, position);
+ _playlist->add_region (region, position);
return 0;
}
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 328c9b25f5..1136476358 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -73,28 +73,28 @@ AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidd
{
save_state (_("initial state"));
- list<Region*>::const_iterator in_o = other.regions.begin();
- list<Region*>::iterator in_n = regions.begin();
+ RegionList::const_iterator in_o = other.regions.begin();
+ RegionList::iterator in_n = regions.begin();
while (in_o != other.regions.end()) {
- AudioRegion *ar = dynamic_cast<AudioRegion *>( (*in_o) );
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o);
// We look only for crossfades which begin with the current region, so we don't get doubles
for (list<Crossfade *>::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) {
- if ( &(*xfades)->in() == ar) {
+ if ((*xfades)->in() == ar) {
// We found one! Now copy it!
- list<Region*>::const_iterator out_o = other.regions.begin();
- list<Region*>::const_iterator out_n = regions.begin();
+ RegionList::const_iterator out_o = other.regions.begin();
+ RegionList::const_iterator out_n = regions.begin();
while (out_o != other.regions.end()) {
- AudioRegion *ar2 = dynamic_cast<AudioRegion *>( (*out_o) );
+ boost::shared_ptr<AudioRegion>ar2 = boost::dynamic_pointer_cast<AudioRegion>(*out_o);
- if ( &(*xfades)->out() == ar2) {
- AudioRegion *in = dynamic_cast<AudioRegion*>( (*in_n) );
- AudioRegion *out = dynamic_cast<AudioRegion*>( (*out_n) );
- Crossfade *new_fade = new Crossfade( *(*xfades), in, out);
+ if ((*xfades)->out() == ar2) {
+ boost::shared_ptr<AudioRegion>in = boost::dynamic_pointer_cast<AudioRegion>(*in_n);
+ boost::shared_ptr<AudioRegion>out = boost::dynamic_pointer_cast<AudioRegion>(*out_n);
+ Crossfade *new_fade = new Crossfade (*(*xfades), in, out);
add_crossfade(*new_fade);
break;
}
@@ -128,15 +128,11 @@ AudioPlaylist::~AudioPlaylist ()
set<Crossfade*> all_xfades;
set<Region*> all_regions;
- GoingAway (this);
+ GoingAway (); /* EMIT SIGNAL */
- /* find every region we've ever used, and add it to the set of
- all regions. same for xfades;
- */
+ /* drop connections to signals */
- for (RegionList::iterator x = regions.begin(); x != regions.end(); ++x) {
- all_regions.insert (*x);
- }
+ notify_callbacks ();
for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
all_xfades.insert (*x);
@@ -146,23 +142,13 @@ AudioPlaylist::~AudioPlaylist ()
AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
- for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
- all_regions.insert (*r);
- }
- for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
+ for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
all_xfades.insert (*xf);
}
delete apstate;
}
- /* delete every region */
-
- for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
- (*ar)->unlock_sources ();
- delete *ar;
- }
-
/* delete every crossfade */
for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
@@ -171,7 +157,7 @@ AudioPlaylist::~AudioPlaylist ()
}
struct RegionSortByLayer {
- bool operator() (Region *a, Region *b) {
+ bool operator() (boost::shared_ptr<Region>a, boost::shared_ptr<Region>b) {
return a->layer() < b->layer();
}
};
@@ -212,7 +198,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
skip_frames = 0;
_read_data_count = 0;
- map<uint32_t,vector<Region*> > relevant_regions;
+ map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions;
map<uint32_t,vector<Crossfade*> > relevant_xfades;
vector<uint32_t> relevant_layers;
@@ -243,12 +229,11 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
- // FIXME: Should be vector<AudioRegion*>
- vector<Region*>& r (relevant_regions[*l]);
+ vector<boost::shared_ptr<Region> > r (relevant_regions[*l]);
vector<Crossfade*>& x (relevant_xfades[*l]);
- for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
- AudioRegion* const ar = dynamic_cast<AudioRegion*>(*i);
+ for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i);
assert(ar);
ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames);
_read_data_count += ar->read_data_count();
@@ -268,10 +253,10 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
void
-AudioPlaylist::remove_dependents (Region& region)
+AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region)
{
Crossfades::iterator i, tmp;
- AudioRegion* r = dynamic_cast<AudioRegion*> (&region);
+ boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
if (r == 0) {
fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
@@ -283,7 +268,7 @@ AudioPlaylist::remove_dependents (Region& region)
tmp = i;
tmp++;
- if ((*i)->involves (*r)) {
+ if ((*i)->involves (r)) {
/* do not delete crossfades */
_crossfades.erase (i);
}
@@ -315,9 +300,9 @@ AudioPlaylist::flush_notifications ()
}
void
-AudioPlaylist::refresh_dependents (Region& r)
+AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
{
- AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
set<Crossfade*> updated;
if (ar == 0) {
@@ -333,7 +318,7 @@ AudioPlaylist::refresh_dependents (Region& r)
/* only update them once */
- if ((*x)->involves (*ar)) {
+ if ((*x)->involves (ar)) {
if (find (updated.begin(), updated.end(), *x) == updated.end()) {
if ((*x)->refresh ()) {
@@ -348,11 +333,11 @@ AudioPlaylist::refresh_dependents (Region& r)
}
void
-AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
+AudioPlaylist::finalize_split_region (boost::shared_ptr<Region> o, boost::shared_ptr<Region> l, boost::shared_ptr<Region> r)
{
- AudioRegion *orig = dynamic_cast<AudioRegion*>(o);
- AudioRegion *left = dynamic_cast<AudioRegion*>(l);
- AudioRegion *right = dynamic_cast<AudioRegion*>(r);
+ boost::shared_ptr<AudioRegion> orig = boost::dynamic_pointer_cast<AudioRegion>(o);
+ boost::shared_ptr<AudioRegion> left = boost::dynamic_pointer_cast<AudioRegion>(l);
+ boost::shared_ptr<AudioRegion> right = boost::dynamic_pointer_cast<AudioRegion>(r);
for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
Crossfades::iterator tmp;
@@ -363,24 +348,24 @@ AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
if ((*x)->_in == orig) {
if (! (*x)->covers(right->position())) {
- fade = new Crossfade( *(*x), left, (*x)->_out);
+ fade = new Crossfade (**x, left, (*x)->_out);
} else {
// Overlap, the crossfade is copied on the left side of the right region instead
- fade = new Crossfade( *(*x), right, (*x)->_out);
+ fade = new Crossfade (**x, right, (*x)->_out);
}
}
if ((*x)->_out == orig) {
if (! (*x)->covers(right->position())) {
- fade = new Crossfade( *(*x), (*x)->_in, right);
+ fade = new Crossfade (**x, (*x)->_in, right);
} else {
// Overlap, the crossfade is copied on the right side of the left region instead
- fade = new Crossfade( *(*x), (*x)->_in, left);
+ fade = new Crossfade (**x, (*x)->_in, left);
}
}
if (fade) {
- _crossfades.remove( (*x) );
+ _crossfades.remove (*x);
add_crossfade (*fade);
}
x = tmp;
@@ -388,19 +373,19 @@ AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
}
void
-AudioPlaylist::check_dependents (Region& r, bool norefresh)
+AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
{
- AudioRegion* other;
- AudioRegion* region;
- AudioRegion* top;
- AudioRegion* bottom;
+ boost::shared_ptr<AudioRegion> other;
+ boost::shared_ptr<AudioRegion> region;
+ boost::shared_ptr<AudioRegion> top;
+ boost::shared_ptr<AudioRegion> bottom;
Crossfade* xfade;
if (in_set_state || in_partition) {
return;
}
- if ((region = dynamic_cast<AudioRegion*> (&r)) == 0) {
+ if ((region = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
<< endmsg;
return;
@@ -416,7 +401,7 @@ AudioPlaylist::check_dependents (Region& r, bool norefresh)
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
- other = dynamic_cast<AudioRegion*> (*i);
+ other = boost::dynamic_pointer_cast<AudioRegion> (*i);
if (other == region) {
continue;
@@ -458,14 +443,14 @@ AudioPlaylist::check_dependents (Region& r, bool norefresh)
jack_nframes_t xfade_length = min ((jack_nframes_t) 720, top->length());
/* in, out */
- xfade = new Crossfade (*top, *bottom, xfade_length, top->first_frame(), StartOfIn);
+ xfade = new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn);
add_crossfade (*xfade);
- xfade = new Crossfade (*bottom, *top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
+ xfade = new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
add_crossfade (*xfade);
} else {
- xfade = new Crossfade (*other, *region, _session.get_xfade_model(), _session.get_crossfades_active());
+ xfade = new Crossfade (other, region, _session.get_xfade_model(), _session.get_crossfades_active());
add_crossfade (*xfade);
}
}
@@ -519,8 +504,8 @@ AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
{
Crossfades::iterator i;
- xfade->in().resume_fade_in ();
- xfade->out().resume_fade_out ();
+ xfade->in()->resume_fade_in ();
+ xfade->out()->resume_fade_out ();
if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
_crossfades.erase (i);
@@ -586,7 +571,7 @@ void
AudioPlaylist::drop_all_states ()
{
set<Crossfade*> all_xfades;
- set<Region*> all_regions;
+ set<boost::shared_ptr<Region> > all_regions;
/* find every region we've ever used, and add it to the set of
all regions. same for xfades;
@@ -599,6 +584,7 @@ AudioPlaylist::drop_all_states ()
for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
all_regions.insert (*r);
}
+
for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
all_xfades.insert (*xf);
}
@@ -606,8 +592,8 @@ AudioPlaylist::drop_all_states ()
/* now remove from the "all" lists every region that is in the current list. */
- for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
- set<Region*>::iterator x = all_regions.find (*i);
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ set<boost::shared_ptr<Region> >::iterator x = all_regions.find (*i);
if (x != all_regions.end()) {
all_regions.erase (x);
}
@@ -624,9 +610,8 @@ AudioPlaylist::drop_all_states ()
/* delete every region that is left - these are all things that are part of our "history" */
- for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
+ for (set<boost::shared_ptr<Region> >::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
(*ar)->unlock_sources ();
- delete *ar;
}
/* delete every crossfade that is left (ditto as per regions) */
@@ -694,17 +679,11 @@ AudioPlaylist::get_memento () const
}
void
-AudioPlaylist::clear (bool with_delete, bool with_save)
+AudioPlaylist::clear (bool with_save)
{
- if (with_delete) {
- for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
- delete *i;
- }
- }
-
_crossfades.clear ();
- Playlist::clear (with_delete, with_save);
+ Playlist::clear (with_save);
}
XMLNode&
@@ -724,7 +703,7 @@ AudioPlaylist::state (bool full_state)
void
AudioPlaylist::dump () const
{
- Region *r;
+ boost::shared_ptr<Region>r;
Crossfade *x;
cerr << "Playlist \"" << _name << "\" " << endl
@@ -746,9 +725,9 @@ AudioPlaylist::dump () const
for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
x = *i;
cerr << " xfade ["
- << x->out().name()
+ << x->out()->name()
<< ','
- << x->in().name()
+ << x->in()->name()
<< " @ "
<< x->position()
<< " length = "
@@ -760,9 +739,9 @@ AudioPlaylist::dump () const
}
bool
-AudioPlaylist::destroy_region (Region* region)
+AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
{
- AudioRegion* r = dynamic_cast<AudioRegion*> (region);
+ boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
bool changed = false;
Crossfades::iterator c, ctmp;
set<Crossfade*> unique_xfades;
@@ -798,7 +777,7 @@ AudioPlaylist::destroy_region (Region* region)
ctmp = c;
++ctmp;
- if ((*c)->involves (*r)) {
+ if ((*c)->involves (r)) {
unique_xfades.insert (*c);
_crossfades.erase (c);
}
@@ -819,7 +798,7 @@ AudioPlaylist::destroy_region (Region* region)
ctmp = c;
++ctmp;
- if ((*c)->involves (*r)) {
+ if ((*c)->involves (r)) {
unique_xfades.insert (*c);
_crossfades.erase (c);
}
@@ -883,7 +862,7 @@ AudioPlaylist::crossfade_changed (Change ignored)
}
bool
-AudioPlaylist::region_changed (Change what_changed, Region* region)
+AudioPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{
if (in_flush || in_set_state) {
return false;
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 98a2262f86..60400a046c 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -28,6 +28,7 @@
#include <ardour/redirect.h>
#include <ardour/audioregion.h>
#include <ardour/audiosource.h>
+#include <ardour/region_factory.h>
#include <ardour/route_group_specialized.h>
#include <ardour/insert.h>
#include <ardour/audioplaylist.h>
@@ -746,7 +747,6 @@ AudioTrack::freeze (InterThreadInfo& itt)
string new_playlist_name;
Playlist* new_playlist;
string dir;
- AudioRegion* region;
string region_name;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
@@ -813,13 +813,13 @@ AudioTrack::freeze (InterThreadInfo& itt)
/* create a new region from all filesources, keep it private */
- region = new AudioRegion (srcs, 0, srcs[0]->length(),
- region_name, 0,
- (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
- false);
+ boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(),
+ region_name, 0,
+ (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
+ false));
new_playlist->set_orig_diskstream_id (diskstream->id());
- new_playlist->add_region (*region, 0);
+ new_playlist->add_region (region, 0);
new_playlist->set_frozen (true);
region->set_locked (true);
diff --git a/libs/ardour/audiofilter.cc b/libs/ardour/audiofilter.cc
index a26d9674bd..3e9c36ddd2 100644
--- a/libs/ardour/audiofilter.cc
+++ b/libs/ardour/audiofilter.cc
@@ -26,6 +26,7 @@
#include <ardour/session.h>
#include <ardour/audioregion.h>
#include <ardour/audiofilter.h>
+#include <ardour/region_factory.h>
#include "i18n.h"
@@ -33,16 +34,16 @@ using namespace ARDOUR;
using namespace PBD;
int
-AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsrcs)
+AudioFilter::make_new_sources (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs)
{
- vector<string> names = region.master_source_names();
+ vector<string> names = region->master_source_names();
- for (uint32_t i = 0; i < region.n_channels(); ++i) {
+ for (uint32_t i = 0; i < region->n_channels(); ++i) {
string path = session.path_from_region_name (PBD::basename_nosuffix (names[i]), string (""));
if (path.length() == 0) {
- error << string_compose (_("audiofilter: error creating name for new audio file based on %1"), region.name())
+ error << string_compose (_("audiofilter: error creating name for new audio file based on %1"), region->name())
<< endmsg;
return -1;
}
@@ -64,7 +65,7 @@ AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsr
}
int
-AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs)
+AudioFilter::finish (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs)
{
string region_name;
@@ -76,19 +77,19 @@ AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs)
time (&xnow);
now = localtime (&xnow);
- for (AudioRegion::SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
+ for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*si);
if (afs) {
- afs->update_header (region.position(), *now, xnow);
+ afs->update_header (region->position(), *now, xnow);
}
}
/* create a new region */
- region_name = session.new_region_name (region.name());
+ region_name = session.new_region_name (region->name());
results.clear ();
- results.push_back (new AudioRegion (nsrcs, 0, region.length(), region_name, 0,
- Region::Flag (Region::WholeFile|Region::DefaultFlags)));
-
+ results.push_back (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (nsrcs, 0, region->length(), region_name, 0,
+ Region::Flag (Region::WholeFile|Region::DefaultFlags))));
+
return 0;
}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 4b07599924..5cedb246ba 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -64,7 +64,7 @@ AudioRegionState::AudioRegionState (string why)
{
}
-AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, bool announce)
+AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length)
: Region (start, length, PBD::basename_nosuffix(src.name()), 0, Region::Flag(Region::DefaultFlags|Region::External)),
_fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false),
@@ -74,7 +74,7 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
sources.push_back (&src);
master_sources.push_back (&src);
- src.GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ src.GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), &src));
_scale_amplitude = 1.0;
@@ -84,13 +84,9 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
}
-AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (start, length, name, layer, flags),
_fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false),
@@ -100,7 +96,7 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
sources.push_back (&src);
master_sources.push_back (&src);
- src.GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ src.GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), &src));
_scale_amplitude = 1.0;
@@ -109,13 +105,9 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
}
-AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (start, length, name, layer, flags),
_fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false),
@@ -126,7 +118,7 @@ AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
sources.push_back (*i);
master_sources.push_back (*i);
- (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), (*i)));
}
_scale_amplitude = 1.0;
@@ -136,32 +128,28 @@ AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
}
-AudioRegion::AudioRegion (const AudioRegion& other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (other, offset, length, name, layer, flags),
- _fade_in (other._fade_in),
- _fade_out (other._fade_out),
- _envelope (other._envelope, (double) offset, (double) offset + length)
+ _fade_in (other->_fade_in),
+ _fade_out (other->_fade_out),
+ _envelope (other->_envelope, (double) offset, (double) offset + length)
{
/* create a new AudioRegion, that is part of an existing one */
set<AudioSource*> unique_srcs;
- for (SourceList::const_iterator i= other.sources.begin(); i != other.sources.end(); ++i) {
+ for (SourceList::const_iterator i= other->sources.begin(); i != other->sources.end(); ++i) {
sources.push_back (*i);
- (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
unique_srcs.insert (*i);
}
- for (SourceList::const_iterator i = other.master_sources.begin(); i != other.master_sources.end(); ++i) {
+ for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
}
master_sources.push_back (*i);
}
@@ -175,7 +163,7 @@ AudioRegion::AudioRegion (const AudioRegion& other, jack_nframes_t offset, jack_
if (_fade_in.back()->when >= _length) {
set_default_fade_in ();
} else {
- _fade_in_disabled = other._fade_in_disabled;
+ _fade_in_disabled = other->_fade_in_disabled;
}
set_default_fade_out ();
_flags = Flag (_flags & ~Region::LeftOfSplit);
@@ -185,48 +173,44 @@ AudioRegion::AudioRegion (const AudioRegion& other, jack_nframes_t offset, jack_
if (_fade_out.back()->when >= _length) {
set_default_fade_out ();
} else {
- _fade_out_disabled = other._fade_out_disabled;
+ _fade_out_disabled = other->_fade_out_disabled;
}
set_default_fade_in ();
_flags = Flag (_flags & ~Region::RightOfSplit);
}
- _scale_amplitude = other._scale_amplitude;
+ _scale_amplitude = other->_scale_amplitude;
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
}
-AudioRegion::AudioRegion (const AudioRegion &other)
+AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
: Region (other),
- _fade_in (other._fade_in),
- _fade_out (other._fade_out),
- _envelope (other._envelope)
+ _fade_in (other->_fade_in),
+ _fade_out (other->_fade_out),
+ _envelope (other->_envelope)
{
/* Pure copy constructor */
set<AudioSource*> unique_srcs;
- for (SourceList::const_iterator i = other.sources.begin(); i != other.sources.end(); ++i) {
+ for (SourceList::const_iterator i = other->sources.begin(); i != other->sources.end(); ++i) {
sources.push_back (*i);
- (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
unique_srcs.insert (*i);
}
- for (SourceList::const_iterator i = other.master_sources.begin(); i != other.master_sources.end(); ++i) {
+ for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
master_sources.push_back (*i);
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
}
}
- _scale_amplitude = other._scale_amplitude;
- _envelope = other._envelope;
+ _scale_amplitude = other->_scale_amplitude;
+ _envelope = other->_envelope;
_fade_in_disabled = 0;
_fade_out_disabled = 0;
@@ -246,7 +230,7 @@ AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node)
{
sources.push_back (&src);
master_sources.push_back (&src);
- src.GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ src.GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), &src));
set_default_fades ();
@@ -257,8 +241,6 @@ AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node)
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- CheckNewRegion (this); /* EMIT SIGNAL */
}
AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
@@ -271,14 +253,14 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
sources.push_back (*i);
- (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
unique_srcs.insert (*i);
}
for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) {
master_sources.push_back (*i);
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
}
}
@@ -292,13 +274,11 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- CheckNewRegion (this); /* EMIT SIGNAL */
}
AudioRegion::~AudioRegion ()
{
- GoingAway (this);
+ GoingAway (); /* EMIT SIGNAL */
}
StateManager::State*
@@ -1133,9 +1113,10 @@ AudioRegion::master_source_names ()
}
bool
-AudioRegion::source_equivalent (const Region& o) const
+AudioRegion::source_equivalent (boost::shared_ptr<const Region> o) const
{
- const AudioRegion* other = dynamic_cast<const AudioRegion*>(&o);
+ boost::shared_ptr<const AudioRegion> other = boost::dynamic_pointer_cast<const AudioRegion>(o);
+
if (!other)
return false;
@@ -1160,7 +1141,7 @@ AudioRegion::source_equivalent (const Region& o) const
int
AudioRegion::apply (AudioFilter& filter)
{
- return filter.run (*this);
+ return filter.run (boost::shared_ptr<AudioRegion> (this));
}
int
@@ -1227,13 +1208,13 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
return status;
}
-Region*
+boost::shared_ptr<Region>
AudioRegion::get_parent()
{
- Region* r = 0;
+ boost::shared_ptr<Region> r;
if (_playlist) {
- r = _playlist->session().find_whole_file_parent (*this);
+ r = _playlist->session().find_whole_file_parent (boost::shared_ptr<AudioRegion>(this));
}
return r;
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index dc08979458..91ed4d7efc 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -28,6 +28,7 @@
#include <ardour/audioplaylist.h>
#include <ardour/panner.h>
#include <ardour/data_type.h>
+#include <ardour/region_factory.h>
using namespace std;
using namespace ARDOUR;
@@ -57,7 +58,7 @@ Auditioner::Auditioner (Session& s)
IO::output_changed.connect (mem_fun (*this, &Auditioner::output_changed));
- the_region = 0;
+ the_region.reset ((AudioRegion*) 0);
g_atomic_int_set (&_active, 0);
}
@@ -72,7 +73,7 @@ Auditioner::prepare_playlist ()
AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
assert(apl);
- apl->clear (false, false);
+ apl->clear (false);
return *apl;
}
@@ -99,7 +100,7 @@ Auditioner::audition_current_playlist ()
}
void
-Auditioner::audition_region (AudioRegion& region)
+Auditioner::audition_region (boost::shared_ptr<AudioRegion> region)
{
if (g_atomic_int_get (&_active)) {
/* don't go via session for this, because we are going
@@ -110,11 +111,13 @@ Auditioner::audition_region (AudioRegion& region)
Glib::Mutex::Lock lm (lock);
- the_region = new AudioRegion (region);
+ /* copy it */
+
+ boost::shared_ptr<AudioRegion> the_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
the_region->set_position (0, this);
- _diskstream->playlist()->clear (true, false);
- _diskstream->playlist()->add_region (*the_region, 0, 1, false);
+ _diskstream->playlist()->clear (false);
+ _diskstream->playlist()->add_region (the_region, 0, 1, false);
while (_diskstream->n_channels() < the_region->n_channels()) {
audio_diskstream()->add_channel ();
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index ccfcef28f4..afdeecbbfe 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -136,6 +136,8 @@ AutomationList::~AutomationList()
std::set<ControlEvent*> all_events;
AutomationList::State* asp;
+ GoingAway ();
+
for (AutomationEventList::iterator x = events.begin(); x != events.end(); ++x) {
all_events.insert (*x);
}
diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc
index 0370886a35..5c02936ba0 100644
--- a/libs/ardour/control_protocol_manager.cc
+++ b/libs/ardour/control_protocol_manager.cc
@@ -43,7 +43,7 @@ void
ControlProtocolManager::set_session (Session& s)
{
_session = &s;
- _session->going_away.connect (mem_fun (*this, &ControlProtocolManager::drop_session));
+ _session->GoingAway.connect (mem_fun (*this, &ControlProtocolManager::drop_session));
for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
if ((*i)->requested || (*i)->mandatory) {
diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc
index f0fcac14e2..19b75619e3 100644
--- a/libs/ardour/coreaudiosource.cc
+++ b/libs/ardour/coreaudiosource.cc
@@ -141,7 +141,7 @@ CoreAudioSource::init (const string& idstr)
CoreAudioSource::~CoreAudioSource ()
{
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
if (af) {
ExtAudioFileDispose (af);
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index 379c9333b0..fcd2158fd8 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2003 Paul Davis
+ Copyright (C) 2003-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,7 +36,7 @@ using namespace ARDOUR;
using namespace PBD;
jack_nframes_t Crossfade::_short_xfade_length = 0;
-Change Crossfade::ActiveChanged = ARDOUR::new_change();
+Change Crossfade::ActiveChanged = new_change();
/* XXX if and when we ever implement parallel processing of the process()
callback, these will need to be handled on a per-thread basis.
@@ -70,15 +70,15 @@ Crossfade::operator== (const Crossfade& other)
return (_in == other._in) && (_out == other._out);
}
-Crossfade::Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out,
+Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<AudioRegion> out,
jack_nframes_t length,
jack_nframes_t position,
AnchorPoint ap)
: _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
{
- _in = &in;
- _out = &out;
+ _in = in;
+ _out = out;
_length = length;
_position = position;
_anchor_point = ap;
@@ -89,7 +89,7 @@ Crossfade::Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out,
initialize ();
}
-Crossfade::Crossfade (ARDOUR::AudioRegion& a, ARDOUR::AudioRegion& b, CrossfadeModel model, bool act)
+Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model, bool act)
: _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
{
@@ -110,7 +110,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
: _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
{
- Region* r;
+ boost::shared_ptr<Region> r;
XMLProperty* prop;
LocaleGuard lg (X_("POSIX"));
@@ -129,7 +129,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
throw failed_constructor();
}
- if ((_in = dynamic_cast<AudioRegion*> (r)) == 0) {
+ if ((_in = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
throw failed_constructor();
}
@@ -146,7 +146,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
throw failed_constructor();
}
- if ((_out = dynamic_cast<AudioRegion*> (r)) == 0) {
+ if ((_out = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
throw failed_constructor();
}
@@ -160,7 +160,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
save_state ("initial");
}
-Crossfade::Crossfade (const Crossfade &orig, ARDOUR::AudioRegion *newin, ARDOUR::AudioRegion *newout)
+Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newin, boost::shared_ptr<AudioRegion> newout)
: _fade_in(orig._fade_in),
_fade_out(orig._fade_out)
{
@@ -236,20 +236,20 @@ Crossfade::initialize (bool savestate)
}
int
-Crossfade::compute (AudioRegion& a, AudioRegion& b, CrossfadeModel model)
+Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model)
{
- AudioRegion* top;
- AudioRegion* bottom;
+ boost::shared_ptr<AudioRegion> top;
+ boost::shared_ptr<AudioRegion> bottom;
jack_nframes_t short_xfade_length;
short_xfade_length = _short_xfade_length;
- if (a.layer() < b.layer()) {
- top = &b;
- bottom = &a;
+ if (a->layer() < b->layer()) {
+ top = b;
+ bottom = a;
} else {
- top = &a;
- bottom = &b;
+ top = a;
+ bottom = b;
}
/* first check for matching ends */
@@ -605,7 +605,7 @@ Crossfade::member_changed (Change what_changed)
{
Change what_we_care_about = Change (Region::MuteChanged|
Region::LayerChanged|
- ARDOUR::BoundsChanged);
+ BoundsChanged);
if (what_changed & what_we_care_about) {
refresh ();
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 151ff5bd3e..ea532d226a 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -32,6 +32,8 @@
#include <sys/stat.h>
#include <sys/mman.h>
+#include <sigc++/bind.h>
+
#include <pbd/error.h>
#include <pbd/basename.h>
#include <glibmm/thread.h>
@@ -332,7 +334,7 @@ Diskstream::use_playlist (Playlist* playlist)
plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &Diskstream::playlist_changed));
plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified));
- plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &Diskstream::playlist_deleted));
+ plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), _playlist));
}
if (!overwrite_queued) {
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index c68eb16aae..6c44185fce 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -40,6 +40,7 @@
#include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/audioregion.h>
+#include <ardour/region_factory.h>
#include "i18n.h"
@@ -53,7 +54,7 @@ Session::import_audiofile (import_status& status)
{
SNDFILE *in;
AudioFileSource **newfiles = 0;
- AudioRegion::SourceList sources;
+ SourceList sources;
SF_INFO info;
float *data = 0;
Sample **channel_data = 0;
@@ -217,8 +218,8 @@ Session::import_audiofile (import_status& status)
sources.push_back(newfiles[n]);
}
- AudioRegion *r = new AudioRegion (sources, 0, newfiles[0]->length(), region_name_from_path (Glib::path_get_basename (basepath)),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile));
+ boost::shared_ptr<AudioRegion> r (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, 0, newfiles[0]->length(), region_name_from_path (Glib::path_get_basename (basepath)),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile))));
status.new_regions.push_back (r);
@@ -233,9 +234,9 @@ Session::import_audiofile (import_status& status)
did not bother to create whole-file AudioRegions for them. Do it now.
*/
- AudioRegion *r = new AudioRegion (*newfiles[n], 0, newfiles[n]->length(), region_name_from_path (Glib::path_get_basename (newfiles[n]->name())),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile | AudioRegion::Import));
-
+ boost::shared_ptr<AudioRegion> r (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (*newfiles[n], 0, newfiles[n]->length(), region_name_from_path (Glib::path_get_basename (newfiles[n]->name())),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile | AudioRegion::Import))));
+
status.new_regions.push_back (r);
}
}
@@ -262,9 +263,8 @@ Session::import_audiofile (import_status& status)
}
if (status.cancel) {
- for (vector<AudioRegion *>::iterator i = status.new_regions.begin(); i != status.new_regions.end(); ++i) {
- delete *i;
- }
+
+ status.new_regions.clear ();
for (vector<string>::iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
unlink ((*i).c_str());
diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc
index 18727e8b5b..f9ead93dbc 100644
--- a/libs/ardour/insert.cc
+++ b/libs/ardour/insert.cc
@@ -172,7 +172,7 @@ PluginInsert::init ()
PluginInsert::~PluginInsert ()
{
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
}
void
@@ -897,7 +897,7 @@ PortInsert::PortInsert (Session& s, const XMLNode& node)
PortInsert::~PortInsert ()
{
- GoingAway (this);
+ GoingAway ();
}
void
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index 6b773b9e0b..310931102d 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -143,7 +143,7 @@ LadspaPlugin::~LadspaPlugin ()
deactivate ();
cleanup ();
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
/* XXX who should close a plugin? */
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index ca88a2851b..58ef812d2e 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -51,6 +51,13 @@ Location::Location (const Location& other)
_flags = Flags (_flags & ~IsEnd);
}
+Location::Location (const XMLNode& node)
+{
+ if (set_state (node)) {
+ throw failed_constructor ();
+ }
+}
+
Location*
Location::operator= (const Location& other)
{
@@ -241,13 +248,16 @@ XMLNode&
Location::get_state (void)
{
XMLNode *node = new XMLNode ("Location");
- char buf[32];
+ char buf[64];
typedef map<string, string>::const_iterator CI;
+
for(CI m = cd_info.begin(); m != cd_info.end(); ++m){
node->add_child_nocopy(cd_info_node(m->first, m->second));
}
+ id().print (buf);
+ node->add_property("id", buf);
node->add_property ("name", name());
snprintf (buf, sizeof (buf), "%u", start());
node->add_property ("start", buf);
@@ -262,7 +272,6 @@ Location::get_state (void)
int
Location::set_state (const XMLNode& node)
{
- XMLPropertyList plist;
const XMLProperty *prop;
XMLNodeList cd_list = node.children();
@@ -272,14 +281,17 @@ Location::set_state (const XMLNode& node)
string cd_name;
string cd_value;
-
if (node.name() != "Location") {
error << _("incorrect XML node passed to Location::set_state") << endmsg;
return -1;
}
- plist = node.properties();
-
+ if ((prop = node.property ("id")) == 0) {
+ warning << _("XML node for Location has no ID information") << endmsg;
+ } else {
+ _id = prop->value ();
+ }
+
if ((prop = node.property ("name")) == 0) {
error << _("XML node for Location has no name information") << endmsg;
return -1;
@@ -582,16 +594,20 @@ Locations::set_state (const XMLNode& node)
Glib::Mutex::Lock lm (lock);
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- Location *loc = new Location;
- if (loc->set_state (**niter)) {
- delete loc;
- } else {
+ try {
+
+ Location *loc = new Location (**niter);
locations.push_back (loc);
}
+
+ catch (failed_constructor& err) {
+ error << _("could not load location from session file - ignored") << endmsg;
+ }
}
if (locations.size()) {
+
current_location = locations.front();
} else {
current_location = 0;
diff --git a/libs/ardour/osc.cc b/libs/ardour/osc.cc
index 5aaf9d5591..c43f254f6f 100644
--- a/libs/ardour/osc.cc
+++ b/libs/ardour/osc.cc
@@ -365,7 +365,7 @@ void
OSC::set_session (Session& s)
{
session = &s;
- session->going_away.connect (mem_fun (*this, &OSC::session_going_away));
+ session->GoingAway.connect (mem_fun (*this, &OSC::session_going_away));
}
void
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 6d5e8f7847..b8a7a44f58 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -55,19 +55,19 @@ struct ShowMeTheList {
};
struct RegionSortByLayer {
- bool operator() (Region *a, Region *b) {
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
return a->layer() < b->layer();
}
};
struct RegionSortByPosition {
- bool operator() (Region *a, Region *b) {
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
return a->position() < b->position();
}
};
struct RegionSortByLastLayerOp {
- bool operator() (Region *a, Region *b) {
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
return a->last_layer_op() < b->last_layer_op();
}
};
@@ -101,7 +101,7 @@ Playlist::Playlist (const Playlist& other, string namestr, bool hide)
in_set_state = true;
- for (list<Region*>::iterator x = tmp.begin(); x != tmp.end(); ++x) {
+ for (list<boost::shared_ptr<Region> >::iterator x = tmp.begin(); x != tmp.end(); ++x) {
add_region_internal( (*x), (*x)->position() );
}
@@ -135,8 +135,8 @@ Playlist::Playlist (const Playlist& other, jack_nframes_t start, jack_nframes_t
for (RegionList::const_iterator i = other.regions.begin(); i != other.regions.end(); i++) {
- Region *region;
- Region *new_region;
+ boost::shared_ptr<Region> region;
+ boost::shared_ptr<Region> new_region;
jack_nframes_t offset = 0;
jack_nframes_t position = 0;
jack_nframes_t len = 0;
@@ -178,7 +178,7 @@ Playlist::Playlist (const Playlist& other, jack_nframes_t start, jack_nframes_t
_session.region_name (new_name, region->name(), false);
- new_region = createRegion (*region, offset, len, new_name, region->layer(), region->flags());
+ new_region = RegionFactory::RegionFactory::create (region, offset, len, new_name, region->layer(), region->flags());
add_region_internal (new_region, position, true);
}
@@ -216,7 +216,7 @@ Playlist::copy_regions (RegionList& newlist) const
RegionLock rlock (const_cast<Playlist *> (this));
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
- newlist.push_back (createRegion (**i));
+ newlist.push_back (RegionFactory::RegionFactory::create (*i));
}
}
@@ -259,6 +259,7 @@ Playlist::Playlist (Playlist& pl)
Playlist::~Playlist ()
{
+ /* GoingAway must be emitted by derived classes */
}
void
@@ -329,7 +330,7 @@ Playlist::notify_modified ()
}
void
-Playlist::notify_region_removed (Region *r)
+Playlist::notify_region_removed (boost::shared_ptr<Region> r)
{
if (holding_state ()) {
pending_removals.insert (pending_removals.end(), r);
@@ -344,7 +345,7 @@ Playlist::notify_region_removed (Region *r)
}
void
-Playlist::notify_region_added (Region *r)
+Playlist::notify_region_added (boost::shared_ptr<Region> r)
{
if (holding_state()) {
pending_adds.insert (pending_adds.end(), r);
@@ -374,7 +375,7 @@ Playlist::flush_notifications ()
{
RegionList::iterator r;
RegionList::iterator a;
- set<Region*> dependent_checks_needed;
+ set<boost::shared_ptr<Region> > dependent_checks_needed;
uint32_t n = 0;
if (in_flush) {
@@ -394,7 +395,7 @@ Playlist::flush_notifications ()
for (RegionList::iterator r = pending_bounds.begin(); r != pending_bounds.end(); ++r) {
if (_session.get_layer_model() == Session::MoveAddHigher) {
- timestamp_layer_op (**r);
+ timestamp_layer_op (*r);
}
pending_length = true;
n++;
@@ -411,12 +412,12 @@ Playlist::flush_notifications ()
n++;
}
- for (set<Region*>::iterator x = dependent_checks_needed.begin(); x != dependent_checks_needed.end(); ++x) {
- check_dependents (**x, false);
+ for (set<boost::shared_ptr<Region> >::iterator x = dependent_checks_needed.begin(); x != dependent_checks_needed.end(); ++x) {
+ check_dependents (*x, false);
}
for (r = pending_removals.begin(); r != pending_removals.end(); ++r) {
- remove_dependents (**r);
+ remove_dependents (*r);
RegionRemoved (*r); /* EMIT SIGNAL */
n++;
}
@@ -453,7 +454,7 @@ Playlist::flush_notifications ()
*************************************************************/
void
-Playlist::add_region (const Region& region, jack_nframes_t position, float times, bool with_save)
+Playlist::add_region (boost::shared_ptr<Region> region, jack_nframes_t position, float times, bool with_save)
{
RegionLock rlock (this);
@@ -464,8 +465,8 @@ Playlist::add_region (const Region& region, jack_nframes_t position, float times
jack_nframes_t pos = position;
if (itimes >= 1) {
- add_region_internal (const_cast<Region*>(&region), pos, true);
- pos += region.length();
+ add_region_internal (region, pos, true);
+ pos += region->length();
--itimes;
}
@@ -480,16 +481,16 @@ Playlist::add_region (const Region& region, jack_nframes_t position, float times
*/
for (int i = 0; i < itimes; ++i) {
- Region *copy = createRegion (region);
+ boost::shared_ptr<Region> copy = RegionFactory::create (region);
add_region_internal (copy, pos, true);
- pos += region.length();
+ pos += region->length();
}
if (floor (times) != times) {
- jack_nframes_t length = (jack_nframes_t) floor (region.length() * (times - floor (times)));
+ jack_nframes_t length = (jack_nframes_t) floor (region->length() * (times - floor (times)));
string name;
- _session.region_name (name, region.name(), false);
- Region *sub = createRegion (region, 0, length, name, region.layer(), region.flags());
+ _session.region_name (name, region->name(), false);
+ boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos, true);
}
@@ -499,13 +500,11 @@ Playlist::add_region (const Region& region, jack_nframes_t position, float times
}
void
-Playlist::add_region_internal (Region *region, jack_nframes_t position, bool delay_sort)
+Playlist::add_region_internal (boost::shared_ptr<Region> region, jack_nframes_t position, bool delay_sort)
{
RegionSortByPosition cmp;
jack_nframes_t old_length = 0;
- // cerr << "adding region " << region->name() << " at " << position << endl;
-
if (!holding_state()) {
old_length = _get_maximum_extent();
}
@@ -514,7 +513,7 @@ Playlist::add_region_internal (Region *region, jack_nframes_t position, bool del
region->set_position (position, this);
region->lock_sources ();
- timestamp_layer_op (*region);
+ timestamp_layer_op (region);
regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region);
@@ -528,7 +527,7 @@ Playlist::add_region_internal (Region *region, jack_nframes_t position, bool del
notify_region_added (region);
if (!holding_state ()) {
- check_dependents (*region, false);
+ check_dependents (region, false);
if (old_length != _get_maximum_extent()) {
notify_length_changed ();
}
@@ -538,12 +537,12 @@ Playlist::add_region_internal (Region *region, jack_nframes_t position, bool del
}
void
-Playlist::replace_region (Region& old, Region& newr, jack_nframes_t pos)
+Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, jack_nframes_t pos)
{
RegionLock rlock (this);
- remove_region_internal (&old);
- add_region_internal (&newr, pos);
+ remove_region_internal (old);
+ add_region_internal (newr, pos);
if (!holding_state ()) {
possibly_splice_unlocked ();
@@ -553,7 +552,7 @@ Playlist::replace_region (Region& old, Region& newr, jack_nframes_t pos)
}
void
-Playlist::remove_region (Region *region)
+Playlist::remove_region (boost::shared_ptr<Region> region)
{
RegionLock rlock (this);
remove_region_internal (region);
@@ -566,7 +565,7 @@ Playlist::remove_region (Region *region)
}
int
-Playlist::remove_region_internal (Region *region, bool delay_sort)
+Playlist::remove_region_internal (boost::shared_ptr<Region>region, bool delay_sort)
{
RegionList::iterator i;
jack_nframes_t old_length = 0;
@@ -584,7 +583,7 @@ Playlist::remove_region_internal (Region *region, bool delay_sort)
if (!holding_state ()) {
relayer ();
- remove_dependents (*region);
+ remove_dependents (region);
if (old_length != _get_maximum_extent()) {
notify_length_changed ();
@@ -599,7 +598,7 @@ Playlist::remove_region_internal (Region *region, bool delay_sort)
}
void
-Playlist::get_equivalent_regions (const Region& other, vector<Region*>& results)
+Playlist::get_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results)
{
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
if (Config->get_use_overlap_equivalency()) {
@@ -613,7 +612,7 @@ Playlist::get_equivalent_regions (const Region& other, vector<Region*>& results)
}
void
-Playlist::get_region_list_equivalent_regions (const Region& other, vector<Region*>& results)
+Playlist::get_region_list_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results)
{
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
@@ -641,8 +640,8 @@ void
Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cutting, RegionList& thawlist)
{
RegionLock rlock (this);
- Region *region;
- Region *current;
+ boost::shared_ptr<Region> region;
+ boost::shared_ptr<Region> current;
string new_name;
RegionList::iterator tmp;
OverlapType overlap;
@@ -702,7 +701,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
/* "middle" ++++++ */
_session.region_name (new_name, current->name(), false);
- region = createRegion (*current, pos2 - pos1, pos3 - pos2, new_name,
+ region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit));
add_region_internal (region, start, true);
new_regions.push_back (region);
@@ -711,7 +710,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
/* "end" ====== */
_session.region_name (new_name, current->name(), false);
- region = createRegion (*current, pos3 - pos1, pos4 - pos3, new_name,
+ region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
add_region_internal (region, end, true);
@@ -741,7 +740,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
/* end +++++ */
_session.region_name (new_name, current->name(), false);
- region = createRegion (*current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
+ region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
add_region_internal (region, start, true);
new_regions.push_back (region);
@@ -775,7 +774,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
/* front **** */
_session.region_name (new_name, current->name(), false);
- region = createRegion (*current, 0, pos3 - pos1, new_name,
+ region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
add_region_internal (region, pos1, true);
new_regions.push_back (region);
@@ -815,7 +814,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
in_partition = false;
for (RegionList::iterator i = new_regions.begin(); i != new_regions.end(); ++i) {
- check_dependents (**i, false);
+ check_dependents (*i, false);
}
}
@@ -936,7 +935,7 @@ Playlist::paste (Playlist& other, jack_nframes_t position, float times)
while (itimes--) {
for (RegionList::iterator i = other.regions.begin(); i != other.regions.end(); ++i) {
- Region *copy_of_region = createRegion (**i);
+ boost::shared_ptr<Region> copy_of_region = RegionFactory::create (*i);
/* put these new regions on top of all existing ones, but preserve
the ordering they had in the original playlist.
@@ -966,7 +965,7 @@ Playlist::paste (Playlist& other, jack_nframes_t position, float times)
void
-Playlist::duplicate (Region& region, jack_nframes_t position, float times)
+Playlist::duplicate (boost::shared_ptr<Region> region, jack_nframes_t position, float times)
{
times = fabs (times);
@@ -975,16 +974,16 @@ Playlist::duplicate (Region& region, jack_nframes_t position, float times)
jack_nframes_t pos = position;
while (itimes--) {
- Region *copy = createRegion (region);
+ boost::shared_ptr<Region> copy = RegionFactory::create (region);
add_region_internal (copy, pos, true);
- pos += region.length();
+ pos += region->length();
}
if (floor (times) != times) {
- jack_nframes_t length = (jack_nframes_t) floor (region.length() * (times - floor (times)));
+ jack_nframes_t length = (jack_nframes_t) floor (region->length() * (times - floor (times)));
string name;
- _session.region_name (name, region.name(), false);
- Region *sub = createRegion (region, 0, length, name, region.layer(), region.flags());
+ _session.region_name (name, region->name(), false);
+ boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos, true);
}
@@ -992,40 +991,40 @@ Playlist::duplicate (Region& region, jack_nframes_t position, float times)
}
void
-Playlist::split_region (Region& region, jack_nframes_t playlist_position)
+Playlist::split_region (boost::shared_ptr<Region> region, jack_nframes_t playlist_position)
{
RegionLock rl (this);
- if (!region.covers (playlist_position)) {
+ if (!region->covers (playlist_position)) {
return;
}
- if (region.position() == playlist_position ||
- region.last_frame() == playlist_position) {
+ if (region->position() == playlist_position ||
+ region->last_frame() == playlist_position) {
return;
}
- Region *left;
- Region *right;
+ boost::shared_ptr<Region> left;
+ boost::shared_ptr<Region> right;
jack_nframes_t before;
jack_nframes_t after;
string before_name;
string after_name;
- before = playlist_position - region.position();
- after = region.length() - before;
+ before = playlist_position - region->position();
+ after = region->length() - before;
- _session.region_name (before_name, region.name(), false);
- left = createRegion (region, 0, before, before_name, region.layer(), Region::Flag (region.flags()|Region::LeftOfSplit));
+ _session.region_name (before_name, region->name(), false);
+ left = RegionFactory::create (region, 0, before, before_name, region->layer(), Region::Flag (region->flags()|Region::LeftOfSplit));
- _session.region_name (after_name, region.name(), false);
- right = createRegion (region, before, after, after_name, region.layer(), Region::Flag (region.flags()|Region::RightOfSplit));
+ _session.region_name (after_name, region->name(), false);
+ right = RegionFactory::create (region, before, after, after_name, region->layer(), Region::Flag (region->flags()|Region::RightOfSplit));
- add_region_internal (left, region.position(), true);
- add_region_internal (right, region.position() + before);
+ add_region_internal (left, region->position(), true);
+ add_region_internal (right, region->position() + before);
- uint64_t orig_layer_op = region.last_layer_op();
+ uint64_t orig_layer_op = region->last_layer_op();
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
if ((*i)->last_layer_op() > orig_layer_op) {
(*i)->set_last_layer_op( (*i)->last_layer_op() + 1 );
@@ -1037,9 +1036,9 @@ Playlist::split_region (Region& region, jack_nframes_t playlist_position)
layer_op_counter++;
- finalize_split_region (&region, left, right);
+ finalize_split_region (region, left, right);
- if (remove_region_internal (&region, true)) {
+ if (remove_region_internal (region, true)) {
return;
}
@@ -1103,7 +1102,7 @@ Playlist::core_splice ()
}
void
-Playlist::region_bounds_changed (Change what_changed, Region *region)
+Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region> region)
{
if (in_set_state || _splicing || _nudging) {
return;
@@ -1127,8 +1126,7 @@ Playlist::region_bounds_changed (Change what_changed, Region *region)
}
regions.erase (i);
- regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp),
- region);
+ regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region);
}
@@ -1139,11 +1137,11 @@ Playlist::region_bounds_changed (Change what_changed, Region *region)
} else {
if (_session.get_layer_model() == Session::MoveAddHigher) {
/* it moved or changed length, so change the timestamp */
- timestamp_layer_op (*region);
+ timestamp_layer_op (region);
}
possibly_splice ();
- check_dependents (*region, false);
+ check_dependents (region, false);
notify_length_changed ();
relayer ();
}
@@ -1151,7 +1149,7 @@ Playlist::region_bounds_changed (Change what_changed, Region *region)
}
void
-Playlist::region_changed_proxy (Change what_changed, Region* region)
+Playlist::region_changed_proxy (Change what_changed, boost::shared_ptr<Region> region)
{
/* this makes a virtual call to the right kind of playlist ... */
@@ -1159,7 +1157,7 @@ Playlist::region_changed_proxy (Change what_changed, Region* region)
}
bool
-Playlist::region_changed (Change what_changed, Region* region)
+Playlist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{
Change our_interests = Change (Region::MuteChanged|Region::LayerChanged|Region::OpacityChanged);
bool save = false;
@@ -1176,7 +1174,7 @@ Playlist::region_changed (Change what_changed, Region* region)
if ((what_changed & Region::MuteChanged) &&
!(what_changed & Change (ARDOUR::PositionChanged|ARDOUR::LengthChanged))) {
- check_dependents (*region, false);
+ check_dependents (region, false);
}
if (what_changed & our_interests) {
@@ -1188,7 +1186,7 @@ Playlist::region_changed (Change what_changed, Region* region)
}
void
-Playlist::clear (bool with_delete, bool with_save)
+Playlist::clear (bool with_save)
{
RegionList::iterator i;
RegionList tmp;
@@ -1201,9 +1199,6 @@ Playlist::clear (bool with_delete, bool with_save)
for (i = tmp.begin(); i != tmp.end(); ++i) {
notify_region_removed (*i);
- if (with_delete) {
- delete *i;
- }
}
if (with_save) {
@@ -1223,14 +1218,14 @@ Playlist::regions_at (jack_nframes_t frame)
return find_regions_at (frame);
}
-Region *
+boost::shared_ptr<Region>
Playlist::top_region_at (jack_nframes_t frame)
{
RegionLock rlock (this);
RegionList *rlist = find_regions_at (frame);
- Region *region = 0;
-
+ boost::shared_ptr<Region> region;
+
if (rlist->size()) {
RegionSortByLayer cmp;
rlist->sort (cmp);
@@ -1271,18 +1266,17 @@ Playlist::regions_touched (jack_nframes_t start, jack_nframes_t end)
}
-Region*
-
+boost::shared_ptr<Region>
Playlist::find_next_region (jack_nframes_t frame, RegionPoint point, int dir)
{
RegionLock rlock (this);
- Region* ret = 0;
+ boost::shared_ptr<Region> ret;
jack_nframes_t closest = max_frames;
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
jack_nframes_t distance;
- Region* r = (*i);
+ boost::shared_ptr<Region> r = (*i);
jack_nframes_t pos = 0;
switch (point) {
@@ -1347,10 +1341,10 @@ Playlist::set_state (const XMLNode& node)
XMLPropertyList plist;
XMLPropertyConstIterator piter;
XMLProperty *prop;
- Region *region;
+ boost::shared_ptr<Region> region;
string region_name;
- clear (false, false);
+ clear (false);
if (node.name() != "Playlist") {
in_set_state = false;
@@ -1380,12 +1374,12 @@ Playlist::set_state (const XMLNode& node)
if (child->name() == "Region") {
- if ((region = createRegion (_session, *child, true)) == 0) {
+ if ((region = RegionFactory::create (_session, *child, true)) == 0) {
error << _("Playlist: cannot create region from state file") << endmsg;
continue;
}
- add_region (*region, region->position(), 1.0, false);
+ add_region (region, region->position(), 1.0, false);
// So that layer_op ordering doesn't get screwed up
region->set_last_layer_op( region->layer());
@@ -1399,7 +1393,7 @@ Playlist::set_state (const XMLNode& node)
*/
for (RegionList::iterator r = regions.begin(); r != regions.end(); ++r) {
- check_dependents (**r, false);
+ check_dependents (*r, false);
}
in_set_state = false;
@@ -1581,10 +1575,10 @@ Playlist::relayer ()
/* XXX these layer functions are all deprecated */
void
-Playlist::raise_region (Region& region)
+Playlist::raise_region (boost::shared_ptr<Region> region)
{
uint32_t rsz = regions.size();
- layer_t target = region.layer() + 1U;
+ layer_t target = region->layer() + 1U;
if (target >= rsz) {
/* its already at the effective top */
@@ -1595,20 +1589,20 @@ Playlist::raise_region (Region& region)
}
void
-Playlist::lower_region (Region& region)
+Playlist::lower_region (boost::shared_ptr<Region> region)
{
- if (region.layer() == 0) {
+ if (region->layer() == 0) {
/* its already at the bottom */
return;
}
- layer_t target = region.layer() - 1U;
+ layer_t target = region->layer() - 1U;
move_region_to_layer (target, region, -1);
}
void
-Playlist::raise_region_to_top (Region& region)
+Playlist::raise_region_to_top (boost::shared_ptr<Region> region)
{
/* does nothing useful if layering mode is later=higher */
if ((_session.get_layer_model() == Session::MoveAddHigher) ||
@@ -1619,21 +1613,21 @@ Playlist::raise_region_to_top (Region& region)
}
void
-Playlist::lower_region_to_bottom (Region& region)
+Playlist::lower_region_to_bottom (boost::shared_ptr<Region> region)
{
/* does nothing useful if layering mode is later=higher */
if ((_session.get_layer_model() == Session::MoveAddHigher) ||
(_session.get_layer_model() == Session::AddHigher)) {
- region.set_last_layer_op (0);
+ region->set_last_layer_op (0);
relayer ();
}
}
int
-Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
+Playlist::move_region_to_layer (layer_t target_layer, boost::shared_ptr<Region> region, int dir)
{
RegionList::iterator i;
- typedef pair<Region*,layer_t> LayerInfo;
+ typedef pair<boost::shared_ptr<Region>,layer_t> LayerInfo;
list<LayerInfo> layerinfo;
layer_t dest;
@@ -1642,7 +1636,7 @@ Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
for (i = regions.begin(); i != regions.end(); ++i) {
- if (&region == *i) {
+ if (region == *i) {
continue;
}
@@ -1652,7 +1646,7 @@ Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
down 1
*/
- if ((*i)->layer() > region.layer() && (*i)->layer() <= target_layer) {
+ if ((*i)->layer() > region->layer() && (*i)->layer() <= target_layer) {
dest = (*i)->layer() - 1;
} else {
/* not affected */
@@ -1664,7 +1658,7 @@ Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
up 1
*/
- if ((*i)->layer() < region.layer() && (*i)->layer() >= target_layer) {
+ if ((*i)->layer() < region->layer() && (*i)->layer() >= target_layer) {
dest = (*i)->layer() + 1;
} else {
/* not affected */
@@ -1687,12 +1681,12 @@ Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
x->first->set_layer (x->second);
}
- region.set_layer (target_layer);
+ region->set_layer (target_layer);
/* now check all dependents */
for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) {
- check_dependents (*(x->first), false);
+ check_dependents (x->first, false);
}
check_dependents (region, false);
@@ -1747,19 +1741,20 @@ Playlist::nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwa
}
-Region*
+boost::shared_ptr<Region>
Playlist::find_region (const ID& id) const
{
RegionLock rlock (const_cast<Playlist*> (this));
RegionList::const_iterator i;
-
+ boost::shared_ptr<Region> ret;
+
for (i = regions.begin(); i != regions.end(); ++i) {
if ((*i)->id() == id) {
- return (*i);
+ ret = *i;
}
}
- return 0;
+ return ret;
}
void
@@ -1773,7 +1768,7 @@ Playlist::save_state (std::string why)
void
Playlist::dump () const
{
- Region *r;
+ boost::shared_ptr<Region> r;
cerr << "Playlist \"" << _name << "\" " << endl
<< regions.size() << " regions "
@@ -1798,11 +1793,11 @@ Playlist::set_frozen (bool yn)
}
void
-Playlist::timestamp_layer_op (Region& region)
+Playlist::timestamp_layer_op (boost::shared_ptr<Region> region)
{
// struct timeval tv;
// gettimeofday (&tv, 0);
- region.set_last_layer_op (++layer_op_counter);
+ region->set_last_layer_op (++layer_op_counter);
}
void
diff --git a/libs/ardour/playlist_factory.cc b/libs/ardour/playlist_factory.cc
index 7c7060dae8..05d9c76f7a 100644
--- a/libs/ardour/playlist_factory.cc
+++ b/libs/ardour/playlist_factory.cc
@@ -20,60 +20,14 @@
#include <pbd/error.h>
-#include <ardour/session.h>
-
#include <ardour/playlist.h>
#include <ardour/audioplaylist.h>
-#include <ardour/region_factory.h>
-#include <ardour/region.h>
-#include <ardour/audioregion.h>
-
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
-Region*
-ARDOUR::createRegion (const Region& region, jack_nframes_t start,
- jack_nframes_t length, std::string name,
- layer_t layer, Region::Flag flags)
-{
- const AudioRegion* ar;
-
- if ((ar = dynamic_cast<const AudioRegion*>(&region)) != 0) {
- AudioRegion* ret;
- ret = new AudioRegion (*ar, start, length, name, layer, flags);
- return ret;
- } else {
- fatal << _("programming error: Playlist::createRegion called with unknown Region type")
- << endmsg;
- /*NOTREACHED*/
- return 0;
- }
-}
-
-Region*
-ARDOUR::createRegion (const Region& region)
-{
- const AudioRegion* ar;
-
- if ((ar = dynamic_cast<const AudioRegion*>(&region)) != 0) {
- return new AudioRegion (*ar);
- } else {
- fatal << _("programming error: Playlist::createRegion called with unknown Region type")
- << endmsg;
- /*NOTREACHED*/
- return 0;
- }
-}
-
-Region*
-ARDOUR::createRegion (Session& session, XMLNode& node, bool yn)
-{
- return session.XMLRegionFactory (node, yn);
-}
-
Playlist*
Playlist::copyPlaylist (const Playlist& playlist, jack_nframes_t start, jack_nframes_t length,
string name, bool result_is_hidden)
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 037c844324..f81cb3bed5 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -47,8 +47,6 @@ Change Region::LockChanged = ARDOUR::new_change ();
Change Region::LayerChanged = ARDOUR::new_change ();
Change Region::HiddenChanged = ARDOUR::new_change ();
-sigc::signal<void,Region *> Region::CheckNewRegion;
-
Region::Region (jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags)
{
/* basic Region constructor */
@@ -71,7 +69,7 @@ Region::Region (jack_nframes_t start, jack_nframes_t length, const string& name,
_last_layer_op = 0;
}
-Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
+Region::Region (boost::shared_ptr<const Region> other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
{
/* create a new Region from part of an existing one */
@@ -80,9 +78,9 @@ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t lengt
_playlist = 0;
_read_data_count = 0;
- _start = other._start + offset;
- if (other._sync_position < offset) {
- _sync_position = other._sync_position;
+ _start = other->_start + offset;
+ if (other->_sync_position < offset) {
+ _sync_position = other->_sync_position;
} else {
_sync_position = _start;
}
@@ -96,7 +94,7 @@ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t lengt
_last_layer_op = 0;
}
-Region::Region (const Region &other)
+Region::Region (boost::shared_ptr<const Region> other)
{
/* Pure copy constructor */
@@ -106,23 +104,23 @@ Region::Region (const Region &other)
_read_data_count = 0;
_first_edit = EditChangesID;
- other._first_edit = EditChangesName;
+ other->_first_edit = EditChangesName;
- if (other._extra_xml) {
- _extra_xml = new XMLNode (*other._extra_xml);
+ if (other->_extra_xml) {
+ _extra_xml = new XMLNode (*other->_extra_xml);
} else {
_extra_xml = 0;
}
- _start = other._start;
- _sync_position = other._sync_position;
- _length = other._length;
- _name = other._name;
- _position = other._position;
- _layer = other._layer;
- _flags = Flag (other._flags & ~Locked);
+ _start = other->_start;
+ _sync_position = other->_sync_position;
+ _length = other->_length;
+ _name = other->_name;
+ _position = other->_position;
+ _layer = other->_layer;
+ _flags = Flag (other->_flags & ~Locked);
_current_state_id = 0;
- _last_layer_op = other._last_layer_op;
+ _last_layer_op = other->_last_layer_op;
}
Region::Region (const XMLNode& node)
@@ -148,6 +146,9 @@ Region::Region (const XMLNode& node)
Region::~Region ()
{
+ notify_callbacks ();
+
+ /* derived classes must emit GoingAway */
}
void
@@ -273,7 +274,7 @@ Region::first_edit ()
_first_edit = EditChangesNothing;
send_change (NameChanged);
- CheckNewRegion (this);
+ /// XXX CheckNewRegion (boost::shared_ptr<Region>(this));
}
}
@@ -284,7 +285,7 @@ Region::move_to_natural_position (void *src)
return;
}
- Region* whole_file_region = get_parent();
+ boost::shared_ptr<Region> whole_file_region = get_parent();
if (whole_file_region) {
set_position (whole_file_region->position() + _start, src);
@@ -342,7 +343,7 @@ Region::set_position_on_top (jack_nframes_t pos, void *src)
}
}
- _playlist->raise_region_to_top (*this);
+ _playlist->raise_region_to_top (boost::shared_ptr<Region>(this));
/* do this even if the position is the same. this helps out
a GUI that has moved its representation already.
@@ -784,7 +785,7 @@ Region::raise ()
return;
}
- _playlist->raise_region (*this);
+ _playlist->raise_region (boost::shared_ptr<Region>(this));
}
void
@@ -794,7 +795,7 @@ Region::lower ()
return;
}
- _playlist->lower_region (*this);
+ _playlist->lower_region (boost::shared_ptr<Region>(this));
}
void
@@ -805,7 +806,7 @@ Region::raise_to_top ()
return;
}
- _playlist->raise_region_to_top (*this);
+ _playlist->raise_region_to_top (boost::shared_ptr<Region>(this));
}
void
@@ -815,7 +816,7 @@ Region::lower_to_bottom ()
return;
}
- _playlist->lower_region_to_bottom (*this);
+ _playlist->lower_region_to_bottom (boost::shared_ptr<Region>(this));
}
void
@@ -992,28 +993,28 @@ Region::set_last_layer_op (uint64_t when)
}
bool
-Region::overlap_equivalent (const Region& other) const
+Region::overlap_equivalent (boost::shared_ptr<const Region> other) const
{
- return coverage (other.first_frame(), other.last_frame()) != OverlapNone;
+ return coverage (other->first_frame(), other->last_frame()) != OverlapNone;
}
bool
-Region::equivalent (const Region& other) const
+Region::equivalent (boost::shared_ptr<const Region> other) const
{
- return _start == other._start &&
- _position == other._position &&
- _length == other._length;
+ return _start == other->_start &&
+ _position == other->_position &&
+ _length == other->_length;
}
bool
-Region::size_equivalent (const Region& other) const
+Region::size_equivalent (boost::shared_ptr<const Region> other) const
{
- return _start == other._start &&
- _length == other._length;
+ return _start == other->_start &&
+ _length == other->_length;
}
bool
-Region::region_list_equivalent (const Region& other) const
+Region::region_list_equivalent (boost::shared_ptr<const Region> other) const
{
- return size_equivalent (other) && source_equivalent (other) && _name == other._name;
+ return size_equivalent (other) && source_equivalent (other) && _name == other->_name;
}
diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc
index 3fe6aaa630..4d8dd22aa4 100644
--- a/libs/ardour/reverse.cc
+++ b/libs/ardour/reverse.cc
@@ -43,10 +43,10 @@ Reverse::~Reverse ()
}
int
-Reverse::run (AudioRegion& region)
+Reverse::run (boost::shared_ptr<AudioRegion> region)
{
- AudioRegion::SourceList nsrcs;
- AudioRegion::SourceList::iterator si;
+ SourceList nsrcs;
+ SourceList::iterator si;
const jack_nframes_t blocksize = 256 * 1048;
Sample buf[blocksize];
jack_nframes_t fpos;
@@ -61,8 +61,8 @@ Reverse::run (AudioRegion& region)
goto out;
}
- fend = region.start() + region.length();
- fstart = region.start();
+ fend = region->start() + region->length();
+ fstart = region->start();
if (blocksize < fend) {
fpos =max(fstart, fend - blocksize);
@@ -70,7 +70,7 @@ Reverse::run (AudioRegion& region)
fpos = fstart;
}
- to_read = min (region.length(), blocksize);
+ to_read = min (region->length(), blocksize);
/* now read it backwards */
@@ -78,11 +78,11 @@ Reverse::run (AudioRegion& region)
uint32_t n;
- for (n = 0, si = nsrcs.begin(); n < region.n_channels(); ++n, ++si) {
+ for (n = 0, si = nsrcs.begin(); n < region->n_channels(); ++n, ++si) {
/* read it in */
- if (region.source (n).read (buf, fpos, to_read) != to_read) {
+ if (region->source (n).read (buf, fpos, to_read) != to_read) {
goto out;
}
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 2b72fb9bdb..a8e239d49b 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -65,7 +65,7 @@ Send::Send (const Send& other)
Send::~Send ()
{
- GoingAway (this);
+ GoingAway ();
}
XMLNode&
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 91a3bfcc46..21b0cf5fa7 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -372,9 +372,23 @@ Session::~Session ()
_state_of_the_state = StateOfTheState (CannotSave|Deletion);
_engine.remove_session ();
+
+ GoingAway (); /* EMIT SIGNAL */
- going_away (); /* EMIT SIGNAL */
+ /* do this */
+
+ notify_callbacks ();
+
+ /* clear history so that no references to objects are held any more */
+
+ history.clear ();
+
+ /* clear state tree so that no references to objects are held any more */
+ if (state_tree) {
+ delete state_tree;
+ }
+
terminate_butler_thread ();
terminate_midi_thread ();
@@ -433,16 +447,12 @@ Session::~Session ()
#ifdef TRACK_DESTRUCTION
cerr << "delete audio regions\n";
#endif /* TRACK_DESTRUCTION */
- for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
- AudioRegionList::iterator tmp;
-
- tmp =i;
- ++tmp;
-
- delete i->second;
-
- i = tmp;
+
+ for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
+ i->second->drop_references ();
}
+
+ audio_regions.clear ();
#ifdef TRACK_DESTRUCTION
cerr << "delete routes\n";
@@ -450,12 +460,8 @@ Session::~Session ()
{
RCUWriter<RouteList> writer (routes);
boost::shared_ptr<RouteList> r = writer.get_copy ();
- for (RouteList::iterator i = r->begin(); i != r->end(); ) {
- RouteList::iterator tmp;
- tmp = i;
- ++tmp;
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->drop_references ();
- i = tmp;
}
r->clear ();
/* writer goes out of scope and updates master */
@@ -552,10 +558,6 @@ Session::~Session ()
if (mmc) {
delete mmc;
}
-
- if (state_tree) {
- delete state_tree;
- }
}
void
@@ -2497,24 +2499,24 @@ Session::region_name (string& result, string base, bool newlevel) const
}
void
-Session::add_region (Region* region)
+Session::add_region (boost::shared_ptr<Region> region)
{
- AudioRegion* ar = 0;
- AudioRegion* oar = 0;
+ boost::shared_ptr<AudioRegion> ar;
+ boost::shared_ptr<AudioRegion> oar;
bool added = false;
{
Glib::Mutex::Lock lm (region_lock);
- if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
+ if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
AudioRegionList::iterator x;
for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
- oar = dynamic_cast<AudioRegion*> (x->second);
+ oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
- if (ar->region_list_equivalent (*oar)) {
+ if (ar->region_list_equivalent (oar)) {
break;
}
}
@@ -2527,6 +2529,7 @@ Session::add_region (Region* region)
entry.second = ar;
pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
+
if (!x.second) {
return;
@@ -2552,14 +2555,14 @@ Session::add_region (Region* region)
set_dirty();
if (added) {
- region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
+ region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
AudioRegionAdded (ar); /* EMIT SIGNAL */
}
}
void
-Session::region_changed (Change what_changed, Region* region)
+Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{
if (what_changed & Region::HiddenChanged) {
/* relay hidden changes */
@@ -2568,22 +2571,22 @@ Session::region_changed (Change what_changed, Region* region)
}
void
-Session::region_renamed (Region* region)
+Session::region_renamed (boost::shared_ptr<Region> region)
{
add_region (region);
}
void
-Session::remove_region (Region* region)
+Session::remove_region (boost::shared_ptr<Region> region)
{
AudioRegionList::iterator i;
- AudioRegion* ar = 0;
+ boost::shared_ptr<AudioRegion> ar;
bool removed = false;
{
Glib::Mutex::Lock lm (region_lock);
- if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
+ if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
audio_regions.erase (i);
removed = true;
@@ -2609,11 +2612,11 @@ Session::remove_region (Region* region)
}
}
-AudioRegion*
-Session::find_whole_file_parent (AudioRegion& child)
+boost::shared_ptr<AudioRegion>
+Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
{
AudioRegionList::iterator i;
- AudioRegion* region;
+ boost::shared_ptr<AudioRegion> region;
Glib::Mutex::Lock lm (region_lock);
for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
@@ -2622,28 +2625,28 @@ Session::find_whole_file_parent (AudioRegion& child)
if (region->whole_file()) {
- if (child.source_equivalent (*region)) {
+ if (child->source_equivalent (region)) {
return region;
}
}
}
- return 0;
+ return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
}
void
-Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
+Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
{
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
(*i)->get_region_list_equivalent_regions (region, result);
}
int
-Session::destroy_region (Region* region)
+Session::destroy_region (boost::shared_ptr<Region> region)
{
- AudioRegion* aregion;
+ boost::shared_ptr<AudioRegion> aregion;
- if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
+ if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
return 0;
}
@@ -2672,9 +2675,9 @@ Session::destroy_region (Region* region)
}
int
-Session::destroy_regions (list<Region*> regions)
+Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
{
- for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
+ for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
destroy_region (*i);
}
return 0;
@@ -2683,12 +2686,12 @@ Session::destroy_regions (list<Region*> regions)
int
Session::remove_last_capture ()
{
- list<Region*> r;
+ list<boost::shared_ptr<Region> > r;
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- list<Region*>& l = (*i)->last_capture_regions();
+ list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
if (!l.empty()) {
r.insert (r.end(), l.begin(), l.end());
@@ -2701,9 +2704,9 @@ Session::remove_last_capture ()
}
int
-Session::remove_region_from_region_list (Region& r)
+Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
{
- remove_region (&r);
+ remove_region (r);
return 0;
}
@@ -2721,7 +2724,7 @@ Session::add_audio_source (AudioSource* source)
audio_sources.insert (entry);
}
- source->GoingAway.connect (mem_fun (this, &Session::remove_source));
+ source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), source));
set_dirty();
SourceAdded (source); /* EMIT SIGNAL */
@@ -3055,7 +3058,7 @@ Session::add_playlist (Playlist* playlist)
playlists.insert (playlists.begin(), playlist);
// playlist->ref();
playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
- playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
+ playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
}
}
@@ -3126,7 +3129,7 @@ Session::remove_playlist (Playlist* playlist)
}
void
-Session::set_audition (AudioRegion* r)
+Session::set_audition (boost::shared_ptr<AudioRegion> r)
{
pending_audition_region = r;
post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
@@ -3136,12 +3139,12 @@ Session::set_audition (AudioRegion* r)
void
Session::non_realtime_set_audition ()
{
- if (pending_audition_region == (AudioRegion*) 0xfeedface) {
+ if (pending_audition_region.get() == (AudioRegion*) 0xfeedface) {
auditioner->audition_current_playlist ();
} else if (pending_audition_region) {
- auditioner->audition_region (*pending_audition_region);
+ auditioner->audition_region (pending_audition_region);
}
- pending_audition_region = 0;
+ pending_audition_region.reset ((AudioRegion*) 0);
AuditionActive (true); /* EMIT SIGNAL */
}
@@ -3154,12 +3157,12 @@ Session::audition_playlist ()
}
void
-Session::audition_region (Region& r)
+Session::audition_region (boost::shared_ptr<Region> r)
{
- AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
if (ar) {
Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
- ev->set_ptr (ar);
+ // ev->set_ptr (ar); // AUDFIX
queue_event (ev);
}
}
@@ -3336,7 +3339,7 @@ Session::add_redirect (Redirect* redirect)
/*NOTREACHED*/
}
- redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
+ redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
set_dirty();
}
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
index dbe0ffccdd..b54e5c8398 100644
--- a/libs/ardour/session_command.cc
+++ b/libs/ardour/session_command.cc
@@ -13,9 +13,7 @@ using namespace PBD;
namespace ARDOUR {
-static map<PBD::ID, Stateful*> registry;
-
-void Session::register_with_memento_command_factory(PBD::ID id, Stateful *ptr)
+void Session::register_with_memento_command_factory(PBD::ID id, StatefulDestructible *ptr)
{
registry[id] = ptr;
}
@@ -90,7 +88,8 @@ Command *Session::memento_command_factory(XMLNode *n)
}
// For Editor and AutomationLine which are off-limits here
else if (registry.count(id))
- return new MementoCommand<Stateful>(*registry[id], before, after);
+ return new MementoCommand<StatefulDestructible>(*registry[id], before, after);
+
/* we failed */
error << _("could not reconstitute MementoCommand from XMLNode. id=") << id.to_s() << endmsg;
diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc
index e918e0383f..1e7a2a41ba 100644
--- a/libs/ardour/session_events.cc
+++ b/libs/ardour/session_events.cc
@@ -401,7 +401,7 @@ Session::process_event (Event* ev)
break;
case Event::Audition:
- set_audition (static_cast<AudioRegion*> (ev->ptr));
+ // set_audition (static_cast<AudioRegion*> (ev->ptr)); AUDFIX
break;
case Event::InputConfigurationChange:
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 6f2ad965b4..3df43157ea 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -81,6 +81,7 @@
#include <ardour/audioregion.h>
#include <ardour/crossfade.h>
#include <ardour/control_protocol_manager.h>
+#include <ardour/region_factory.h>
#include "i18n.h"
#include <locale.h>
@@ -175,7 +176,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
g_atomic_int_set (&_capture_load, 100);
g_atomic_int_set (&_playback_load_min, 100);
g_atomic_int_set (&_capture_load_min, 100);
- pending_audition_region = 0;
_edit_mode = Slide;
pending_edit_mode = _edit_mode;
_play_range = false;
@@ -190,6 +190,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
layer_model = MoveAddHigher;
xfade_model = ShortCrossfade;
destructive_index = 0;
+ current_trans = 0;
AudioDiskstream::allocate_working_buffers();
@@ -260,7 +261,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
/* These are all static "per-class" signals */
- Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
+ RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
@@ -1751,7 +1752,7 @@ Session::load_regions (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- AudioRegion* region;
+ boost::shared_ptr<AudioRegion> region;
nlist = node.children();
@@ -1762,21 +1763,22 @@ Session::load_regions (const XMLNode& node)
error << _("Session: cannot create Region from XML description.") << endmsg;
}
}
+
return 0;
}
-AudioRegion *
+boost::shared_ptr<AudioRegion>
Session::XMLRegionFactory (const XMLNode& node, bool full)
{
const XMLProperty* prop;
Source* source;
AudioSource* as;
- AudioRegion::SourceList sources;
+ SourceList sources;
uint32_t nchans = 1;
char buf[128];
if (node.name() != X_("Region")) {
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
if ((prop = node.property (X_("channels"))) != 0) {
@@ -1787,7 +1789,7 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
if ((prop = node.property (X_("source-0"))) == 0) {
if ((prop = node.property ("source")) == 0) {
error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
}
@@ -1795,13 +1797,13 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
if ((source = source_by_id (s_id)) == 0) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
as = dynamic_cast<AudioSource*>(source);
if (!as) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
sources.push_back (as);
@@ -1816,24 +1818,26 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
if ((source = source_by_id (id2)) == 0) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
as = dynamic_cast<AudioSource*>(source);
if (!as) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
sources.push_back (as);
}
}
try {
- return new AudioRegion (sources, node);
+ boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
+ return region;
+
}
catch (failed_constructor& err) {
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
}
@@ -2574,8 +2578,8 @@ Session::set_meter_falloff (float val)
void
Session::begin_reversible_command (string name)
{
- current_trans.clear ();
- current_trans.set_name (name);
+ current_trans = new UndoTransaction;
+ current_trans->set_name (name);
}
void
@@ -2584,11 +2588,11 @@ Session::commit_reversible_command (Command *cmd)
struct timeval now;
if (cmd) {
- current_trans.add_command (cmd);
+ current_trans->add_command (cmd);
}
gettimeofday (&now, 0);
- current_trans.set_timestamp (now);
+ current_trans->set_timestamp (now);
history.add (current_trans);
}
@@ -2976,7 +2980,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
AudioRegionList::iterator tmp;
- AudioRegion* ar;
+ boost::shared_ptr<AudioRegion> ar;
tmp = r;
++tmp;
@@ -3360,15 +3364,15 @@ Session::restore_history (string snapshot_name)
it++)
{
XMLNode *t = *it;
- UndoTransaction ut;
+ UndoTransaction* ut = new UndoTransaction ();
struct timeval tv;
- ut.set_name(t->property("name")->value());
+ ut->set_name(t->property("name")->value());
stringstream ss(t->property("tv_sec")->value());
ss >> tv.tv_sec;
ss.str(t->property("tv_usec")->value());
ss >> tv.tv_usec;
- ut.set_timestamp(tv);
+ ut->set_timestamp(tv);
for (XMLNodeConstIterator child_it = t->children().begin();
child_it != t->children().end();
@@ -3382,7 +3386,7 @@ Session::restore_history (string snapshot_name)
{
c = memento_command_factory(n);
if (c)
- ut.add_command(c);
+ ut->add_command(c);
}
else
{
diff --git a/libs/ardour/session_timefx.cc b/libs/ardour/session_timefx.cc
index 45733c75ae..2b6b45dad0 100644
--- a/libs/ardour/session_timefx.cc
+++ b/libs/ardour/session_timefx.cc
@@ -28,6 +28,7 @@
#include <ardour/session.h>
#include <ardour/audioregion.h>
#include <ardour/sndfilesource.h>
+#include <ardour/region_factory.h>
#include "i18n.h"
@@ -36,12 +37,12 @@ using namespace ARDOUR;
using namespace PBD;
using namespace soundtouch;
-AudioRegion*
+boost::shared_ptr<AudioRegion>
Session::tempoize_region (TimeStretchRequest& tsr)
{
- AudioRegion::SourceList sources;
- AudioRegion::SourceList::iterator it;
- AudioRegion* r = 0;
+ SourceList sources;
+ SourceList::iterator it;
+ boost::shared_ptr<AudioRegion> r;
SoundTouch st;
string region_name;
string ident = X_("-TIMEFX-");
@@ -160,10 +161,9 @@ Session::tempoize_region (TimeStretchRequest& tsr)
region_name = tsr.region->name() + X_(".t");
- r = new AudioRegion (sources, 0, sources.front()->length(), region_name,
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile));
-
-
+ r = (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, 0, sources.front()->length(), region_name,
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile))));
+
out:
if (sources.size()) {
@@ -172,7 +172,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
for deletion.
*/
- if ((r == 0 || !tsr.running)) {
+ if ((!r || !tsr.running)) {
for (it = sources.begin(); it != sources.end(); ++it) {
(*it)->mark_for_remove ();
delete *it;
@@ -183,10 +183,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
/* if the process was cancelled, delete the region */
if (!tsr.running) {
- if (r) {
- delete r;
- r = 0;
- }
+ r.reset ();
}
return r;
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index b487d4e3a3..f67d61472f 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -235,7 +235,8 @@ SndFileSource::open ()
_length = _info.frames;
- _broadcast_info = (SF_BROADCAST_INFO*) calloc (1, sizeof (SF_BROADCAST_INFO));
+ _broadcast_info = new SF_BROADCAST_INFO;
+ memset (_broadcast_info, 0, sizeof (*_broadcast_info));
/* lookup broadcast info */
@@ -244,7 +245,7 @@ SndFileSource::open ()
/* if the file has data but no broadcast info, then clearly, there is no broadcast info */
if (_length) {
- free (_broadcast_info);
+ delete _broadcast_info;
_broadcast_info = 0;
_flags = Flag (_flags & ~Broadcast);
}
@@ -269,7 +270,7 @@ SndFileSource::open ()
SndFileSource::~SndFileSource ()
{
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
if (sf) {
sf_close (sf);
@@ -485,7 +486,7 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
_flags = Flag (_flags & ~Broadcast);
- free (_broadcast_info);
+ delete _broadcast_info;
_broadcast_info = 0;
return -1;
}
@@ -506,7 +507,7 @@ SndFileSource::set_header_timeline_position ()
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
_flags = Flag (_flags & ~Broadcast);
- free (_broadcast_info);
+ delete _broadcast_info;
_broadcast_info = 0;
}
}
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index 4c09ba3440..dbb7547052 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -98,7 +98,7 @@ VSTPlugin::VSTPlugin (const VSTPlugin &other)
VSTPlugin::~VSTPlugin ()
{
deactivate ();
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
fst_close (_fst);
}
diff --git a/libs/pbd/pbd/command.h b/libs/pbd/pbd/command.h
index cd9bf0e08a..7c367e7462 100644
--- a/libs/pbd/pbd/command.h
+++ b/libs/pbd/pbd/command.h
@@ -22,8 +22,9 @@
#define __lib_pbd_command_h__
#include <pbd/stateful.h>
+#include <pbd/destructible.h>
-class Command : public Stateful
+class Command : public Stateful, public PBD::Destructible
{
public:
virtual ~Command() {}
diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h
index 3a72fc9841..f257e63233 100644
--- a/libs/pbd/pbd/memento_command.h
+++ b/libs/pbd/pbd/memento_command.h
@@ -21,6 +21,10 @@
#ifndef __lib_pbd_memento_command_h__
#define __lib_pbd_memento_command_h__
+#include <iostream>
+using std::cerr;
+using std::endl;
+
#include <pbd/command.h>
#include <pbd/xml++.h>
#include <sigc++/slot.h>
@@ -34,12 +38,22 @@ template <class obj_T>
class MementoCommand : public Command
{
public:
- MementoCommand(XMLNode &state);
- MementoCommand(obj_T &obj,
+ MementoCommand(obj_T &object,
XMLNode *before,
XMLNode *after
)
- : obj(obj), before(before), after(after) {}
+ : obj(object), before(before), after(after) {
+ obj.GoingAway.connect (sigc::mem_fun (*this, &MementoCommand<obj_T>::object_death));
+ }
+ ~MementoCommand () {
+ GoingAway();
+ if (before) {
+ delete before;
+ }
+ if (after) {
+ delete after;
+ }
+ }
void operator() ()
{
if (after)
@@ -60,20 +74,27 @@ class MementoCommand : public Command
else
name = "MementoRedoCommand";
+
XMLNode *node = new XMLNode(name);
- node->add_property("obj_id", obj.id().to_s());
- node->add_property("type_name", typeid(obj).name());
- if (before)
- node->add_child_copy(*before);
- if (after)
- node->add_child_copy(*after);
+ node->add_property("obj_id", obj.id().to_s());
+ node->add_property("type_name", typeid(obj).name());
+
+ if (before)
+ node->add_child_copy(*before);
+ if (after)
+ node->add_child_copy(*after);
return *node;
}
+
protected:
obj_T &obj;
XMLNode *before, *after;
+
+ void object_death () {
+ delete this;
+ }
};
#endif // __lib_pbd_memento_h__
diff --git a/libs/pbd/pbd/statefuldestructible.h b/libs/pbd/pbd/statefuldestructible.h
new file mode 100644
index 0000000000..e78cc4bdaa
--- /dev/null
+++ b/libs/pbd/pbd/statefuldestructible.h
@@ -0,0 +1,13 @@
+#ifndef __pbd_stateful_destructible_h__
+#define __pbd_stateful_destructible_h__
+
+#include <pbd/stateful.h>
+#include <pbd/destructible.h>
+
+namespace PBD {
+class StatefulDestructible : public Stateful, public Destructible
+{
+};
+}
+
+#endif /* __pbd_stateful_destructible_h__ */
diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h
index 724e86aaa0..eecd8ae49d 100644
--- a/libs/pbd/pbd/undo.h
+++ b/libs/pbd/pbd/undo.h
@@ -29,9 +29,6 @@
#include <sys/time.h>
#include <pbd/command.h>
-using std::string;
-using std::list;
-
typedef sigc::slot<void> UndoAction;
class UndoTransaction : public Command
@@ -40,10 +37,11 @@ class UndoTransaction : public Command
UndoTransaction ();
UndoTransaction (const UndoTransaction&);
UndoTransaction& operator= (const UndoTransaction&);
+ ~UndoTransaction ();
void clear ();
- void add_command (Command *const);
+ void add_command (Command* const);
void operator() ();
void undo();
@@ -51,10 +49,10 @@ class UndoTransaction : public Command
XMLNode &get_state();
- void set_name (const string& str) {
+ void set_name (const std::string& str) {
_name = str;
}
- const string& name() const { return _name; }
+ const std::string& name() const { return _name; }
void set_timestamp (struct timeval &t) {
_timestamp = t;
@@ -65,26 +63,28 @@ class UndoTransaction : public Command
}
private:
- list<Command*> actions;
- struct timeval _timestamp;
- string _name;
+ std::list<Command*> actions;
+ struct timeval _timestamp;
+ std::string _name;
+ bool clearing;
+ void remove_command (Command* const);
};
class UndoHistory
{
public:
- UndoHistory() {}
+ UndoHistory();
~UndoHistory() {}
- void add (UndoTransaction ut);
+ void add (UndoTransaction* ut);
void undo (unsigned int n);
void redo (unsigned int n);
unsigned long undo_depth() const { return UndoList.size(); }
unsigned long redo_depth() const { return RedoList.size(); }
- string next_undo() const { return (UndoList.empty() ? string("") : UndoList.back().name()); }
- string next_redo() const { return (RedoList.empty() ? string("") : RedoList.back().name()); }
+ std::string next_undo() const { return (UndoList.empty() ? std::string("") : UndoList.back()->name()); }
+ std::string next_redo() const { return (RedoList.empty() ? std::string("") : RedoList.back()->name()); }
void clear ();
void clear_undo ();
@@ -92,9 +92,13 @@ class UndoHistory
XMLNode &get_state();
void save_state();
+
private:
- list<UndoTransaction> UndoList;
- list<UndoTransaction> RedoList;
+ bool clearing;
+ std::list<UndoTransaction*> UndoList;
+ std::list<UndoTransaction*> RedoList;
+
+ void remove (UndoTransaction*);
};
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index 6f421de84e..717c355bae 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -19,26 +19,36 @@
*/
#include <iostream>
+#include <string>
+#include <sstream>
#include <pbd/undo.h>
#include <pbd/xml++.h>
-#include <string>
-#include <sstream>
+
+#include <sigc++/bind.h>
using namespace std;
using namespace sigc;
UndoTransaction::UndoTransaction ()
{
+ clearing = false;
}
UndoTransaction::UndoTransaction (const UndoTransaction& rhs)
{
_name = rhs._name;
+ clearing = false;
clear ();
actions.insert(actions.end(),rhs.actions.begin(),rhs.actions.end());
}
+UndoTransaction::~UndoTransaction ()
+{
+ GoingAway ();
+ clear ();
+}
+
UndoTransaction&
UndoTransaction::operator= (const UndoTransaction& rhs)
{
@@ -52,13 +62,31 @@ UndoTransaction::operator= (const UndoTransaction& rhs)
void
UndoTransaction::add_command (Command *const action)
{
+ action->GoingAway.connect (bind (mem_fun (*this, &UndoTransaction::remove_command), action));
actions.push_back (action);
}
void
+UndoTransaction::remove_command (Command* const action)
+{
+ if (clearing) {
+ return;
+ }
+ actions.remove (action);
+ if (actions.empty()) {
+ delete this;
+ }
+}
+
+void
UndoTransaction::clear ()
{
+ clearing = true;
+ for (list<Command*>::iterator i = actions.begin(); i != actions.end(); ++i) {
+ delete *i;
+ }
actions.clear ();
+ clearing = false;
}
void
@@ -72,7 +100,6 @@ UndoTransaction::operator() ()
void
UndoTransaction::undo ()
{
- cerr << "Undo " << _name << endl;
for (list<Command*>::reverse_iterator i = actions.rbegin(); i != actions.rend(); ++i) {
(*i)->undo();
}
@@ -81,7 +108,6 @@ UndoTransaction::undo ()
void
UndoTransaction::redo ()
{
- cerr << "Redo " << _name << endl;
(*this)();
}
@@ -103,10 +129,29 @@ XMLNode &UndoTransaction::get_state()
return *node;
}
+UndoHistory::UndoHistory ()
+{
+ clearing = false;
+}
+
void
-UndoHistory::add (UndoTransaction ut)
+UndoHistory::add (UndoTransaction* const ut)
{
+ ut->GoingAway.connect (bind (mem_fun (*this, &UndoHistory::remove), ut));
UndoList.push_back (ut);
+
+ /* we are now owners of the transaction */
+}
+
+void
+UndoHistory::remove (UndoTransaction* const ut)
+{
+ if (clearing) {
+ return;
+ }
+
+ UndoList.remove (ut);
+ RedoList.remove (ut);
}
void
@@ -116,9 +161,9 @@ UndoHistory::undo (unsigned int n)
if (UndoList.size() == 0) {
return;
}
- UndoTransaction ut = UndoList.back ();
+ UndoTransaction* ut = UndoList.back ();
UndoList.pop_back ();
- ut.undo ();
+ ut->undo ();
RedoList.push_back (ut);
}
}
@@ -130,9 +175,9 @@ UndoHistory::redo (unsigned int n)
if (RedoList.size() == 0) {
return;
}
- UndoTransaction ut = RedoList.back ();
+ UndoTransaction* ut = RedoList.back ();
RedoList.pop_back ();
- ut.redo ();
+ ut->redo ();
UndoList.push_back (ut);
}
}
@@ -140,29 +185,34 @@ UndoHistory::redo (unsigned int n)
void
UndoHistory::clear_redo ()
{
+ clearing = true;
RedoList.clear ();
+ clearing = false;
}
void
UndoHistory::clear_undo ()
{
+ clearing = true;
UndoList.clear ();
+ clearing = false;
}
void
UndoHistory::clear ()
{
- RedoList.clear ();
- UndoList.clear ();
+ clear_undo ();
+ clear_redo ();
}
XMLNode & UndoHistory::get_state()
{
XMLNode *node = new XMLNode ("UndoHistory");
- list<UndoTransaction>::iterator it;
- for (it=UndoList.begin(); it != UndoList.end(); it++)
- node->add_child_nocopy(it->get_state());
+ list<UndoTransaction*>::iterator it;
+ for (it = UndoList.begin(); it != UndoList.end(); it++) {
+ node->add_child_nocopy((*it)->get_state());
+ }
return *node;
}