fix ever increasing MIDI event IDs
authorRobin Gareus <robin@gareus.org>
Fri, 18 Sep 2015 15:34:12 +0000 (17:34 +0200)
committerRobin Gareus <robin@gareus.org>
Fri, 18 Sep 2015 15:36:15 +0000 (17:36 +0200)
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 =.

libs/evoral/evoral/Event.hpp
libs/evoral/src/Event.cpp
libs/evoral/src/Sequence.cpp

index ec92d575d0958b0cf18328b80207d60db6af21ba..2a6810a3b46e11365cc99919325320cbd19e4544 100644 (file)
@@ -61,7 +61,7 @@ public:
 
         ~Event();
 
-       const Event& operator=(const Event& copy);
+       void assign (const Event& other);
 
        void set(const uint8_t* buf, uint32_t size, Time t);
 
index 45935ccf8d255998cfa191f811bc30aea1574052..680f488596b333c6d1e1302f2d13dcaf1712ab33 100644 (file)
@@ -107,30 +107,29 @@ Event<Timestamp>::~Event() {
 }
 
 template<typename Timestamp>
-const Event<Timestamp>&
-Event<Timestamp>::operator=(const Event& copy)
+void
+Event<Timestamp>::assign(const Event& other)
 {
-       _id = next_event_id ();
-       _type = copy._type;
-       _original_time = copy._original_time;
-       _nominal_time = copy._nominal_time;
-       _owns_buf = copy._owns_buf;
+       _id = other._id;
+       _type = other._type;
+       _original_time = other._original_time;
+       _nominal_time = other._nominal_time;
+       _owns_buf = other._owns_buf;
        if (_owns_buf) {
-               if (copy._buf) {
-                       if (copy._size > _size) {
-                               _buf = (uint8_t*)::realloc(_buf, copy._size);
+               if (other._buf) {
+                       if (other._size > _size) {
+                               _buf = (uint8_t*)::realloc(_buf, other._size);
                        }
-                       memcpy(_buf, copy._buf, copy._size);
+                       memcpy(_buf, other._buf, other._size);
                } else {
                        free(_buf);
                        _buf = NULL;
                }
        } else {
-               _buf = copy._buf;
+               _buf = other._buf;
        }
 
-       _size = copy._size;
-       return *this;
+       _size = other._size;
 }
 
 template<typename Timestamp>
index e153cea9b4ab7c617096c94b2efce645470008ca..526256bf5e274be9b197329420b3f0454a802fcf 100644 (file)
@@ -284,18 +284,18 @@ Sequence<Time>::const_iterator::set_event()
        switch (_type) {
        case NOTE_ON:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = note on\n");
-               *_event = (*_note_iter)->on_event();
+               _event->assign ((*_note_iter)->on_event());
                _active_notes.push(*_note_iter);
                break;
        case NOTE_OFF:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = note off\n");
                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
                break;
        case SYSEX:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = sysex\n");
-               *_event = *(*_sysex_iter);
+               _event->assign (*(*_sysex_iter));
                break;
        case CONTROL:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = control\n");
@@ -303,7 +303,7 @@ Sequence<Time>::const_iterator::set_event()
                break;
        case PATCH_CHANGE:
                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;
        default:
                _is_end = true;