При написании нового vst-плагина с использованием VSTGUI я действительно борюсь с тем, как использовать библиотеку, и большая часть прогресса достигнута в угадывании и отладке после (потому что на самом деле нет документации, кроме миллиона строк и ygrabit, в которых указано чуть больше, чем очевидное).
Пока все идет хорошо, но мой последний вклад в проект включал темы, которые сделали дизайн немного более проблематичным. В частности, я работаю над набором текстовых меток в контейнере (выполняю неатомарные операции), и они могут (и, очевидно, будут) разрушаться без моего ведома, когда пользователь закрывает окно.
Даже добавление проверок непосредственно перед изменением элементов может быть проблемой. Поэтому мне действительно нужно контролировать время жизни этих объектов (что нормально), за исключением случаев, когда они отображаются в CViewContainer, он автоматически принимает на себя ответственность.
Я понятия не имею, как написать основную часть редактора, поэтому я использовал для этого программу VSTGUIBuilder и добавил (и переписал) то, что мне нужно. Однако, поскольку для всех «представлений», с которыми вы можете работать, требуется либо родительское, либо системное окно, вы не можете создавать экземпляры каких-либо представлений / элементов управления до достижения функции AEffEditor :: Open (), которая вызывается всякий раз, когда ваше окно всплывает.
И метод AEffEditor :: close () вызывается всякий раз, когда окно закрывается. Теперь, vstguibuilder положить
delete frame;
внутри метода AEffEditor :: close (), который предлагает вам перестроить и распределить все ресурсы при каждом открытии и закрытии. Может ли это быть правдой? И если это так, нет ли способа, которым я могу защитить содержимое моего контейнера (который для деталей является вектором< CTextLabel *>) от удаления удаленной функции? Это не проблема, чтобы избавиться от него потом, я просто беспокоюсь о segfaults при изменении его.
Использование мьютексов и тому подобного является последним средством (если вызов поступает от хоста), я не хочу в любом случае зависать хост, если мой код дает сбой и никогда не будет освобожден.
Редактировать:
В итоге я нашел решение, которое не так элегантно, но работает безопасно. Вот код в рабочей функции:
while(bLock) {
Sleep(0);
}
bLock = true;
if(msgs.empty())
return;
/*
Prevent someone deletes our lines in close().
we create a copy of the container to be 100% sure
and increase the reference count, so we can safely
work with our own container and we 'forget' them
afterwards, so they will be deleted if needed.
This ensures that close AND open can be called
meanwhile we are working with the lines
*/
bDeleteLock = true;
// also the copy constructor should work as expected here
// since we are working with pointers, we still reference the same content.
auto copy_lines = lines;
for each(auto line in copy_lines) {
line->remember();
}
bDeleteLock = false;
...
for each(auto line in copy_lines) {
line->forget();
}
cont->setDirty();
bLock — это еще один «мьютекс», защищающий очередь сообщений, которую эта функция будет распечатывать. bDeleteLock защищает процесс копирования линейного контейнера и его «запоминания» и мгновенно освобождает, если впоследствии. Оба объявляются как изменчивые bools, разве этого не достаточно? Вот метод close (), кстати.
void CConsole::Close() {
// locking lines while copying them over in a container we can work with
while(bDeleteLock)
Sleep(0);
//waiting for bLock is not needed because it wont get deleted.
if(!visible) //if we are not visible it's our responsibility to remove the view
delete cont;
lines.clear();
}
Аааа, VSTGUI, это возвращает некоторые темные воспоминания. 😉 А если серьезно, то, возможно, вам придется использовать мьютекс, чтобы предотвратить зависание хоста. Необходимость создавать все при открытии окна выглядит глупо, но вы можете видеть, что многие плагины делают именно это.
Одним из возможных способов решения этой проблемы является использование сегмента общей памяти для данных кэшированного представления, а затем передача ссылки на местоположение обратно в ваш плагин.
Других решений пока нет …