From 150f5878157da37c66004fd7ac7be6fb2d41bcb9 Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 28 Nov 2014 10:13:38 +0000 Subject: [PATCH] Make pipe class function names more extensive, add docs; Fix #164 --- source/backend/CarlaUtils.cpp | 24 +- source/backend/engine/CarlaEngineNative.cpp | 305 +++++++++--------- source/backend/engine/Makefile | 3 +- source/carla_host.py | 2 +- source/externalui.py | 6 + source/modules/CarlaNativeExtUI.hpp | 72 +++-- .../native-plugins/resources/bigmeter-ui | 22 +- .../native-plugins/resources/carla-plugin | 23 +- .../modules/native-plugins/resources/notes-ui | 13 +- source/utils/CarlaExternalUI.hpp | 12 +- source/utils/CarlaPipeUtils.cpp | 93 +++--- source/utils/CarlaPipeUtils.hpp | 176 ++++++++-- 12 files changed, 481 insertions(+), 270 deletions(-) diff --git a/source/backend/CarlaUtils.cpp b/source/backend/CarlaUtils.cpp index 8e7ea18cf..bb8e543de 100644 --- a/source/backend/CarlaUtils.cpp +++ b/source/backend/CarlaUtils.cpp @@ -87,7 +87,7 @@ public: const char* readlineblock(const uint timeout) noexcept { - return CarlaPipeClient::readlineblock(timeout); + return CarlaPipeClient::_readlineblock(timeout); } bool msgReceived(const char* const msg) noexcept @@ -115,7 +115,7 @@ CarlaPipeClientHandle carla_pipe_client_new(const char* argv[], CarlaPipeCallbac CarlaPipeClientPlugin* const pipe(new CarlaPipeClientPlugin(callbackFunc, callbackPtr)); - if (! pipe->init(argv)) + if (! pipe->initPipeClient(argv)) { delete pipe; return nullptr; @@ -128,28 +128,28 @@ void carla_pipe_client_idle(CarlaPipeClientHandle handle) { CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); - ((CarlaPipeClientPlugin*)handle)->idle(); + ((CarlaPipeClientPlugin*)handle)->idlePipe(); } bool carla_pipe_client_is_running(CarlaPipeClientHandle handle) { CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); - return ((CarlaPipeClientPlugin*)handle)->isRunning(); + return ((CarlaPipeClientPlugin*)handle)->isPipeRunning(); } void carla_pipe_client_lock(CarlaPipeClientHandle handle) { CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); - return ((CarlaPipeClientPlugin*)handle)->lock(); + return ((CarlaPipeClientPlugin*)handle)->lockPipe(); } void carla_pipe_client_unlock(CarlaPipeClientHandle handle) { CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); - return ((CarlaPipeClientPlugin*)handle)->unlock(); + return ((CarlaPipeClientPlugin*)handle)->unlockPipe(); } const char* carla_pipe_client_readlineblock(CarlaPipeClientHandle handle, uint timeout) @@ -163,21 +163,21 @@ bool carla_pipe_client_write_msg(CarlaPipeClientHandle handle, const char* msg) { CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); - return ((CarlaPipeClientPlugin*)handle)->writeMsg(msg); + return ((CarlaPipeClientPlugin*)handle)->writeMessage(msg); } bool carla_pipe_client_write_and_fix_msg(CarlaPipeClientHandle handle, const char* msg) { CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); - return ((CarlaPipeClientPlugin*)handle)->writeAndFixMsg(msg); + return ((CarlaPipeClientPlugin*)handle)->writeAndFixMessage(msg); } bool carla_pipe_client_flush(CarlaPipeClientHandle handle) { CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); - return ((CarlaPipeClientPlugin*)handle)->flush(); + return ((CarlaPipeClientPlugin*)handle)->flushMessages(); } bool carla_pipe_client_flush_and_unlock(CarlaPipeClientHandle handle) @@ -185,8 +185,8 @@ bool carla_pipe_client_flush_and_unlock(CarlaPipeClientHandle handle) CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); - const bool ret(pipe->flush()); - pipe->unlock(); + const bool ret(pipe->flushMessages()); + pipe->unlockPipe(); return ret; } @@ -196,7 +196,7 @@ void carla_pipe_client_destroy(CarlaPipeClientHandle handle) carla_debug("carla_pipe_client_destroy(%p)", handle); CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); - pipe->close(); + pipe->closePipeClient(); delete pipe; } diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 2d4c8d008..e5c362c88 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -73,11 +73,18 @@ public: carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()"); } - void show() noexcept + void writeShowMessage() noexcept { - const CarlaMutexLocker cml(getLock()); - writeMsg("show\n", 5); - flush(); + const CarlaMutexLocker cml(getPipeLock()); + writeMessage("show\n", 5); + flushMessages(); + } + + void writeFocusMessage() noexcept + { + const CarlaMutexLocker cml(getPipeLock()); + writeMessage("focus\n", 6); + flushMessages(); } protected: @@ -542,10 +549,10 @@ protected: if (! ok) { - const CarlaMutexLocker cml(getLock()); - writeMsg("error\n", 6); - writeAndFixMsg(fEngine->getLastError()); - flush(); + const CarlaMutexLocker cml(getPipeLock()); + writeMessage("error\n", 6); + writeAndFixMessage(fEngine->getLastError()); + flushMessages(); } return true; @@ -713,12 +720,12 @@ protected: return; { - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); - fUiServer.writeAndFixMsg("buffer-size"); + fUiServer.writeAndFixMessage("buffer-size"); std::sprintf(fTmpBuf, "%i\n", newBufferSize); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); } pData->bufferSize = newBufferSize; @@ -731,13 +738,13 @@ protected: return; { - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); const ScopedLocale csl; - fUiServer.writeAndFixMsg("sample-rate"); + fUiServer.writeAndFixMessage("sample-rate"); std::sprintf(fTmpBuf, "%f\n", newSampleRate); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); } pData->sampleRate = newSampleRate; @@ -748,64 +755,64 @@ protected: void uiServerSendPluginInfo(CarlaPlugin* const plugin) { - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); const uint pluginId(plugin->getId()); std::sprintf(fTmpBuf, "PLUGIN_INFO_%i\n", pluginId); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%i:%i:%i:" P_INT64 ":%i:%i\n", plugin->getType(), plugin->getCategory(), plugin->getHints(), plugin->getUniqueId(), plugin->getOptionsAvailable(), plugin->getOptionsEnabled()); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); if (const char* const filename = plugin->getFilename()) { std::sprintf(fTmpBuf, "%s", filename); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); } else - fUiServer.writeMsg("\n"); + fUiServer.writeMessage("\n"); if (const char* const name = plugin->getName()) { std::sprintf(fTmpBuf, "%s", name); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); } else - fUiServer.writeMsg("\n"); + fUiServer.writeMessage("\n"); if (const char* const iconName = plugin->getIconName()) { std::sprintf(fTmpBuf, "%s", iconName); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); } else - fUiServer.writeMsg("\n"); + fUiServer.writeMessage("\n"); plugin->getRealName(fTmpBuf); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); plugin->getLabel(fTmpBuf); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); plugin->getMaker(fTmpBuf); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); plugin->getCopyright(fTmpBuf); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); std::sprintf(fTmpBuf, "AUDIO_COUNT_%i:%i:%i\n", pluginId, plugin->getAudioInCount(), plugin->getAudioOutCount()); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "MIDI_COUNT_%i:%i:%i\n", pluginId, plugin->getMidiInCount(), plugin->getMidiOutCount()); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); - fUiServer.flush(); + fUiServer.flushMessages(); } void uiServerSendPluginParameters(CarlaPlugin* const plugin) { - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); const ScopedLocale csl; const uint pluginId(plugin->getId()); @@ -813,17 +820,17 @@ protected: for (int32_t i=PARAMETER_ACTIVE; i>PARAMETER_MAX; --i) { std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", pluginId, i); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%f\n", plugin->getInternalParameterValue(i)); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); } uint32_t ins, outs, count; plugin->getParameterCountInfo(ins, outs); count = plugin->getParameterCount(); std::sprintf(fTmpBuf, "PARAMETER_COUNT_%i:%i:%i:%i\n", pluginId, ins, outs, count); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); for (uint32_t i=0; igetParameterRanges(i)); std::sprintf(fTmpBuf, "PARAMETER_DATA_%i:%i\n", pluginId, i); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%i:%i:%i:%i\n", paramData.type, paramData.hints, paramData.midiChannel, paramData.midiCC); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); plugin->getParameterName(i, fTmpBuf); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); plugin->getParameterUnit(i, fTmpBuf); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); std::sprintf(fTmpBuf, "PARAMETER_RANGES_%i:%i\n", pluginId, i); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%f:%f:%f:%f:%f:%f\n", paramRanges.def, paramRanges.min, paramRanges.max, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", pluginId, i); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%f\n", plugin->getParameterValue(i)); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); } - fUiServer.flush(); + fUiServer.flushMessages(); } void uiServerSendPluginPrograms(CarlaPlugin* const plugin) { - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); const uint pluginId(plugin->getId()); uint32_t count = plugin->getProgramCount(); std::sprintf(fTmpBuf, "PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentProgram()); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); for (uint32_t i=0; igetProgramName(i, fTmpBuf); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); } - fUiServer.flush(); + fUiServer.flushMessages(); count = plugin->getMidiProgramCount(); std::sprintf(fTmpBuf, "MIDI_PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentMidiProgram()); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); for (uint32_t i=0; igetMidiProgramData(i)); std::sprintf(fTmpBuf, "%i:%i\n", mpData.bank, mpData.program); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%s", mpData.name); - fUiServer.writeAndFixMsg(fTmpBuf); + fUiServer.writeAndFixMessage(fTmpBuf); } - fUiServer.flush(); + fUiServer.flushMessages(); } void uiServerCallback(const EngineCallbackOpcode action, const uint pluginId, const int value1, const int value2, const float value3, const char* const valueStr) { if (! fIsRunning) return; - if (! fUiServer.isRunning()) + if (! fUiServer.isPipeRunning()) return; CarlaPlugin* plugin; @@ -950,138 +957,138 @@ protected: break; } - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); const ScopedLocale csl; std::sprintf(fTmpBuf, "ENGINE_CALLBACK_%i\n", int(action)); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%u\n", pluginId); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%i\n", value1); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%i\n", value2); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%f\n", value3); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); - fUiServer.writeAndFixMsg(valueStr != nullptr ? valueStr : ""); + fUiServer.writeAndFixMessage(valueStr != nullptr ? valueStr : ""); - fUiServer.flush(); + fUiServer.flushMessages(); } void uiServerInfo() { CARLA_SAFE_ASSERT_RETURN(fIsRunning,); - CARLA_SAFE_ASSERT_RETURN(fUiServer.isRunning(),); + CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),); - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); - fUiServer.writeAndFixMsg("complete-license"); - fUiServer.writeAndFixMsg(carla_get_complete_license_text()); + fUiServer.writeAndFixMessage("complete-license"); + fUiServer.writeAndFixMessage(carla_get_complete_license_text()); - fUiServer.writeAndFixMsg("juce-version"); - fUiServer.writeAndFixMsg(carla_get_juce_version()); + fUiServer.writeAndFixMessage("juce-version"); + fUiServer.writeAndFixMessage(carla_get_juce_version()); - fUiServer.writeAndFixMsg("file-exts"); - fUiServer.writeAndFixMsg(carla_get_supported_file_extensions()); + fUiServer.writeAndFixMessage("file-exts"); + fUiServer.writeAndFixMessage(carla_get_supported_file_extensions()); - fUiServer.writeAndFixMsg("max-plugin-number"); + fUiServer.writeAndFixMessage("max-plugin-number"); std::sprintf(fTmpBuf, "%i\n", pData->maxPluginNumber); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); - fUiServer.writeAndFixMsg("buffer-size"); + fUiServer.writeAndFixMessage("buffer-size"); std::sprintf(fTmpBuf, "%i\n", pData->bufferSize); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); const ScopedLocale csl; - fUiServer.writeAndFixMsg("sample-rate"); + fUiServer.writeAndFixMessage("sample-rate"); std::sprintf(fTmpBuf, "%f\n", pData->sampleRate); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); - fUiServer.flush(); + fUiServer.flushMessages(); } void uiServerOptions() { CARLA_SAFE_ASSERT_RETURN(fIsRunning,); - CARLA_SAFE_ASSERT_RETURN(fUiServer.isRunning(),); + CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),); const EngineOptions& options(pData->options); - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); const char* const optionsForcedStr(fOptionsForced ? "true\n" : "false\n"); const std::size_t optionsForcedStrSize(fOptionsForced ? 5 : 6); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PROCESS_MODE); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); std::sprintf(fTmpBuf, "%i\n", options.processMode); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_TRANSPORT_MODE); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); std::sprintf(fTmpBuf, "%i\n", options.transportMode); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_FORCE_STEREO); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); - fUiServer.writeMsg(options.forceStereo ? "true\n" : "false\n"); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); + fUiServer.writeMessage(options.forceStereo ? "true\n" : "false\n"); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_PLUGIN_BRIDGES); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); - fUiServer.writeMsg(options.preferPluginBridges ? "true\n" : "false\n"); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); + fUiServer.writeMessage(options.preferPluginBridges ? "true\n" : "false\n"); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_UI_BRIDGES); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); - fUiServer.writeMsg(options.preferUiBridges ? "true\n" : "false\n"); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); + fUiServer.writeMessage(options.preferUiBridges ? "true\n" : "false\n"); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UIS_ALWAYS_ON_TOP); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); - fUiServer.writeMsg(options.uisAlwaysOnTop ? "true\n" : "false\n"); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); + fUiServer.writeMessage(options.uisAlwaysOnTop ? "true\n" : "false\n"); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_MAX_PARAMETERS); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); std::sprintf(fTmpBuf, "%i\n", options.maxParameters); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UI_BRIDGES_TIMEOUT); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); std::sprintf(fTmpBuf, "%i\n", options.uiBridgesTimeout); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_BINARIES); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg("true\n", 5); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage("true\n", 5); std::sprintf(fTmpBuf, "%s\n", options.binaryDir); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_RESOURCES); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg("true\n", 5); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage("true\n", 5); std::sprintf(fTmpBuf, "%s\n", options.resourceDir); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); } // ------------------------------------------------------------------- @@ -1413,10 +1420,9 @@ protected: { if (show) { - if (fUiServer.isRunning()) + if (fUiServer.isPipeRunning()) { - fUiServer.writeMsg("focus\n", 6); - fUiServer.flush(); + fUiServer.writeFocusMessage(); return; } @@ -1432,13 +1438,13 @@ protected: carla_stdout("Trying to start carla-plugin using \"%s\"", path.buffer()); fUiServer.setData(path, pData->sampleRate, pHost->uiName); - fUiServer.start(false); + fUiServer.startPipeServer(false); uiServerInfo(); uiServerOptions(); uiServerCallback(ENGINE_CALLBACK_ENGINE_STARTED, 0, pData->options.processMode, pData->options.transportMode, 0.0f, "Plugin"); - fUiServer.show(); + fUiServer.writeShowMessage(); for (uint i=0; i < pData->curPluginCount; ++i) { @@ -1455,41 +1461,41 @@ protected: } else { - fUiServer.stop(5000); + fUiServer.stopPipeServer(5000); } } void uiIdle() { CarlaEngine::idle(); - fUiServer.idle(); + fUiServer.idlePipe(); - if (fUiServer.isRunning()) + if (fUiServer.isPipeRunning()) { const EngineTimeInfo& timeInfo(pData->timeInfo); - const CarlaMutexLocker cml(fUiServer.getLock()); + const CarlaMutexLocker cml(fUiServer.getPipeLock()); const ScopedLocale csl; #ifndef CARLA_OS_WIN // FIXME // send transport - fUiServer.writeAndFixMsg("transport"); - fUiServer.writeMsg(timeInfo.playing ? "true\n" : "false\n"); + fUiServer.writeAndFixMessage("transport"); + fUiServer.writeMessage(timeInfo.playing ? "true\n" : "false\n"); if (timeInfo.valid & EngineTimeInfo::kValidBBT) { std::sprintf(fTmpBuf, P_UINT64 ":%i:%i:%i\n", timeInfo.frame, timeInfo.bbt.bar, timeInfo.bbt.beat, timeInfo.bbt.tick); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%f\n", timeInfo.bbt.beatsPerMinute); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); } else { std::sprintf(fTmpBuf, P_UINT64 ":0:0:0\n", timeInfo.frame); - fUiServer.writeMsg(fTmpBuf); - fUiServer.writeMsg("0.0\n"); + fUiServer.writeMessage(fTmpBuf); + fUiServer.writeMessage("0.0\n"); } - fUiServer.flush(); + fUiServer.flushMessages(); #endif // send peaks and param outputs for all plugins @@ -1499,11 +1505,11 @@ protected: const CarlaPlugin* const plugin(pData->plugins[i].plugin); std::sprintf(fTmpBuf, "PEAKS_%i\n", i); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%f:%f:%f:%f\n", plugData.insPeak[0], plugData.insPeak[1], plugData.outsPeak[0], plugData.outsPeak[1]); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); for (uint32_t j=0, count=plugin->getParameterCount(); j < count; ++j) { @@ -1511,10 +1517,10 @@ protected: continue; std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", i, j); - fUiServer.writeMsg(fTmpBuf); + fUiServer.writeMessage(fTmpBuf); std::sprintf(fTmpBuf, "%f\n", plugin->getParameterValue(j)); - fUiServer.writeMsg(fTmpBuf); - fUiServer.flush(); + fUiServer.writeMessage(fTmpBuf); + fUiServer.flushMessages(); } } } @@ -1529,7 +1535,7 @@ protected: break; case CarlaExternalUI::UiHide: pHost->ui_closed(pHost->handle); - fUiServer.stop(2000); + fUiServer.stopPipeServer(2000); break; } } @@ -1546,6 +1552,15 @@ protected: void setState(const char* const data) { + // remove all plugins first, no lock + fIsRunning = false; + removeAllPlugins(); + fIsRunning = true; + + // stopped during removeAllPlugins() + if (! pData->thread.isThreadRunning()) + pData->thread.startThread(); + fOptionsForced = true; const String state(data); XmlDocument xml(state); diff --git a/source/backend/engine/Makefile b/source/backend/engine/Makefile index 07097c053..4f1569bab 100644 --- a/source/backend/engine/Makefile +++ b/source/backend/engine/Makefile @@ -82,6 +82,7 @@ $(OBJDIR)/%.cpp.o: %.cpp @echo "Compiling $<" @$(CXX) $< $(BUILD_CXX_FLAGS) -MMD -c -o $@ --include $(OBJS:%.o=%.d) +-include $(OBJSa:%.o=%.d) +-include $(OBJDIR)/CarlaEngineNative.cpp.exp.d # ---------------------------------------------------------------------------------------------------------------------------- diff --git a/source/carla_host.py b/source/carla_host.py index dd6fd47ca..0d6195173 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -2030,7 +2030,7 @@ def initHost(initName, libPrefixOrPluginClass, isControl, isPlugin, failError): gCarla.utils = CarlaUtils(os.path.join(pathBinaries, utilsname)) gCarla.utils.set_process_name(initName) - gCarla.utils.set_locale_C() + #gCarla.utils.set_locale_C() # -------------------------------------------------------------------------------------------------------- # Done diff --git a/source/externalui.py b/source/externalui.py index 44744ce56..edf54646b 100755 --- a/source/externalui.py +++ b/source/externalui.py @@ -105,6 +105,9 @@ class ExternalUI(object): def uiShow(self): return + def uiFocus(self): + return + def uiHide(self): return @@ -149,6 +152,9 @@ class ExternalUI(object): elif msg == "show": self.uiShow() + elif msg == "focus": + self.uiFocus() + elif msg == "hide": self.uiHide() diff --git a/source/modules/CarlaNativeExtUI.hpp b/source/modules/CarlaNativeExtUI.hpp index ccca2c385..e218e14e8 100644 --- a/source/modules/CarlaNativeExtUI.hpp +++ b/source/modules/CarlaNativeExtUI.hpp @@ -47,10 +47,10 @@ protected: { if (show) { - if (isRunning()) + if (isPipeRunning()) { - writeMsg("focus\n", 6); - flush(); + writeMessage("focus\n", 6); + flushMessages(); return; } @@ -58,17 +58,17 @@ protected: carla_stdout("Trying to start UI using \"%s\"", path.buffer()); CarlaExternalUI::setData(path, getSampleRate(), getUiName()); - CarlaExternalUI::start(); + CarlaExternalUI::startPipeServer(); } else { - CarlaExternalUI::stop(5000); + CarlaExternalUI::stopPipeServer(5000); } } void uiIdle() override { - CarlaExternalUI::idle(); + CarlaExternalUI::idlePipe(); switch (CarlaExternalUI::getAndResetUiState()) { @@ -80,7 +80,7 @@ protected: break; case CarlaExternalUI::UiHide: uiClosed(); - CarlaExternalUI::stop(2000); + CarlaExternalUI::stopPipeServer(2000); break; } } @@ -90,15 +90,22 @@ protected: CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),); char tmpBuf[0xff+1]; + tmpBuf[0xff] = '\0'; - const CarlaMutexLocker cml(getLock()); + const CarlaMutexLocker cml(getPipeLock()); + const ScopedLocale csl; - writeMsg("control\n", 8); - std::sprintf(tmpBuf, "%i\n", index); - writeMsg(tmpBuf); - std::sprintf(tmpBuf, "%f\n", value); - writeMsg(tmpBuf); - flush(); + writeMessage("control\n", 8); + + { + std::snprintf(tmpBuf, 0xff, "%i\n", index); + writeMessage(tmpBuf); + + std::snprintf(tmpBuf, 0xff, "%f\n", value); + writeMessage(tmpBuf); + } + + flushMessages(); } void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) override @@ -106,17 +113,24 @@ protected: CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); char tmpBuf[0xff+1]; + tmpBuf[0xff] = '\0'; + + const CarlaMutexLocker cml(getPipeLock()); - const CarlaMutexLocker cml(getLock()); + writeMessage("program\n", 8); - writeMsg("program\n", 8); - std::sprintf(tmpBuf, "%i\n", channel); - writeMsg(tmpBuf); - std::sprintf(tmpBuf, "%i\n", bank); - writeMsg(tmpBuf); - std::sprintf(tmpBuf, "%i\n", program); - writeMsg(tmpBuf); - flush(); + { + std::snprintf(tmpBuf, 0xff, "%i\n", channel); + writeMessage(tmpBuf); + + std::snprintf(tmpBuf, 0xff, "%i\n", bank); + writeMessage(tmpBuf); + + std::snprintf(tmpBuf, 0xff, "%i\n", program); + writeMessage(tmpBuf); + } + + flushMessages(); } void uiSetCustomData(const char* const key, const char* const value) override @@ -124,12 +138,14 @@ protected: CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(value != nullptr,); - const CarlaMutexLocker cml(getLock()); + const CarlaMutexLocker cml(getPipeLock()); + + writeMessage("configure\n", 10); + + writeAndFixMessage(key); + writeAndFixMessage(value); - writeMsg("configure\n", 10); - writeAndFixMsg(key); - writeAndFixMsg(value); - flush(); + flushMessages(); } // ------------------------------------------------------------------- diff --git a/source/modules/native-plugins/resources/bigmeter-ui b/source/modules/native-plugins/resources/bigmeter-ui index 533b5e010..e0a67a0f7 100755 --- a/source/modules/native-plugins/resources/bigmeter-ui +++ b/source/modules/native-plugins/resources/bigmeter-ui @@ -16,6 +16,19 @@ # # For a full copy of the GNU General Public License see the doc/GPL.txt file. +# ------------------------------------------------------------------------------------------------------------ +# Imports (Config) + +from carla_config import * + +# ------------------------------------------------------------------------------------------------------------ +# Imports (Global) + +if config_UseQt5: + from PyQt5.QtCore import Qt +else: + from PyQt4.QtCore import Qt + # ----------------------------------------------------------------------- # Imports (Custom) @@ -81,6 +94,13 @@ class DistrhoUIBigMeter(ExternalUI, DigitalPeakMeter): def uiShow(self): self.show() + def uiFocus(self): + self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) + self.show() + + self.raise_() + self.activateWindow() + def uiHide(self): self.hide() @@ -110,8 +130,8 @@ if __name__ == '__main__': pathBinaries, pathResources = getPaths() gCarla.utils = CarlaUtils(os.path.join(pathBinaries, "libcarla_utils." + DLL_EXTENSION)) - gCarla.utils.set_locale_C() gCarla.utils.set_process_name("BigMeter") + #gCarla.utils.set_locale_C() app = CarlaApplication("BigMeter") gui = DistrhoUIBigMeter() diff --git a/source/modules/native-plugins/resources/carla-plugin b/source/modules/native-plugins/resources/carla-plugin index 2808de1c7..8986949ff 100755 --- a/source/modules/native-plugins/resources/carla-plugin +++ b/source/modules/native-plugins/resources/carla-plugin @@ -91,12 +91,24 @@ class CarlaMiniW(ExternalUI, HostWindow): # ExternalUI Callbacks def uiShow(self): - if self.parent() is None: - self.show() + if self.parent() is not None: + return + self.show() + + def uiFocus(self): + if self.parent() is not None: + return + + self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) + self.show() + + self.raise_() + self.activateWindow() def uiHide(self): - if self.parent() is None: - self.hide() + if self.parent() is not None: + return + self.hide() def uiQuit(self): self.closeExternalUI() @@ -340,6 +352,9 @@ class CarlaMiniW(ExternalUI, HostWindow): self.fFirstInit = False self.uiShow() + elif msg == "focus": + self.uiFocus() + elif msg == "hide": self.uiHide() diff --git a/source/modules/native-plugins/resources/notes-ui b/source/modules/native-plugins/resources/notes-ui index ac21b3de7..05eaa8ce7 100755 --- a/source/modules/native-plugins/resources/notes-ui +++ b/source/modules/native-plugins/resources/notes-ui @@ -25,10 +25,10 @@ from carla_config import * # Imports (Global) if config_UseQt5: - from PyQt5.QtCore import pyqtSlot + from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtWidgets import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget else: - from PyQt4.QtCore import pyqtSlot + from PyQt4.QtCore import pyqtSlot, Qt from PyQt4.QtGui import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget # ----------------------------------------------------------------------- @@ -196,6 +196,13 @@ class DistrhoUINotes(ExternalUI, QWidget): def uiShow(self): self.show() + def uiFocus(self): + self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) + self.show() + + self.raise_() + self.activateWindow() + def uiHide(self): self.hide() @@ -243,8 +250,8 @@ if __name__ == '__main__': pathBinaries, pathResources = getPaths() gCarla.utils = CarlaUtils(os.path.join(pathBinaries, "libcarla_utils." + DLL_EXTENSION)) - gCarla.utils.set_locale_C() gCarla.utils.set_process_name("Notes") + #gCarla.utils.set_locale_C() app = CarlaApplication("Notes") gui = DistrhoUINotes() diff --git a/source/utils/CarlaExternalUI.hpp b/source/utils/CarlaExternalUI.hpp index 073212f4a..2876d1c54 100644 --- a/source/utils/CarlaExternalUI.hpp +++ b/source/utils/CarlaExternalUI.hpp @@ -59,16 +59,16 @@ public: fUiTitle = uiTitle; } - void start(const bool show = true) noexcept + void startPipeServer(const bool show = true) noexcept { - CarlaPipeServer::start(fFilename, fSampleRate, fUiTitle); + CarlaPipeServer::startPipeServer(fFilename, fSampleRate, fUiTitle); if (! show) return; - const CarlaMutexLocker cml(getLock()); - writeMsg("show\n", 5); - flush(); + const CarlaMutexLocker cml(getPipeLock()); + writeMessage("show\n", 5); + flushMessages(); } protected: @@ -77,7 +77,7 @@ protected: { if (std::strcmp(msg, "exiting") == 0) { - close(); + closePipeServer(); fUiState = UiHide; return true; } diff --git a/source/utils/CarlaPipeUtils.cpp b/source/utils/CarlaPipeUtils.cpp index 018ec5c9a..4625c76b2 100644 --- a/source/utils/CarlaPipeUtils.cpp +++ b/source/utils/CarlaPipeUtils.cpp @@ -470,13 +470,18 @@ CarlaPipeCommon::~CarlaPipeCommon() noexcept // ------------------------------------------------------------------- -void CarlaPipeCommon::idle() noexcept +bool CarlaPipeCommon::isPipeRunning() const noexcept +{ + return (pData->pipeRecv != INVALID_PIPE_VALUE && pData->pipeSend != INVALID_PIPE_VALUE); +} + +void CarlaPipeCommon::idlePipe() noexcept { const char* locale = nullptr; for (;;) { - const char* const msg(readline()); + const char* const msg(_readline()); if (msg == nullptr) break; @@ -505,29 +510,24 @@ void CarlaPipeCommon::idle() noexcept } } -bool CarlaPipeCommon::isRunning() const noexcept -{ - return (pData->pipeRecv != INVALID_PIPE_VALUE && pData->pipeSend != INVALID_PIPE_VALUE); -} - // ------------------------------------------------------------------- -void CarlaPipeCommon::lock() const noexcept +void CarlaPipeCommon::lockPipe() const noexcept { pData->writeLock.lock(); } -bool CarlaPipeCommon::tryLock() const noexcept +bool CarlaPipeCommon::tryLockPipe() const noexcept { return pData->writeLock.tryLock(); } -void CarlaPipeCommon::unlock() const noexcept +void CarlaPipeCommon::unlockPipe() const noexcept { pData->writeLock.unlock(); } -CarlaMutex& CarlaPipeCommon::getLock() noexcept +CarlaMutex& CarlaPipeCommon::getPipeLock() noexcept { return pData->writeLock; } @@ -538,7 +538,7 @@ bool CarlaPipeCommon::readNextLineAsBool(bool& value) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); - if (const char* const msg = readlineblock()) + if (const char* const msg = _readlineblock()) { value = (std::strcmp(msg, "true") == 0); delete[] msg; @@ -552,7 +552,7 @@ bool CarlaPipeCommon::readNextLineAsInt(int32_t& value) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); - if (const char* const msg = readlineblock()) + if (const char* const msg = _readlineblock()) { value = std::atoi(msg); delete[] msg; @@ -566,7 +566,7 @@ bool CarlaPipeCommon::readNextLineAsUInt(uint32_t& value) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); - if (const char* const msg = readlineblock()) + if (const char* const msg = _readlineblock()) { int32_t tmp = std::atoi(msg); delete[] msg; @@ -585,7 +585,7 @@ bool CarlaPipeCommon::readNextLineAsLong(int64_t& value) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); - if (const char* const msg = readlineblock()) + if (const char* const msg = _readlineblock()) { value = std::atol(msg); delete[] msg; @@ -599,7 +599,7 @@ bool CarlaPipeCommon::readNextLineAsULong(uint64_t& value) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); - if (const char* const msg = readlineblock()) + if (const char* const msg = _readlineblock()) { int64_t tmp = std::atol(msg); delete[] msg; @@ -618,7 +618,7 @@ bool CarlaPipeCommon::readNextLineAsFloat(float& value) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); - if (const char* const msg = readlineblock()) + if (const char* const msg = _readlineblock()) { value = static_cast(std::atof(msg)); delete[] msg; @@ -632,7 +632,7 @@ bool CarlaPipeCommon::readNextLineAsDouble(double& value) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); - if (const char* const msg = readlineblock()) + if (const char* const msg = _readlineblock()) { value = std::atof(msg); delete[] msg; @@ -646,7 +646,7 @@ bool CarlaPipeCommon::readNextLineAsString(const char*& value) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); - if (const char* const msg = readlineblock()) + if (const char* const msg = _readlineblock()) { value = msg; return true; @@ -658,7 +658,7 @@ bool CarlaPipeCommon::readNextLineAsString(const char*& value) noexcept // ------------------------------------------------------------------- // must be locked before calling -bool CarlaPipeCommon::writeMsg(const char* const msg) const noexcept +bool CarlaPipeCommon::writeMessage(const char* const msg) const noexcept { CARLA_SAFE_ASSERT_RETURN(msg != nullptr && msg[0] != '\0', false); @@ -666,19 +666,19 @@ bool CarlaPipeCommon::writeMsg(const char* const msg) const noexcept CARLA_SAFE_ASSERT_RETURN(size > 0, false); CARLA_SAFE_ASSERT_RETURN(msg[size-1] == '\n', false); - return writeMsgBuffer(msg, size); + return _writeMsgBuffer(msg, size); } -bool CarlaPipeCommon::writeMsg(const char* const msg, std::size_t size) const noexcept +bool CarlaPipeCommon::writeMessage(const char* const msg, std::size_t size) const noexcept { CARLA_SAFE_ASSERT_RETURN(msg != nullptr && msg[0] != '\0', false); CARLA_SAFE_ASSERT_RETURN(size > 0, false); CARLA_SAFE_ASSERT_RETURN(msg[size-1] == '\n', false); - return writeMsgBuffer(msg, size); + return _writeMsgBuffer(msg, size); } -bool CarlaPipeCommon::writeAndFixMsg(const char* const msg) const noexcept +bool CarlaPipeCommon::writeAndFixMessage(const char* const msg) const noexcept { CARLA_SAFE_ASSERT_RETURN(msg != nullptr, false); @@ -714,10 +714,10 @@ bool CarlaPipeCommon::writeAndFixMsg(const char* const msg) const noexcept fixedMsg[1] = '\0'; } - return writeMsgBuffer(fixedMsg, size+1); + return _writeMsgBuffer(fixedMsg, size+1); } -bool CarlaPipeCommon::flush() const noexcept +bool CarlaPipeCommon::flushMessages() const noexcept { // TESTING remove later (replace with trylock scope) if (pData->writeLock.tryLock()) @@ -741,7 +741,7 @@ bool CarlaPipeCommon::flush() const noexcept // ------------------------------------------------------------------- // internal -const char* CarlaPipeCommon::readline() noexcept +const char* CarlaPipeCommon::_readline() noexcept { CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv != INVALID_PIPE_VALUE, nullptr); @@ -797,13 +797,13 @@ const char* CarlaPipeCommon::readline() noexcept return nullptr; } -const char* CarlaPipeCommon::readlineblock(const uint32_t timeOutMilliseconds) noexcept +const char* CarlaPipeCommon::_readlineblock(const uint32_t timeOutMilliseconds) noexcept { const uint32_t timeoutEnd(juce::Time::getMillisecondCounter() + timeOutMilliseconds); for (;;) { - if (const char* const msg = readline()) + if (const char* const msg = _readline()) return msg; if (juce::Time::getMillisecondCounter() >= timeoutEnd) @@ -816,7 +816,7 @@ const char* CarlaPipeCommon::readlineblock(const uint32_t timeOutMilliseconds) n return nullptr; } -bool CarlaPipeCommon::writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept +bool CarlaPipeCommon::_writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept { // TESTING remove later (replace with trylock scope) if (pData->writeLock.tryLock()) @@ -854,12 +854,12 @@ CarlaPipeServer::~CarlaPipeServer() noexcept { carla_debug("CarlaPipeServer::~CarlaPipeServer()"); - stop(5*1000); + stopPipeServer(5*1000); } // ----------------------------------------------------------------------- -bool CarlaPipeServer::start(const char* const filename, const char* const arg1, const char* const arg2) noexcept +bool CarlaPipeServer::startPipeServer(const char* const filename, const char* const arg1, const char* const arg2) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv == INVALID_PIPE_VALUE, false); CARLA_SAFE_ASSERT_RETURN(pData->pipeSend == INVALID_PIPE_VALUE, false); @@ -872,7 +872,7 @@ bool CarlaPipeServer::start(const char* const filename, const char* const arg1, CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false); CARLA_SAFE_ASSERT_RETURN(arg1 != nullptr, false); CARLA_SAFE_ASSERT_RETURN(arg2 != nullptr, false); - carla_debug("CarlaPipeServer::start(\"%s\", \"%s\", \"%s\")", filename, arg1, arg2); + carla_debug("CarlaPipeServer::startPipeServer(\"%s\", \"%s\", \"%s\")", filename, arg1, arg2); const CarlaMutexLocker cml(pData->writeLock); @@ -1108,9 +1108,9 @@ bool CarlaPipeServer::start(const char* const filename, const char* const arg1, return false; } -void CarlaPipeServer::stop(const uint32_t timeOutMilliseconds) noexcept +void CarlaPipeServer::stopPipeServer(const uint32_t timeOutMilliseconds) noexcept { - carla_debug("CarlaPipeServer::stop(%i)", timeOutMilliseconds); + carla_debug("CarlaPipeServer::stopPipeServer(%i)", timeOutMilliseconds); #ifdef CARLA_OS_WIN if (pData->processInfo.hProcess != INVALID_HANDLE_VALUE) @@ -1118,7 +1118,7 @@ void CarlaPipeServer::stop(const uint32_t timeOutMilliseconds) noexcept const CarlaMutexLocker cml(pData->writeLock); if (pData->pipeSend != INVALID_PIPE_VALUE) - writeMsgBuffer("quit\n", 5); + _writeMsgBuffer("quit\n", 5); waitForProcessToStopOrKillIt(pData->processInfo, timeOutMilliseconds); try { CloseHandle(pData->processInfo.hThread); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->processInfo.hThread)"); @@ -1131,19 +1131,19 @@ void CarlaPipeServer::stop(const uint32_t timeOutMilliseconds) noexcept const CarlaMutexLocker cml(pData->writeLock); if (pData->pipeSend != INVALID_PIPE_VALUE) - writeMsgBuffer("quit\n", 5); + _writeMsgBuffer("quit\n", 5); waitForChildToStopOrKillIt(pData->pid, timeOutMilliseconds); pData->pid = -1; } #endif - close(); + closePipeServer(); } -void CarlaPipeServer::close() noexcept +void CarlaPipeServer::closePipeServer() noexcept { - carla_debug("CarlaPipeServer::close()"); + carla_debug("CarlaPipeServer::closePipeServer()"); const CarlaMutexLocker cml(pData->writeLock); @@ -1181,13 +1181,14 @@ CarlaPipeClient::~CarlaPipeClient() noexcept { carla_debug("CarlaPipeClient::~CarlaPipeClient()"); - close(); + closePipeClient(); } -bool CarlaPipeClient::init(const char* argv[]) noexcept +bool CarlaPipeClient::initPipeClient(const char* argv[]) noexcept { CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv == INVALID_PIPE_VALUE, false); CARLA_SAFE_ASSERT_RETURN(pData->pipeSend == INVALID_PIPE_VALUE, false); + carla_debug("CarlaPipeClient::initPipeClient(%p)", argv); const CarlaMutexLocker cml(pData->writeLock); @@ -1248,15 +1249,15 @@ bool CarlaPipeClient::init(const char* argv[]) noexcept pData->pipeRecv = pipeRecvServer; pData->pipeSend = pipeSendServer; - writeMsg("\n"); - flush(); + writeMessage("\n", 1); + flushMessages(); return true; } -void CarlaPipeClient::close() noexcept +void CarlaPipeClient::closePipeClient() noexcept { - carla_debug("CarlaPipeClient::close()"); + carla_debug("CarlaPipeClient::closePipeClient()"); const CarlaMutexLocker cml(pData->writeLock); diff --git a/source/utils/CarlaPipeUtils.hpp b/source/utils/CarlaPipeUtils.hpp index f2f907539..f634a998f 100644 --- a/source/utils/CarlaPipeUtils.hpp +++ b/source/utils/CarlaPipeUtils.hpp @@ -22,53 +22,141 @@ #include "CarlaMutex.hpp" // ----------------------------------------------------------------------- +// CarlaPipeCommon class class CarlaPipeCommon { protected: + /*! + * Constructor. + */ CarlaPipeCommon() noexcept; + + /*! + * Destructor. + */ virtual ~CarlaPipeCommon() noexcept; - // returns true if msg handled + /*! + * A message has been received (in the context of idlePipe()). + * If extra data is required, use any of the readNextLineAs* functions. + * Returning true means the message has been handled and should not propagate to subclasses. + */ virtual bool msgReceived(const char* const msg) noexcept = 0; - // to possibly send errors somewhere + /*! + * An error has occurred during the current requested operation. + * Reimplementing this method allows to catch these errors as strings. + * By default the error is simply printed to stderr. + */ virtual void fail(const char* const error) noexcept { carla_stderr2(error); } public: - void idle() noexcept; - bool isRunning() const noexcept; + /*! + * Check if the pipe is running. + */ + bool isPipeRunning() const noexcept; + + /*! + * Check the pipe for new messages and send them to msgReceived(). + */ + void idlePipe() noexcept; // ------------------------------------------------------------------- // write lock - void lock() const noexcept; - bool tryLock() const noexcept; - void unlock() const noexcept; + /*! + * Lock the pipe write mutex. + */ + void lockPipe() const noexcept; + + /*! + * Try locking the pipe write mutex. + * Returns true if successful. + */ + bool tryLockPipe() const noexcept; - CarlaMutex& getLock() noexcept; + /*! + * Unlock the pipe write mutex. + */ + void unlockPipe() const noexcept; + + /*! + * Get the pipe write lock. + */ + CarlaMutex& getPipeLock() noexcept; // ------------------------------------------------------------------- + // read lines, must only be called in the context of msgReceived() + /*! + * Read the next line as a boolean. + */ bool readNextLineAsBool(bool& value) noexcept; + + /*! + * Read the next line as an integer. + */ bool readNextLineAsInt(int32_t& value) noexcept; + + /*! + * Read the next line as an unsigned integer. + */ bool readNextLineAsUInt(uint32_t& value) noexcept; + + /*! + * Read the next line as a long integer. + */ bool readNextLineAsLong(int64_t& value) noexcept; + + /*! + * Read the next line as a long unsigned integer. + */ bool readNextLineAsULong(uint64_t& value) noexcept; + + /*! + * Read the next line as a floating point number (single precision). + */ bool readNextLineAsFloat(float& value) noexcept; + + /*! + * Read the next line as a floating point number (double precision). + */ bool readNextLineAsDouble(double& value) noexcept; + + /*! + * Read the next line as a string. + * @note: @a value must be deleted if valid. + */ bool readNextLineAsString(const char*& value) noexcept; // ------------------------------------------------------------------- - // must be locked before calling - - bool writeMsg(const char* const msg) const noexcept; - bool writeMsg(const char* const msg, std::size_t size) const noexcept; - bool writeAndFixMsg(const char* const msg) const noexcept; - bool flush() const noexcept; + // write messages, must be locked before calling + + /*! + * Write a valid message with unknown size. + * A valid message has only one '\n' character and it's at the end. + */ + bool writeMessage(const char* const msg) const noexcept; + + /*! + * Write a valid message with known size. + * A valid message has only one '\n' character and it's at the end. + */ + bool writeMessage(const char* const msg, std::size_t size) const noexcept; + + /*! + * Write and fix a message. + */ + bool writeAndFixMessage(const char* const msg) const noexcept; + + /*! + * Flush all messages currently in cache. + */ + bool flushMessages() const noexcept; // ------------------------------------------------------------------- @@ -78,44 +166,86 @@ protected: // ------------------------------------------------------------------- - // internal - const char* readline() noexcept; - const char* readlineblock(const uint32_t timeOutMilliseconds = 50) noexcept; - bool writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept; + /*! @internal */ + const char* _readline() noexcept; + + /*! @internal */ + const char* _readlineblock(const uint32_t timeOutMilliseconds = 50) noexcept; + + /*! @internal */ + bool _writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeCommon) }; // ----------------------------------------------------------------------- +// CarlaPipeServer class class CarlaPipeServer : public CarlaPipeCommon { public: + /*! + * Constructor. + */ CarlaPipeServer() noexcept; + + /*! + * Destructor. + */ ~CarlaPipeServer() noexcept override; - bool start(const char* const filename, const char* const arg1, const char* const arg2) noexcept; - void stop(const uint32_t timeOutMilliseconds) noexcept; - void close() noexcept; + /*! + * Start the pipe server using @a filename with 2 arguments. + * @see fail() + */ + bool startPipeServer(const char* const filename, const char* const arg1, const char* const arg2) noexcept; + + /*! + * Stop the pipe server. + * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes. + */ + void stopPipeServer(const uint32_t timeOutMilliseconds) noexcept; + + /*! + * Close the pipes without waiting for the child process to terminate. + */ + void closePipeServer() noexcept; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer) }; // ----------------------------------------------------------------------- +// CarlaPipeClient class class CarlaPipeClient : public CarlaPipeCommon { public: + /*! + * Constructor. + */ CarlaPipeClient() noexcept; + + /*! + * Destructor. + */ ~CarlaPipeClient() noexcept override; - bool init(const char* argv[]) noexcept; - void close() noexcept; + /*! + * Initialize the pipes used by a server. + * @a argv must match the arguments set the by server. + */ + bool initPipeClient(const char* argv[]) noexcept; + + /*! + * Close the pipes. + */ + void closePipeClient() noexcept; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient) }; // ----------------------------------------------------------------------- +// ScopedLocale class class ScopedLocale { public: