fix ever increasing MIDI event IDs
Iterating over a const Midi-Sequence calls Evoral::Sequence::set_event(), which in turn used Evoral::Event::operator=() which always created a new event-ID (create copy of the event). Issues fixed: - Saving *unmodified* MIDI produced new event-IDs on every save; files changed with every save. - greetings to Deva. - all [GUI] operations that use IDs to refer to notes e.g. undo. invalid undo-history. Also clarify assignment operator name. Prefer explicit assign() over =.
This commit is contained in:
parent
c12e8cc47c
commit
8b2fb88f15
@ -61,7 +61,7 @@ public:
|
|||||||
|
|
||||||
~Event();
|
~Event();
|
||||||
|
|
||||||
const Event& operator=(const Event& copy);
|
void assign (const Event& other);
|
||||||
|
|
||||||
void set(const uint8_t* buf, uint32_t size, Time t);
|
void set(const uint8_t* buf, uint32_t size, Time t);
|
||||||
|
|
||||||
|
@ -107,30 +107,29 @@ Event<Timestamp>::~Event() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Timestamp>
|
template<typename Timestamp>
|
||||||
const Event<Timestamp>&
|
void
|
||||||
Event<Timestamp>::operator=(const Event& copy)
|
Event<Timestamp>::assign(const Event& other)
|
||||||
{
|
{
|
||||||
_id = next_event_id ();
|
_id = other._id;
|
||||||
_type = copy._type;
|
_type = other._type;
|
||||||
_original_time = copy._original_time;
|
_original_time = other._original_time;
|
||||||
_nominal_time = copy._nominal_time;
|
_nominal_time = other._nominal_time;
|
||||||
_owns_buf = copy._owns_buf;
|
_owns_buf = other._owns_buf;
|
||||||
if (_owns_buf) {
|
if (_owns_buf) {
|
||||||
if (copy._buf) {
|
if (other._buf) {
|
||||||
if (copy._size > _size) {
|
if (other._size > _size) {
|
||||||
_buf = (uint8_t*)::realloc(_buf, copy._size);
|
_buf = (uint8_t*)::realloc(_buf, other._size);
|
||||||
}
|
}
|
||||||
memcpy(_buf, copy._buf, copy._size);
|
memcpy(_buf, other._buf, other._size);
|
||||||
} else {
|
} else {
|
||||||
free(_buf);
|
free(_buf);
|
||||||
_buf = NULL;
|
_buf = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_buf = copy._buf;
|
_buf = other._buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
_size = copy._size;
|
_size = other._size;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Timestamp>
|
template<typename Timestamp>
|
||||||
|
@ -284,18 +284,18 @@ Sequence<Time>::const_iterator::set_event()
|
|||||||
switch (_type) {
|
switch (_type) {
|
||||||
case NOTE_ON:
|
case NOTE_ON:
|
||||||
DEBUG_TRACE(DEBUG::Sequence, "iterator = note on\n");
|
DEBUG_TRACE(DEBUG::Sequence, "iterator = note on\n");
|
||||||
*_event = (*_note_iter)->on_event();
|
_event->assign ((*_note_iter)->on_event());
|
||||||
_active_notes.push(*_note_iter);
|
_active_notes.push(*_note_iter);
|
||||||
break;
|
break;
|
||||||
case NOTE_OFF:
|
case NOTE_OFF:
|
||||||
DEBUG_TRACE(DEBUG::Sequence, "iterator = note off\n");
|
DEBUG_TRACE(DEBUG::Sequence, "iterator = note off\n");
|
||||||
assert(!_active_notes.empty());
|
assert(!_active_notes.empty());
|
||||||
*_event = _active_notes.top()->off_event();
|
_event->assign (_active_notes.top()->off_event());
|
||||||
// We don't pop the active note until we increment past it
|
// We don't pop the active note until we increment past it
|
||||||
break;
|
break;
|
||||||
case SYSEX:
|
case SYSEX:
|
||||||
DEBUG_TRACE(DEBUG::Sequence, "iterator = sysex\n");
|
DEBUG_TRACE(DEBUG::Sequence, "iterator = sysex\n");
|
||||||
*_event = *(*_sysex_iter);
|
_event->assign (*(*_sysex_iter));
|
||||||
break;
|
break;
|
||||||
case CONTROL:
|
case CONTROL:
|
||||||
DEBUG_TRACE(DEBUG::Sequence, "iterator = control\n");
|
DEBUG_TRACE(DEBUG::Sequence, "iterator = control\n");
|
||||||
@ -303,7 +303,7 @@ Sequence<Time>::const_iterator::set_event()
|
|||||||
break;
|
break;
|
||||||
case PATCH_CHANGE:
|
case PATCH_CHANGE:
|
||||||
DEBUG_TRACE(DEBUG::Sequence, "iterator = program change\n");
|
DEBUG_TRACE(DEBUG::Sequence, "iterator = program change\n");
|
||||||
*_event = (*_patch_change_iter)->message (_active_patch_change_message);
|
_event->assign ((*_patch_change_iter)->message (_active_patch_change_message));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_is_end = true;
|
_is_end = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user