| @@ -41,6 +41,7 @@ using namespace AT1; | |||
| // AT1 Plugin | |||
| class AT1Plugin : public NativePluginClass, | |||
| public X_handler_thread<Mainwin>::SetValueCallback, | |||
| private Mainwin::ValueChangedCallback | |||
| { | |||
| public: | |||
| @@ -68,7 +69,7 @@ public: | |||
| rootwin(nullptr), | |||
| mainwin(nullptr), | |||
| handler(nullptr), | |||
| handlerThread(), | |||
| handlerThread(this), | |||
| leakDetector_AT1Plugin() | |||
| { | |||
| CARLA_SAFE_ASSERT(host != nullptr); | |||
| @@ -347,18 +348,7 @@ public: | |||
| if (mainwin == nullptr) | |||
| return; | |||
| const CarlaMutexLocker cml(handlerThread.getLock()); | |||
| if (index < kParameterNROTARY) | |||
| { | |||
| mainwin->_rotary[index]->set_value(value); | |||
| return; | |||
| } | |||
| if (index == kParameterM_CHANNEL) | |||
| { | |||
| mainwin->setchan_ui(value); | |||
| return; | |||
| } | |||
| handlerThread.setParameterValueLater(index, value); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -396,6 +386,25 @@ public: | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // X_handler_thread callbacks | |||
| void setParameterValueFromHandlerThread(uint32_t index, float value) override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(mainwin != nullptr,); | |||
| if (index < kParameterNROTARY) | |||
| { | |||
| mainwin->_rotary[index]->set_value(value); | |||
| return; | |||
| } | |||
| if (index == kParameterM_CHANNEL) | |||
| { | |||
| mainwin->setchan_ui(value); | |||
| return; | |||
| } | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| private: | |||
| // Fake jack client | |||
| @@ -41,6 +41,7 @@ using namespace BLS1; | |||
| // BLS1 Plugin | |||
| class BLS1Plugin : public NativePluginClass, | |||
| public X_handler_thread<Mainwin>::SetValueCallback, | |||
| private Mainwin::ValueChangedCallback | |||
| { | |||
| public: | |||
| @@ -66,7 +67,7 @@ public: | |||
| rootwin(nullptr), | |||
| mainwin(nullptr), | |||
| handler(nullptr), | |||
| handlerThread(), | |||
| handlerThread(this), | |||
| leakDetector_BLS1Plugin() | |||
| { | |||
| CARLA_SAFE_ASSERT(host != nullptr); | |||
| @@ -306,9 +307,7 @@ public: | |||
| if (mainwin == nullptr) | |||
| return; | |||
| const CarlaMutexLocker cml(handlerThread.getLock()); | |||
| mainwin->_rotary[index]->set_value(value); | |||
| handlerThread.setParameterValueLater(index, value); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -346,6 +345,16 @@ public: | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // X_handler_thread callbacks | |||
| void setParameterValueFromHandlerThread(uint32_t index, float value) override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(mainwin != nullptr,); | |||
| mainwin->_rotary[index]->set_value(value); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| private: | |||
| // Fake jack client | |||
| @@ -20,6 +20,7 @@ | |||
| #include "CarlaMutex.hpp" | |||
| #include "CarlaThread.hpp" | |||
| #include "LinkedList.hpp" | |||
| #include <png.h> | |||
| #include <clxclient.h> | |||
| @@ -29,17 +30,32 @@ | |||
| // ----------------------------------------------------------------------- | |||
| struct X_handler_Param { | |||
| uint32_t index; | |||
| float value; | |||
| }; | |||
| typedef LinkedList<X_handler_Param> ParamList; | |||
| template<class MainwinType> | |||
| class X_handler_thread : public CarlaThread | |||
| { | |||
| public: | |||
| X_handler_thread() | |||
| struct SetValueCallback { | |||
| virtual ~SetValueCallback() {} | |||
| virtual void setParameterValueFromHandlerThread(const uint32_t index, const float value) = 0; | |||
| }; | |||
| X_handler_thread(SetValueCallback* const cb) | |||
| : CarlaThread("X_handler"), | |||
| fCallback(cb), | |||
| fMutex(), | |||
| fHandler(nullptr), | |||
| fRootwin(nullptr), | |||
| fMainwin(nullptr), | |||
| fClosed(false) {} | |||
| fClosed(false), | |||
| fParamMutex(), | |||
| fParamChanges() {} | |||
| void setupAndRun(X_handler* const h, X_rootwin* const r, MainwinType* const m) noexcept | |||
| { | |||
| @@ -71,6 +87,14 @@ public: | |||
| return fMutex; | |||
| } | |||
| void setParameterValueLater(const uint32_t index, const float value) noexcept | |||
| { | |||
| const CarlaMutexLocker cml(fParamMutex); | |||
| const X_handler_Param param = { index, value }; | |||
| fParamChanges.append(param); | |||
| } | |||
| bool wasClosed() noexcept | |||
| { | |||
| if (fClosed) | |||
| @@ -82,12 +106,17 @@ public: | |||
| } | |||
| private: | |||
| SetValueCallback* const fCallback; | |||
| CarlaMutex fMutex; | |||
| X_handler* fHandler; | |||
| X_rootwin* fRootwin; | |||
| MainwinType* fMainwin; | |||
| volatile bool fClosed; | |||
| CarlaMutex fParamMutex; | |||
| ParamList fParamChanges; | |||
| void run() override | |||
| { | |||
| for (; ! shouldThreadExit();) | |||
| @@ -99,6 +128,18 @@ private: | |||
| CARLA_SAFE_ASSERT_RETURN(fMainwin != nullptr,); | |||
| { | |||
| const CarlaMutexLocker cml(fParamMutex); | |||
| for (ParamList::Itenerator it = fParamChanges.begin(); it.valid(); it.next()) | |||
| { | |||
| const X_handler_Param& param(it.getValue()); | |||
| fCallback->setParameterValueFromHandlerThread(param.index, param.value); | |||
| } | |||
| fParamChanges.clear(); | |||
| } | |||
| for (; (ev = fMainwin->process()) == EV_X11;) | |||
| { | |||
| fRootwin->handle_event(); | |||
| @@ -40,6 +40,7 @@ using namespace REV1; | |||
| // REV1 Plugin | |||
| class REV1Plugin : public NativePluginClass, | |||
| public X_handler_thread<Mainwin>::SetValueCallback, | |||
| private Mainwin::ValueChangedCallback | |||
| { | |||
| public: | |||
| @@ -69,7 +70,7 @@ public: | |||
| rootwin(nullptr), | |||
| mainwin(nullptr), | |||
| handler(nullptr), | |||
| handlerThread(), | |||
| handlerThread(this), | |||
| leakDetector_REV1Plugin() | |||
| { | |||
| CARLA_SAFE_ASSERT(host != nullptr); | |||
| @@ -387,14 +388,7 @@ public: | |||
| if (mainwin == nullptr) | |||
| return; | |||
| uint32_t rindex = index; | |||
| if (kIsAmbisonic && index == kParameterOPMIXorRGXYZ) | |||
| rindex += 1; | |||
| const CarlaMutexLocker cml(handlerThread.getLock()); | |||
| mainwin->_rotary[rindex]->set_value(value); | |||
| handlerThread.setParameterValueLater(index, value); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -437,6 +431,21 @@ public: | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // X_handler_thread callbacks | |||
| void setParameterValueFromHandlerThread(uint32_t index, float value) override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(mainwin != nullptr,); | |||
| uint32_t rindex = index; | |||
| if (kIsAmbisonic && index == kParameterOPMIXorRGXYZ) | |||
| rindex += 1; | |||
| mainwin->_rotary[rindex]->set_value(value); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| private: | |||
| const bool kIsAmbisonic; | |||