diff --git a/CHANGELOG.md b/CHANGELOG.md index f8ccd03..100277a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). resized ([#145][i145]) ### Fixed +- Potential ID collisions when clearing unit or pasteing instruments - Assign new IDs to loaded instruments, and fix ID collisions in case they somehow still appear ([#146][i146]) - In x86 templates, do not optimize away phase modulations when unisons are used diff --git a/tracker/action.go b/tracker/action.go index a1c2570..faa6f5b 100644 --- a/tracker/action.go +++ b/tracker/action.go @@ -154,6 +154,7 @@ func (m *Model) ClearUnit() Action { defer (*Model)(m).change("DeleteUnitAction", PatchChange, MajorChange)() m.d.UnitIndex = intMax(intMin(m.d.UnitIndex, len(m.d.Song.Patch[m.d.InstrIndex].Units)-1), 0) m.d.Song.Patch[m.d.InstrIndex].Units[m.d.UnitIndex] = sointu.Unit{} + m.d.Song.Patch[m.d.InstrIndex].Units[m.d.UnitIndex].ID = m.maxID() + 1 }, allowed: func() bool { return m.d.InstrIndex >= 0 && diff --git a/tracker/list.go b/tracker/list.go index 644ff21..e765946 100644 --- a/tracker/list.go +++ b/tracker/list.go @@ -269,11 +269,13 @@ func (v *Instruments) unmarshal(data []byte) (from, to int, err error) { if v.d.Song.Patch.NumVoices()+newInstr.Patch.NumVoices() > vm.MAX_VOICES { return 0, 0, fmt.Errorf("InstrumentListView.unmarshal: too many voices: %d", v.d.Song.Patch.NumVoices()+newInstr.Patch.NumVoices()) } - patch := append(v.d.Song.Patch, make([]sointu.Instrument, len(newInstr.Patch))...) + v.d.Song.Patch = append(v.d.Song.Patch, make([]sointu.Instrument, len(newInstr.Patch))...) sel := v.Selected() - copy(patch[sel+len(newInstr.Patch):], patch[sel:]) - copy(patch[sel:sel+len(newInstr.Patch)], newInstr.Patch) - v.d.Song.Patch = patch + copy(v.d.Song.Patch[sel+len(newInstr.Patch):], v.d.Song.Patch[sel:]) + for i := 0; i < len(newInstr.Patch); i++ { + (*Model)(v).assignUnitIDs(newInstr.Patch[i].Units) + v.d.Song.Patch[sel+i] = newInstr.Patch[i] + } from = sel to = sel + len(newInstr.Patch) - 1 return diff --git a/tracker/model.go b/tracker/model.go index f83e958..337f934 100644 --- a/tracker/model.go +++ b/tracker/model.go @@ -408,6 +408,18 @@ func (m *Model) send(message interface{}) { m.modelMessages <- message } +func (m *Model) maxID() int { + maxID := 0 + for _, instr := range m.d.Song.Patch { + for _, unit := range instr.Units { + if unit.ID > maxID { + maxID = unit.ID + } + } + } + return maxID +} + func (m *Model) assignUnitIDs(units []sointu.Unit) { maxId := 0 usedIds := make(map[int]bool)