// This could be made much faster by using a priority_queue for added and
// removed notes (or sort here), and doing a single iteration over _model
- Glib::Mutex::Lock lm (_model->_midi_source->mutex());
- _model->_midi_source->invalidate(); // release model read lock
- _model->write_lock();
+ MidiModel::WriteLock lock(_model->edit_lock());
for (NoteList::iterator i = _added_notes.begin(); i != _added_notes.end(); ++i) {
_model->add_note_unlocked(*i);
_model->remove_note_unlocked(*i);
}
- _model->write_unlock();
+ lock.reset();
_model->ContentsChanged(); /* EMIT SIGNAL */
}
// This could be made much faster by using a priority_queue for added and
// removed notes (or sort here), and doing a single iteration over _model
- Glib::Mutex::Lock lm (_model->_midi_source->mutex());
- _model->_midi_source->invalidate(); // release model read lock
- _model->write_lock();
+ MidiModel::WriteLock lock(_model->edit_lock());;
for (NoteList::iterator i = _added_notes.begin(); i != _added_notes.end(); ++i) {
_model->remove_note_unlocked(*i);
_model->add_note_unlocked(*i);
}
- _model->write_unlock();
+ lock.reset();
_model->ContentsChanged(); /* EMIT SIGNAL */
}
if (added_notes) {
XMLNodeList notes = added_notes->children();
transform(notes.begin(), notes.end(), back_inserter(_added_notes),
- sigc::mem_fun(*this, &DeltaCommand::unmarshal_note));
+ boost::bind (&DeltaCommand::unmarshal_note, this, _1));
}
_removed_notes.clear();
if (removed_notes) {
XMLNodeList notes = removed_notes->children();
transform(notes.begin(), notes.end(), back_inserter(_removed_notes),
- sigc::mem_fun(*this, &DeltaCommand::unmarshal_note));
+ boost::bind (&DeltaCommand::unmarshal_note, this, _1));
}
return 0;
delta_command->add_property("midi-source", _model->midi_source()->id().to_s());
XMLNode* added_notes = delta_command->add_child(ADDED_NOTES_ELEMENT);
- for_each(_added_notes.begin(), _added_notes.end(), sigc::compose(
- sigc::mem_fun(*added_notes, &XMLNode::add_child_nocopy),
- sigc::mem_fun(*this, &DeltaCommand::marshal_note)));
+ for_each(_added_notes.begin(), _added_notes.end(),
+ boost::bind(
+ boost::bind (&XMLNode::add_child_nocopy, *added_notes, _1),
+ boost::bind (&DeltaCommand::marshal_note, this, _1)));
XMLNode* removed_notes = delta_command->add_child(REMOVED_NOTES_ELEMENT);
- for_each(_removed_notes.begin(), _removed_notes.end(), sigc::compose(
- sigc::mem_fun(*removed_notes, &XMLNode::add_child_nocopy),
- sigc::mem_fun(*this, &DeltaCommand::marshal_note)));
+ for_each(_removed_notes.begin(), _removed_notes.end(),
+ boost::bind (
+ boost::bind (&XMLNode::add_child_nocopy, *removed_notes, _1),
+ boost::bind (&DeltaCommand::marshal_note, this, _1)));
return *delta_command;
}
MidiModel::DiffCommand::change(const boost::shared_ptr< Evoral::Note<TimeType> > note, Property prop,
uint8_t new_value)
{
- NotePropertyChange change;
+ NoteChange change;
change.note = note;
change.property = prop;
MidiModel::DiffCommand::change(const boost::shared_ptr< Evoral::Note<TimeType> > note, Property prop,
TimeType new_time)
{
- NotePropertyChange change;
+ NoteChange change;
change.note = note;
change.property = prop;
void
MidiModel::DiffCommand::operator()()
{
- Glib::Mutex::Lock lm (_model->_midi_source->mutex());
- _model->_midi_source->invalidate(); // release model read lock
- _model->write_lock();
+ MidiModel::WriteLock lock(_model->edit_lock());
for (ChangeList::iterator i = _changes.begin(); i != _changes.end(); ++i) {
Property prop = i->property;
}
}
- _model->write_unlock();
+ lock.reset();
_model->ContentsChanged(); /* EMIT SIGNAL */
}
void
MidiModel::DiffCommand::undo()
{
- Glib::Mutex::Lock lm (_model->_midi_source->mutex());
- _model->_midi_source->invalidate(); // release model read lock
- _model->write_lock();
+ MidiModel::WriteLock lock(_model->edit_lock());
for (ChangeList::iterator i = _changes.begin(); i != _changes.end(); ++i) {
Property prop = i->property;
}
}
- _model->write_unlock();
+ lock.reset();
_model->ContentsChanged(); /* EMIT SIGNAL */
}
XMLNode&
-MidiModel::DiffCommand::marshal_change(const NotePropertyChange& change)
+MidiModel::DiffCommand::marshal_change(const NoteChange& change)
{
XMLNode* xml_change = new XMLNode("change");
return *xml_change;
}
-MidiModel::DiffCommand::NotePropertyChange
+MidiModel::DiffCommand::NoteChange
MidiModel::DiffCommand::unmarshal_change(XMLNode *xml_change)
{
XMLProperty* prop;
- NotePropertyChange change;
+ NoteChange change;
unsigned int note;
unsigned int channel;
unsigned int velocity;
if (changed_notes) {
XMLNodeList notes = changed_notes->children();
-
transform (notes.begin(), notes.end(), back_inserter(_changes),
- sigc::mem_fun(*this, &DiffCommand::unmarshal_change));
+ boost::bind (&DiffCommand::unmarshal_change, this, _1));
+
}
return 0;
diff_command->add_property("midi-source", _model->midi_source()->id().to_s());
XMLNode* changes = diff_command->add_child(DIFF_NOTES_ELEMENT);
- for_each(_changes.begin(), _changes.end(), sigc::compose(
- sigc::mem_fun(*changes, &XMLNode::add_child_nocopy),
- sigc::mem_fun(*this, &DiffCommand::marshal_change)));
+ for_each(_changes.begin(), _changes.end(),
+ boost::bind (
+ boost::bind (&XMLNode::add_child_nocopy, *changes, _1),
+ boost::bind (&DiffCommand::marshal_change, this, _1)));
return *diff_command;
}
bool
MidiModel::write_to(boost::shared_ptr<MidiSource> source)
{
- read_lock();
+ ReadLock lock(read_lock());
const bool old_percussive = percussive();
set_percussive(false);
source->drop_model();
+ source->mark_streaming_midi_write_started(note_mode(), _midi_source->timeline_position());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(); i != end(); ++i) {
source->append_event_unlocked_beats(*i);
}
set_percussive(old_percussive);
+ source->mark_streaming_write_completed();
- read_unlock();
set_edited(false);
return true;
return boost::shared_ptr<Evoral::Note<TimeType> >();
}
+
+/** Lock and invalidate the source.
+ * This should be used by commands and editing things
+ */
+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
+ return WriteLock(new WriteLockImpl(source_lock, _lock, _control_lock));
+}
+
+/** Lock just the model, the source lock must already be held.
+ * This should only be called from libardour/evoral places
+ */
+MidiModel::WriteLock
+MidiModel::write_lock()
+{
+ assert(!_midi_source->mutex().trylock());
+ return WriteLock(new WriteLockImpl(NULL, _lock, _control_lock));
+}