Update: I’ve located the source of the problem by systematically removing various UI elements. The breakpoint occurs when buttons (of any type) are added to the matrix of knobs.
Here is the context. I am looping through the rows and columns of the modulation matrix and adding control knobs, indicator lights (ILEDControl), and buttons. The line that produces the issue is marked with a comment above it. The issue doesn’t occur if I replace the button with an IVLabelControl, but it happens with multiple types of buttons. The more buttons that are added, the greater the chance that the debug_heap breakpoint is triggered, so it may occur with just a single button added, though I didn’t observe that when I tested it.
// Function Matrix
IRECT matrixBounds = b.GetReducedFromBottom(380.f).GetReducedFromRight(300.f).GetReducedFromLeft(80.f);
constexpr int nMatrixRows = N_OSC;
constexpr int nMatrixCols = N_OSC * 3;
for (int j{ 0 }; j < nMatrixCols; j++) {
for (int i{ 0 }; i < nMatrixRows; i++) {
// Add pitch selectors on the left side of the matrix
if (j == 0) {
IControl* pBox = pGraphics->AttachControl(
new IVPitchRatioControl(matrixBounds.GetFromLeft(50.f).GetHShifted(-50.f).GetGridCell(i, 0, nMatrixRows, 1).GetCentredInside(50.f, 26.f),
kParamOsc1Pitch + i, nullptr, "", PROJECT_STYLE, true, 1.f, 0.25f, 20.f, "%0.2f", 1.f, 0.25, false)
);
const char* labels[]{ "Osc1", "Osc2", "Osc3", "Osc4", "Osc5" };
pGraphics->AttachControl(new IVLabelControl(pBox->GetRECT().GetHShifted(-50.f), labels[i]));
}
// Matrix knobs
const int tagIdx = kCtrlMatrixR01C01 + j * nMatrixCols + i;
IRECT knobAndButtonRect = matrixBounds.GetGridCell(i, j, nMatrixRows, nMatrixCols);
IControl* knob = pGraphics->AttachControl(new IVKnobControl(knobAndButtonRect.FracRectVertical(0.7, true).GetCentredInside(32.f), kParamMatrixOsc1Phase1 + static_cast<EParams>(j * nMatrixRows + i), "", PROJECT_STYLE.WithShowLabel(false).WithShowValue(false), false, false), tagIdx < kNumCtrlTags ? tagIdx : -1);
// Add Modulation LED indicators, mod edit buttons, and matrix labels
if (knob) {
pGraphics->AttachControl(new ILEDControl(knobAndButtonRect.GetFromTRHC(5.f, 5.f), IColor(255, 0, 0, 0)));
IRECT modButtonRect = knob->GetRECT().GetVSliced(20.f).GetVShifted(30.f).GetHPadded(8.f);
// PROBLEM LINE BELOW:
pGraphics->AttachControl(new IVToggleControl(modButtonRect, SplashClickActionFunc, "", PROJECT_STYLE.WithShowLabel(false)));
if (i == 0) {
const char* symbols[]{ "φ₁", "ω", "A" };
const char* subscripts[]{ "1", "2", "3", "4", "5" };
IControl* pSymbol = pGraphics->AttachControl(new IVLabelControl(knob->GetRECT().GetVShifted(-knob->GetRECT().H()-4.f), symbols[j / N_OSC]));
pGraphics->AttachControl(new IVLabelControl(pSymbol->GetRECT().GetFromBRHC(10.f, 10.f), subscripts[j % N_OSC], DEFAULT_TEXT_STYLE.WithValueText(DEFAULT_VALUE_TEXT.WithSize(12.f).WithFGColor(COLOR_WHITE))));
}
}
// Add gain knobs on the right side of the matrix
if (j + 1 == nMatrixCols) {
pGraphics->AttachControl(new IVKnobControl(matrixBounds.GetFromRight(50.f).GetHShifted(50.f).GetGridCell(i, 0, nMatrixRows, 1).GetCentredInside(50.f), kParamOsc1OutputGain + i, "", PROJECT_STYLE.WithShowLabel(false), false, false)
);
}
}
}
The full matrix is supposed to look like this:
The buttons/toggles that say “off” are the culprit.
Another update: the crashes seem to occur after the IGraphicsWin::onDisplayTimer reaches the final return statement even when msgCount != curCount is true. This shouldn’t be possible, as the function is supposed to return earlier under that condition.