Add more thread-safety in VST
This commit is contained in:
parent
5709fedb94
commit
bea7195c65
4 changed files with 166 additions and 128 deletions
|
|
@ -140,16 +140,20 @@ IPlugView* PLUGIN_API SfizzVstController::createView(FIDString _name)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (_editor) {
|
if (_editor) {
|
||||||
_uiState = _editor->getCurrentUiState();
|
withStateLock([this]() {
|
||||||
|
_uiState = _editor->getCurrentUiState();
|
||||||
|
});
|
||||||
_editor.reset();
|
_editor.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
SfizzVstEditor* editor = new SfizzVstEditor(this);
|
SfizzVstEditor* editor = new SfizzVstEditor(this);
|
||||||
_editor = Steinberg::owned(editor);
|
_editor = Steinberg::owned(editor);
|
||||||
|
|
||||||
editor->updateState(_state);
|
withStateLock([this, editor]() {
|
||||||
editor->updateUiState(_uiState);
|
editor->updateState(_state);
|
||||||
editor->updatePlayState(_playState);
|
editor->updateUiState(_uiState);
|
||||||
|
editor->updatePlayState(_playState);
|
||||||
|
});
|
||||||
|
|
||||||
editor->remember();
|
editor->remember();
|
||||||
return editor;
|
return editor;
|
||||||
|
|
@ -204,53 +208,61 @@ tresult PLUGIN_API SfizzVstController::setParamNormalized(Vst::ParamID tag, Vst:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slotF32 && *slotF32 != value) {
|
if (slotF32 && *slotF32 != value) {
|
||||||
*slotF32 = value;
|
withStateLock([this, slotF32, value]() {
|
||||||
if (SfizzVstEditor* editor = _editor)
|
*slotF32 = value;
|
||||||
editor->updateState(_state);
|
if (SfizzVstEditor* editor = _editor)
|
||||||
|
editor->updateState(_state);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (slotI32 && *slotI32 != (int32)value) {
|
else if (slotI32 && *slotI32 != (int32)value) {
|
||||||
*slotI32 = (int32)value;
|
withStateLock([this, slotI32, value]() {
|
||||||
if (SfizzVstEditor* editor = _editor)
|
*slotI32 = (int32)value;
|
||||||
editor->updateState(_state);
|
if (SfizzVstEditor* editor = _editor)
|
||||||
|
editor->updateState(_state);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return kResultTrue;
|
return kResultTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult PLUGIN_API SfizzVstController::setState(IBStream* state)
|
tresult PLUGIN_API SfizzVstController::setState(IBStream* stream)
|
||||||
{
|
{
|
||||||
SfizzUiState s;
|
SfizzUiState s;
|
||||||
|
|
||||||
tresult r = s.load(state);
|
tresult r = s.load(stream);
|
||||||
if (r != kResultTrue)
|
if (r != kResultTrue)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
_uiState = s;
|
withStateLock([this, &s]() {
|
||||||
|
_uiState = s;
|
||||||
if (SfizzVstEditor* editor = _editor)
|
if (SfizzVstEditor* editor = _editor)
|
||||||
editor->updateUiState(_uiState);
|
editor->updateUiState(_uiState);
|
||||||
|
});
|
||||||
|
|
||||||
return kResultTrue;
|
return kResultTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult PLUGIN_API SfizzVstController::getState(IBStream* state)
|
tresult PLUGIN_API SfizzVstController::getState(IBStream* stream)
|
||||||
{
|
{
|
||||||
if (_editor)
|
tresult result;
|
||||||
_uiState = _editor->getCurrentUiState();
|
|
||||||
|
|
||||||
return _uiState.store(state);
|
withStateLock([this, stream, &result]() {
|
||||||
|
if (_editor)
|
||||||
|
_uiState = _editor->getCurrentUiState();
|
||||||
|
result = _uiState.store(stream);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult PLUGIN_API SfizzVstController::setComponentState(IBStream* state)
|
tresult PLUGIN_API SfizzVstController::setComponentState(IBStream* stream)
|
||||||
{
|
{
|
||||||
SfizzVstState s;
|
SfizzVstState s;
|
||||||
|
|
||||||
tresult r = s.load(state);
|
tresult r = s.load(stream);
|
||||||
if (r != kResultTrue)
|
if (r != kResultTrue)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
_state = s;
|
|
||||||
|
|
||||||
setParamNormalized(kPidVolume, kParamVolumeRange.normalize(s.volume));
|
setParamNormalized(kPidVolume, kParamVolumeRange.normalize(s.volume));
|
||||||
setParamNormalized(kPidNumVoices, kParamNumVoicesRange.normalize(s.numVoices));
|
setParamNormalized(kPidNumVoices, kParamNumVoicesRange.normalize(s.numVoices));
|
||||||
setParamNormalized(kPidOversampling, kParamOversamplingRange.normalize(s.oversamplingLog2));
|
setParamNormalized(kPidOversampling, kParamOversamplingRange.normalize(s.oversamplingLog2));
|
||||||
|
|
@ -259,14 +271,19 @@ tresult PLUGIN_API SfizzVstController::setComponentState(IBStream* state)
|
||||||
setParamNormalized(kPidTuningFrequency, kParamTuningFrequencyRange.normalize(s.tuningFrequency));
|
setParamNormalized(kPidTuningFrequency, kParamTuningFrequencyRange.normalize(s.tuningFrequency));
|
||||||
setParamNormalized(kPidStretchedTuning, kParamStretchedTuningRange.normalize(s.stretchedTuning));
|
setParamNormalized(kPidStretchedTuning, kParamStretchedTuningRange.normalize(s.stretchedTuning));
|
||||||
|
|
||||||
if (SfizzVstEditor* editor = _editor)
|
withStateLock([this, &s]() {
|
||||||
editor->updateState(_state);
|
_state = s;
|
||||||
|
if (SfizzVstEditor* editor = _editor)
|
||||||
|
editor->updateState(_state);
|
||||||
|
});
|
||||||
|
|
||||||
return kResultTrue;
|
return kResultTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult SfizzVstController::notify(Vst::IMessage* message)
|
tresult SfizzVstController::notify(Vst::IMessage* message)
|
||||||
{
|
{
|
||||||
|
// Note: may be called from any thread (Reaper)
|
||||||
|
|
||||||
tresult result = SfizzVstControllerNoUi::notify(message);
|
tresult result = SfizzVstControllerNoUi::notify(message);
|
||||||
if (result != kResultFalse)
|
if (result != kResultFalse)
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -282,10 +299,11 @@ tresult SfizzVstController::notify(Vst::IMessage* message)
|
||||||
if (result != kResultTrue)
|
if (result != kResultTrue)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
_state.sfzFile.assign(static_cast<const char *>(data), size);
|
withStateLock([this, data, size]() {
|
||||||
|
_state.sfzFile.assign(static_cast<const char *>(data), size);
|
||||||
if (SfizzVstEditor* editor = _editor)
|
if (SfizzVstEditor* editor = _editor)
|
||||||
editor->updateState(_state);
|
editor->updateState(_state);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (!strcmp(id, "LoadedScala")) {
|
else if (!strcmp(id, "LoadedScala")) {
|
||||||
const void* data = nullptr;
|
const void* data = nullptr;
|
||||||
|
|
@ -295,10 +313,11 @@ tresult SfizzVstController::notify(Vst::IMessage* message)
|
||||||
if (result != kResultTrue)
|
if (result != kResultTrue)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
_state.scalaFile.assign(static_cast<const char *>(data), size);
|
withStateLock([this, data, size]() {
|
||||||
|
_state.scalaFile.assign(static_cast<const char *>(data), size);
|
||||||
if (SfizzVstEditor* editor = _editor)
|
if (SfizzVstEditor* editor = _editor)
|
||||||
editor->updateState(_state);
|
editor->updateState(_state);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (!strcmp(id, "NotifiedPlayState")) {
|
else if (!strcmp(id, "NotifiedPlayState")) {
|
||||||
const void* data = nullptr;
|
const void* data = nullptr;
|
||||||
|
|
@ -308,10 +327,11 @@ tresult SfizzVstController::notify(Vst::IMessage* message)
|
||||||
if (result != kResultTrue)
|
if (result != kResultTrue)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
_playState = *static_cast<const SfizzPlayState*>(data);
|
withStateLock([this, data]() {
|
||||||
|
_playState = *static_cast<const SfizzPlayState*>(data);
|
||||||
if (SfizzVstEditor* editor = _editor)
|
if (SfizzVstEditor* editor = _editor)
|
||||||
editor->updatePlayState(_playState);
|
editor->updatePlayState(_playState);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (!strcmp(id, "ReceivedMessage")) {
|
else if (!strcmp(id, "ReceivedMessage")) {
|
||||||
const void* data = nullptr;
|
const void* data = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "public.sdk/source/vst/vstparameters.h"
|
#include "public.sdk/source/vst/vstparameters.h"
|
||||||
#include "vstgui/plugin-bindings/vst3editor.h"
|
#include "vstgui/plugin-bindings/vst3editor.h"
|
||||||
#include <sfizz_message.h>
|
#include <sfizz_message.h>
|
||||||
|
#include <mutex>
|
||||||
class SfizzVstState;
|
class SfizzVstState;
|
||||||
class SfizzVstEditor;
|
class SfizzVstEditor;
|
||||||
|
|
||||||
|
|
@ -43,9 +44,9 @@ public:
|
||||||
IPlugView* PLUGIN_API createView(FIDString name) override;
|
IPlugView* PLUGIN_API createView(FIDString name) override;
|
||||||
|
|
||||||
tresult PLUGIN_API setParamNormalized(Vst::ParamID tag, Vst::ParamValue value) override;
|
tresult PLUGIN_API setParamNormalized(Vst::ParamID tag, Vst::ParamValue value) override;
|
||||||
tresult PLUGIN_API setState(IBStream* state) override;
|
tresult PLUGIN_API setState(IBStream* stream) override;
|
||||||
tresult PLUGIN_API getState(IBStream* state) override;
|
tresult PLUGIN_API getState(IBStream* stream) override;
|
||||||
tresult PLUGIN_API setComponentState(IBStream* state) override;
|
tresult PLUGIN_API setComponentState(IBStream* stream) override;
|
||||||
tresult PLUGIN_API notify(Vst::IMessage* message) override;
|
tresult PLUGIN_API notify(Vst::IMessage* message) override;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -54,8 +55,16 @@ public:
|
||||||
static FUID cid;
|
static FUID cid;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SfizzVstState _state;
|
template <class F> void withStateLock(F&& fn) const
|
||||||
SfizzUiState _uiState;
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_stateMutex);
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable std::mutex _stateMutex; // for R/W the state data
|
||||||
|
SfizzVstState _state {};
|
||||||
|
SfizzUiState _uiState {}; // updated on UI open/close/state-request
|
||||||
SfizzPlayState _playState {};
|
SfizzPlayState _playState {};
|
||||||
Steinberg::IPtr<SfizzVstEditor> _editor;
|
Steinberg::IPtr<SfizzVstEditor> _editor;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ SfizzVstEditor::SfizzVstEditor(SfizzVstController* controller)
|
||||||
: VSTGUIEditor(controller, &sfizzUiViewRect),
|
: VSTGUIEditor(controller, &sfizzUiViewRect),
|
||||||
oscTemp_(new uint8_t[kOscTempSize])
|
oscTemp_(new uint8_t[kOscTempSize])
|
||||||
{
|
{
|
||||||
oscQueue_.reserve(kOscQueueSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SfizzVstEditor::~SfizzVstEditor()
|
SfizzVstEditor::~SfizzVstEditor()
|
||||||
|
|
@ -56,10 +55,14 @@ bool PLUGIN_API SfizzVstEditor::open(void* parent, const VSTGUI::PlatformType& p
|
||||||
editor_.reset(editor);
|
editor_.reset(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
mustRedisplayState_ = true;
|
withStateLock([this]() {
|
||||||
mustRedisplayUiState_ = true;
|
mustRedisplayState_ = true;
|
||||||
mustRedisplayPlayState_ = true;
|
mustRedisplayUiState_ = true;
|
||||||
flushOscQueue();
|
mustRedisplayPlayState_ = true;
|
||||||
|
OscByteVec* queue = new OscByteVec;
|
||||||
|
oscQueue_.reset(queue);
|
||||||
|
queue->reserve(kOscQueueSize);
|
||||||
|
});
|
||||||
|
|
||||||
updateStateDisplay();
|
updateStateDisplay();
|
||||||
|
|
||||||
|
|
@ -86,7 +89,9 @@ void PLUGIN_API SfizzVstEditor::close()
|
||||||
this->frame = nullptr;
|
this->frame = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
flushOscQueue();
|
withStateLock([this]() {
|
||||||
|
oscQueue_.reset();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -121,71 +126,73 @@ CMessageResult SfizzVstEditor::notify(CBaseObject* sender, const char* message)
|
||||||
|
|
||||||
void SfizzVstEditor::updateState(const SfizzVstState& state)
|
void SfizzVstEditor::updateState(const SfizzVstState& state)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
withStateLock([this, &state]() {
|
||||||
state_ = state;
|
state_ = state;
|
||||||
mustRedisplayState_ = true;
|
mustRedisplayState_ = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SfizzVstEditor::updateUiState(const SfizzUiState& uiState)
|
void SfizzVstEditor::updateUiState(const SfizzUiState& uiState)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
withStateLock([this, &uiState]() {
|
||||||
uiState_ = uiState;
|
uiState_ = uiState;
|
||||||
mustRedisplayUiState_ = true;
|
mustRedisplayUiState_ = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SfizzVstEditor::updatePlayState(const SfizzPlayState& playState)
|
void SfizzVstEditor::updatePlayState(const SfizzPlayState& playState)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
withStateLock([this, &playState]() {
|
||||||
playState_ = playState;
|
playState_ = playState;
|
||||||
mustRedisplayPlayState_ = true;
|
mustRedisplayPlayState_ = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
SfizzUiState SfizzVstEditor::getCurrentUiState() const
|
SfizzUiState SfizzVstEditor::getCurrentUiState() const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
SfizzUiState uiState;
|
||||||
return uiState_;
|
withStateLock([this, &uiState]() {
|
||||||
|
uiState = uiState_;
|
||||||
|
});
|
||||||
|
return uiState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SfizzVstEditor::receiveMessage(const void* data, uint32_t size)
|
void SfizzVstEditor::receiveMessage(const void* data, uint32_t size)
|
||||||
{
|
{
|
||||||
if (!frame) {
|
// Note: may be called from non-UI thread (Reaper)
|
||||||
// only accumulate if message processing is active
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
withStateLock([this, data, size]() {
|
||||||
std::copy(
|
if (OscByteVec* queue = oscQueue_.get()) {
|
||||||
reinterpret_cast<const uint8_t*>(data),
|
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
|
||||||
reinterpret_cast<const uint8_t*>(data) + size,
|
std::copy(bytes, bytes + size, std::back_inserter(*queue));
|
||||||
std::back_inserter(oscQueue_));
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SfizzVstEditor::processOscQueue()
|
void SfizzVstEditor::processOscQueue()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
withStateLock([this]() {
|
||||||
|
OscByteVec* queue = oscQueue_.get();
|
||||||
|
if (!queue)
|
||||||
|
return;
|
||||||
|
|
||||||
const uint8_t* oscData = oscQueue_.data();
|
const uint8_t* oscData = queue->data();
|
||||||
size_t oscSize = oscQueue_.size();
|
size_t oscSize = queue->size();
|
||||||
|
|
||||||
const char* path;
|
const char* path;
|
||||||
const char* sig;
|
const char* sig;
|
||||||
const sfizz_arg_t* args;
|
const sfizz_arg_t* args;
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[1024];
|
||||||
|
|
||||||
uint32_t msgSize;
|
uint32_t msgSize;
|
||||||
while ((msgSize = sfizz_extract_message(oscData, oscSize, buffer, sizeof(buffer), &path, &sig, &args)) > 0) {
|
while ((msgSize = sfizz_extract_message(oscData, oscSize, buffer, sizeof(buffer), &path, &sig, &args)) > 0) {
|
||||||
uiReceiveMessage(path, sig, args);
|
uiReceiveMessage(path, sig, args);
|
||||||
oscData += msgSize;
|
oscData += msgSize;
|
||||||
oscSize -= msgSize;
|
oscSize -= msgSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
oscQueue_.clear();
|
queue->clear();
|
||||||
}
|
});
|
||||||
|
|
||||||
void SfizzVstEditor::flushOscQueue()
|
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
|
||||||
oscQueue_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -333,41 +340,37 @@ void SfizzVstEditor::updateStateDisplay()
|
||||||
if (!frame)
|
if (!frame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(mustRedisplayState_ || mustRedisplayUiState_ || mustRedisplayPlayState_))
|
withStateLock([this]() {
|
||||||
return;
|
if (mustRedisplayState_) {
|
||||||
|
uiReceiveValue(EditId::SfzFile, state_.sfzFile);
|
||||||
|
uiReceiveValue(EditId::Volume, state_.volume);
|
||||||
|
uiReceiveValue(EditId::Polyphony, state_.numVoices);
|
||||||
|
uiReceiveValue(EditId::Oversampling, 1u << state_.oversamplingLog2);
|
||||||
|
uiReceiveValue(EditId::PreloadSize, state_.preloadSize);
|
||||||
|
uiReceiveValue(EditId::ScalaFile, state_.scalaFile);
|
||||||
|
uiReceiveValue(EditId::ScalaRootKey, state_.scalaRootKey);
|
||||||
|
uiReceiveValue(EditId::TuningFrequency, state_.tuningFrequency);
|
||||||
|
uiReceiveValue(EditId::StretchTuning, state_.stretchedTuning);
|
||||||
|
mustRedisplayState_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
///
|
||||||
|
if (mustRedisplayUiState_) {
|
||||||
|
uiReceiveValue(EditId::UIActivePanel, uiState_.activePanel);
|
||||||
|
mustRedisplayUiState_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
if (mustRedisplayState_) {
|
if (mustRedisplayPlayState_) {
|
||||||
uiReceiveValue(EditId::SfzFile, state_.sfzFile);
|
uiReceiveValue(EditId::UINumCurves, playState_.curves);
|
||||||
uiReceiveValue(EditId::Volume, state_.volume);
|
uiReceiveValue(EditId::UINumMasters, playState_.masters);
|
||||||
uiReceiveValue(EditId::Polyphony, state_.numVoices);
|
uiReceiveValue(EditId::UINumGroups, playState_.groups);
|
||||||
uiReceiveValue(EditId::Oversampling, 1u << state_.oversamplingLog2);
|
uiReceiveValue(EditId::UINumRegions, playState_.regions);
|
||||||
uiReceiveValue(EditId::PreloadSize, state_.preloadSize);
|
uiReceiveValue(EditId::UINumPreloadedSamples, playState_.preloadedSamples);
|
||||||
uiReceiveValue(EditId::ScalaFile, state_.scalaFile);
|
uiReceiveValue(EditId::UINumActiveVoices, playState_.activeVoices);
|
||||||
uiReceiveValue(EditId::ScalaRootKey, state_.scalaRootKey);
|
mustRedisplayPlayState_ = false;
|
||||||
uiReceiveValue(EditId::TuningFrequency, state_.tuningFrequency);
|
}
|
||||||
uiReceiveValue(EditId::StretchTuning, state_.stretchedTuning);
|
});
|
||||||
mustRedisplayState_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
if (mustRedisplayUiState_) {
|
|
||||||
uiReceiveValue(EditId::UIActivePanel, uiState_.activePanel);
|
|
||||||
mustRedisplayUiState_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
if (mustRedisplayPlayState_) {
|
|
||||||
uiReceiveValue(EditId::UINumCurves, playState_.curves);
|
|
||||||
uiReceiveValue(EditId::UINumMasters, playState_.masters);
|
|
||||||
uiReceiveValue(EditId::UINumGroups, playState_.groups);
|
|
||||||
uiReceiveValue(EditId::UINumRegions, playState_.regions);
|
|
||||||
uiReceiveValue(EditId::UINumPreloadedSamples, playState_.preloadedSamples);
|
|
||||||
uiReceiveValue(EditId::UINumActiveVoices, playState_.activeVoices);
|
|
||||||
mustRedisplayPlayState_ = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vst::ParamID SfizzVstEditor::parameterOfEditId(EditId id)
|
Vst::ParamID SfizzVstEditor::parameterOfEditId(EditId id)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,12 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processOscQueue();
|
void processOscQueue();
|
||||||
void flushOscQueue();
|
|
||||||
|
template <class F> void withStateLock(F&& fn) const
|
||||||
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(stateMutex_);
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// EditorController
|
// EditorController
|
||||||
|
|
@ -72,12 +77,13 @@ private:
|
||||||
|
|
||||||
// editor state
|
// editor state
|
||||||
// note: might be updated from a non-UI thread
|
// note: might be updated from a non-UI thread
|
||||||
mutable std::recursive_mutex stateMutex_;
|
mutable std::recursive_mutex stateMutex_; // for R/W the state data, and OSC queue
|
||||||
SfizzVstState state_;
|
SfizzVstState state_ {};
|
||||||
SfizzUiState uiState_;
|
SfizzUiState uiState_ {};
|
||||||
SfizzPlayState playState_;
|
SfizzPlayState playState_ {};
|
||||||
volatile bool mustRedisplayState_ = false;
|
volatile bool mustRedisplayState_ = false;
|
||||||
volatile bool mustRedisplayUiState_ = false;
|
volatile bool mustRedisplayUiState_ = false;
|
||||||
volatile bool mustRedisplayPlayState_ = false;
|
volatile bool mustRedisplayPlayState_ = false;
|
||||||
std::vector<uint8_t> oscQueue_;
|
typedef std::vector<uint8_t> OscByteVec;
|
||||||
|
std::unique_ptr<OscByteVec> oscQueue_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue