Browse Source

Make pipe class function names more extensive, add docs; Fix #164

tags/1.9.6
falkTX 11 years ago
parent
commit
150f587815
12 changed files with 481 additions and 270 deletions
  1. +12
    -12
      source/backend/CarlaUtils.cpp
  2. +160
    -145
      source/backend/engine/CarlaEngineNative.cpp
  3. +2
    -1
      source/backend/engine/Makefile
  4. +1
    -1
      source/carla_host.py
  5. +6
    -0
      source/externalui.py
  6. +44
    -28
      source/modules/CarlaNativeExtUI.hpp
  7. +21
    -1
      source/modules/native-plugins/resources/bigmeter-ui
  8. +19
    -4
      source/modules/native-plugins/resources/carla-plugin
  9. +10
    -3
      source/modules/native-plugins/resources/notes-ui
  10. +6
    -6
      source/utils/CarlaExternalUI.hpp
  11. +47
    -46
      source/utils/CarlaPipeUtils.cpp
  12. +153
    -23
      source/utils/CarlaPipeUtils.hpp

+ 12
- 12
source/backend/CarlaUtils.cpp View File

@@ -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;
}



+ 160
- 145
source/backend/engine/CarlaEngineNative.cpp View File

@@ -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; i<count; ++i)
{
@@ -831,72 +838,72 @@ protected:
const ParameterRanges& paramRanges(plugin->getParameterRanges(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; i<count; ++i)
{
std::sprintf(fTmpBuf, "PROGRAM_NAME_%i:%i\n", pluginId, i);
fUiServer.writeMsg(fTmpBuf);
fUiServer.writeMessage(fTmpBuf);
plugin->getProgramName(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; i<count; ++i)
{
std::sprintf(fTmpBuf, "MIDI_PROGRAM_DATA_%i:%i\n", pluginId, i);
fUiServer.writeMsg(fTmpBuf);
fUiServer.writeMessage(fTmpBuf);

const MidiProgramData& mpData(plugin->getMidiProgramData(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);


+ 2
- 1
source/backend/engine/Makefile View File

@@ -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

# ----------------------------------------------------------------------------------------------------------------------------

+ 1
- 1
source/carla_host.py View File

@@ -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


+ 6
- 0
source/externalui.py View File

@@ -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()



+ 44
- 28
source/modules/CarlaNativeExtUI.hpp View File

@@ -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();
}

// -------------------------------------------------------------------


+ 21
- 1
source/modules/native-plugins/resources/bigmeter-ui View File

@@ -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()


+ 19
- 4
source/modules/native-plugins/resources/carla-plugin View File

@@ -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()



+ 10
- 3
source/modules/native-plugins/resources/notes-ui View File

@@ -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()


+ 6
- 6
source/utils/CarlaExternalUI.hpp View File

@@ -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;
}


+ 47
- 46
source/utils/CarlaPipeUtils.cpp View File

@@ -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<float>(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);



+ 153
- 23
source/utils/CarlaPipeUtils.hpp View File

@@ -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:


Loading…
Cancel
Save