From 74972b5ff4b011dc4761766a1dfcac82fda5c00b Mon Sep 17 00:00:00 2001 From: "5684185+vsariola@users.noreply.github.com" <5684185+vsariola@users.noreply.github.com> Date: Sat, 7 Sep 2024 15:20:12 +0300 Subject: [PATCH] fix(tracker): ID collisions in ClearUnit and Instruments.unmarshal --- CHANGELOG.md | 1 + tracker/action.go | 1 + tracker/list.go | 10 ++++++---- tracker/model.go | 12 ++++++++++++ 4 files changed, 20 insertions(+), 4 deletions(-) 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)