summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-12-09 21:34:31 +0000
committerCarl Hetherington <carl@carlh.net>2010-12-09 21:34:31 +0000
commit7d4e03e28e58a9315f163738f35559f57b099d37 (patch)
tree37b39ea5e40835a918a77845b01fb4ab1515ba66
parentebf3762fa91d911af411f1b5c68e3c67f2c47170 (diff)
Use a weak_ptr rather than a bald pointer for _midi_source in MidiModel.
git-svn-id: svn://localhost/ardour2/branches/3.0@8228 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/ardour/midi_model.h8
-rw-r--r--libs/ardour/ardour/midi_source.h3
-rw-r--r--libs/ardour/midi_model.cc79
-rw-r--r--libs/ardour/smf_source.cc8
-rw-r--r--libs/ardour/source_factory.cc21
5 files changed, 76 insertions, 43 deletions
diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h
index e959535a36..27ffa4d8a2 100644
--- a/libs/ardour/ardour/midi_model.h
+++ b/libs/ardour/ardour/midi_model.h
@@ -51,7 +51,7 @@ class MidiModel : public AutomatableSequence<Evoral::MusicalTime> {
public:
typedef Evoral::MusicalTime TimeType;
- MidiModel(MidiSource* s);
+ MidiModel (boost::shared_ptr<MidiSource>);
NoteMode note_mode() const { return (percussive() ? Percussive : Sustained); }
void set_note_mode(NoteMode mode) { set_percussive(mode == Percussive); };
@@ -140,8 +140,8 @@ public:
PBD::Signal0<void> ContentsChanged;
- const MidiSource* midi_source() const { return _midi_source; }
- void set_midi_source (MidiSource *);
+ boost::shared_ptr<const MidiSource> midi_source ();
+ void set_midi_source (boost::shared_ptr<MidiSource>);
boost::shared_ptr<Evoral::Note<TimeType> > find_note (NotePtr);
boost::shared_ptr<Evoral::Note<TimeType> > find_note (gint note_id);
@@ -181,7 +181,7 @@ private:
PBD::ScopedConnectionList _midi_source_connections;
// We cannot use a boost::shared_ptr here to avoid a retain cycle
- MidiSource* _midi_source;
+ boost::weak_ptr<MidiSource> _midi_source;
InsertMergePolicy _insert_merge_policy;
};
diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h
index e40ccff291..33a0c3c1fa 100644
--- a/libs/ardour/ardour/midi_source.h
+++ b/libs/ardour/ardour/midi_source.h
@@ -23,6 +23,7 @@
#include <string>
#include <time.h>
#include <glibmm/thread.h>
+#include <boost/enable_shared_from_this.hpp>
#include "pbd/stateful.h"
#include "pbd/xml++.h"
#include "evoral/Sequence.hpp"
@@ -38,7 +39,7 @@ class MidiModel;
template<typename T> class MidiRingBuffer;
/** Source for MIDI data */
-class MidiSource : virtual public Source
+class MidiSource : virtual public Source, public boost::enable_shared_from_this<MidiSource>
{
public:
typedef double TimeType;
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc
index 5f6b07c67d..8fbfde0ee7 100644
--- a/libs/ardour/midi_model.cc
+++ b/libs/ardour/midi_model.cc
@@ -38,9 +38,8 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-MidiModel::MidiModel(MidiSource* s)
+MidiModel::MidiModel (boost::shared_ptr<MidiSource> s)
: AutomatableSequence<TimeType>(s->session())
- , _midi_source (0)
{
set_midi_source (s);
}
@@ -54,7 +53,10 @@ MidiModel::MidiModel(MidiSource* s)
MidiModel::DiffCommand*
MidiModel::new_diff_command(const string name)
{
- DiffCommand* cmd = new DiffCommand(_midi_source->model(), name);
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
+ DiffCommand* cmd = new DiffCommand (ms->model(), name);
return cmd;
}
@@ -696,8 +698,11 @@ MidiModel::write_to (boost::shared_ptr<MidiSource> source)
const bool old_percussive = percussive();
set_percussive(false);
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
source->drop_model();
- source->mark_streaming_midi_write_started(note_mode(), _midi_source->timeline_position());
+ source->mark_streaming_midi_write_started (note_mode(), ms->timeline_position ());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) {
source->append_event_unlocked_beats(*i);
@@ -724,14 +729,17 @@ MidiModel::sync_to_source ()
const bool old_percussive = percussive();
set_percussive(false);
- _midi_source->mark_streaming_midi_write_started(note_mode(), _midi_source->timeline_position());
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
+ ms->mark_streaming_midi_write_started (note_mode(), ms->timeline_position());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) {
- _midi_source->append_event_unlocked_beats(*i);
+ ms->append_event_unlocked_beats(*i);
}
set_percussive (old_percussive);
- _midi_source->mark_streaming_write_completed ();
+ ms->mark_streaming_write_completed ();
set_edited (false);
@@ -755,8 +763,11 @@ MidiModel::write_section_to (boost::shared_ptr<MidiSource> source, Evoral::Music
const bool old_percussive = percussive();
set_percussive(false);
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
source->drop_model();
- source->mark_streaming_midi_write_started(note_mode(), _midi_source->timeline_position());
+ source->mark_streaming_midi_write_started (note_mode(), ms->timeline_position());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) {
const Evoral::Event<Evoral::MusicalTime>& ev (*i);
@@ -869,8 +880,11 @@ MidiModel::find_note (gint note_id)
MidiModel::WriteLock
MidiModel::edit_lock()
{
- Glib::Mutex::Lock* source_lock = new Glib::Mutex::Lock(_midi_source->mutex());
- _midi_source->invalidate(); // Release cached iterator's read lock on model
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
+ Glib::Mutex::Lock* source_lock = new Glib::Mutex::Lock (ms->mutex());
+ ms->invalidate(); // Release cached iterator's read lock on model
return WriteLock(new WriteLockImpl(source_lock, _lock, _control_lock));
}
@@ -880,7 +894,10 @@ MidiModel::edit_lock()
MidiModel::WriteLock
MidiModel::write_lock()
{
- assert(!_midi_source->mutex().trylock());
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
+ assert (!ms->mutex().trylock ());
return WriteLock(new WriteLockImpl(NULL, _lock, _control_lock));
}
@@ -1081,25 +1098,30 @@ MidiModel::insert_merge_policy () const
{
/* XXX ultimately this should be a per-track or even per-model policy */
- return _midi_source->session().config.get_insert_merge_policy();
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
+ return ms->session().config.get_insert_merge_policy ();
}
void
-MidiModel::set_midi_source (MidiSource* s)
+MidiModel::set_midi_source (boost::shared_ptr<MidiSource> s)
{
- if (_midi_source) {
- _midi_source->invalidate ();
+ boost::shared_ptr<MidiSource> old = _midi_source.lock ();
+
+ if (old) {
+ old->invalidate ();
}
_midi_source_connections.drop_connections ();
_midi_source = s;
- _midi_source->InterpolationChanged.connect_same_thread (
+ s->InterpolationChanged.connect_same_thread (
_midi_source_connections, boost::bind (&MidiModel::source_interpolation_changed, this, _1, _2)
);
- _midi_source->AutomationStateChanged.connect_same_thread (
+ s->AutomationStateChanged.connect_same_thread (
_midi_source_connections, boost::bind (&MidiModel::source_automation_state_changed, this, _1, _2)
);
}
@@ -1124,7 +1146,10 @@ MidiModel::source_interpolation_changed (Evoral::Parameter p, Evoral::ControlLis
void
MidiModel::control_list_interpolation_changed (Evoral::Parameter p, Evoral::ControlList::InterpolationStyle s)
{
- _midi_source->set_interpolation_of (p, s);
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
+ ms->set_interpolation_of (p, s);
}
void
@@ -1138,7 +1163,10 @@ MidiModel::source_automation_state_changed (Evoral::Parameter p, AutoState s)
void
MidiModel::automation_list_automation_state_changed (Evoral::Parameter p, AutoState s)
{
- _midi_source->set_automation_state_of (p, s);
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
+
+ ms->set_automation_state_of (p, s);
}
boost::shared_ptr<Evoral::Control>
@@ -1150,14 +1178,21 @@ MidiModel::control_factory (Evoral::Parameter const & p)
automation state from our source.
*/
- assert (_midi_source);
+ boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
+ assert (ms);
- c->list()->set_interpolation (_midi_source->interpolation_of (p));
+ c->list()->set_interpolation (ms->interpolation_of (p));
boost::shared_ptr<AutomationList> al = boost::dynamic_pointer_cast<AutomationList> (c->list ());
assert (al);
- al->set_automation_state (_midi_source->automation_state_of (p));
+ al->set_automation_state (ms->automation_state_of (p));
return c;
}
+
+boost::shared_ptr<const MidiSource>
+MidiModel::midi_source ()
+{
+ return _midi_source.lock ();
+}
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 4e939a3762..78c3e55811 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -69,8 +69,6 @@ SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
if (create(path)) {
throw failed_constructor ();
}
-
- load_model(true, true); // FIXME
}
/** Constructor used for existing internal-to-session files. */
@@ -94,8 +92,6 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist)
if (open(_path)) {
throw failed_constructor ();
}
-
- load_model(true, true); // FIXME
}
SMFSource::~SMFSource ()
@@ -442,8 +438,8 @@ SMFSource::load_model (bool lock, bool force_reload)
return;
}
- if (! _model) {
- _model = boost::shared_ptr<MidiModel>(new MidiModel(this));
+ if (!_model) {
+ _model = boost::shared_ptr<MidiModel> (new MidiModel (shared_from_this ()));
} else {
_model->clear();
}
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index f886f952bd..b7c4a8ff56 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -178,12 +178,12 @@ SourceFactory::create (Session& s, const XMLNode& node, bool defer_peaks)
}
} else if (type == DataType::MIDI) {
- Source* src = new SMFSource (s, node);
+ boost::shared_ptr<SMFSource> src (new SMFSource (s, node));
+ src->load_model (true, true);
// boost_debug_shared_ptr_mark_interesting (src, "Source");
- boost::shared_ptr<Source> ret (src);
- ret->check_for_analysis_data_on_disk ();
- SourceCreated (ret);
- return ret;
+ src->check_for_analysis_data_on_disk ();
+ SourceCreated (src);
+ return src;
}
return boost::shared_ptr<Source>();
@@ -240,7 +240,8 @@ SourceFactory::createReadable (DataType type, Session& s, const string& path,
} else if (type == DataType::MIDI) {
- Source* src = new SMFSource (s, path, SMFSource::Flag(0));
+ SMFSource* src = new SMFSource (s, path, SMFSource::Flag(0));
+ src->load_model (true, true);
// boost_debug_shared_ptr_mark_interesting (src, "Source");
boost::shared_ptr<Source> ret (src);
@@ -285,16 +286,16 @@ SourceFactory::createWritable (DataType type, Session& s, const std::string& pat
} else if (type == DataType::MIDI) {
// XXX writable flags should belong to MidiSource too
- Source* src = new SMFSource (s, path, SndFileSource::default_writable_flags);
+ boost::shared_ptr<SMFSource> src (new SMFSource (s, path, SndFileSource::default_writable_flags));
+ src->load_model (true, true);
// boost_debug_shared_ptr_mark_interesting (src, "Source");
- boost::shared_ptr<Source> ret (src);
// no analysis data - this is a new file
if (announce) {
- SourceCreated (ret);
+ SourceCreated (src);
}
- return ret;
+ return src;
}