Browse Source

Add API to know current project folder

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.2.0-RC1
falkTX 4 years ago
parent
commit
89566a1a0f
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
10 changed files with 209 additions and 38 deletions
  1. +7
    -0
      source/backend/CarlaEngine.hpp
  2. +12
    -0
      source/backend/CarlaHost.h
  3. +24
    -0
      source/backend/CarlaStandalone.cpp
  4. +41
    -3
      source/backend/engine/CarlaEngine.cpp
  5. +1
    -0
      source/backend/engine/CarlaEngineInternal.cpp
  6. +1
    -0
      source/backend/engine/CarlaEngineInternal.hpp
  7. +36
    -12
      source/backend/engine/CarlaEngineNative.cpp
  8. +33
    -14
      source/backend/plugin/CarlaPluginJack.cpp
  9. +51
    -9
      source/backend/plugin/CarlaPluginNative.cpp
  10. +3
    -0
      source/frontend/carla-plugin

+ 7
- 0
source/backend/CarlaEngine.hpp View File

@@ -1060,8 +1060,15 @@ public:
bool saveProject(const char* filename, bool setAsCurrentProject);

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
/*!
* Get the currently set project folder.
* @note Valid for both standalone and plugin versions.
*/
virtual const char* getCurrentProjectFolder() const noexcept;

/*!
* Get the currently set project filename.
* @note Valid only for both standalone version.
*/
const char* getCurrentProjectFilename() const noexcept;



+ 12
- 0
source/backend/CarlaHost.h View File

@@ -528,6 +528,18 @@ CARLA_EXPORT bool carla_load_project(CarlaHostHandle handle, const char* filenam
CARLA_EXPORT bool carla_save_project(CarlaHostHandle handle, const char* filename);

#ifndef BUILD_BRIDGE
/*!
* Get the currently set project folder.
* @note Valid for both standalone and plugin versions.
*/
CARLA_EXPORT const char* carla_get_current_project_folder(CarlaHostHandle handle);

/*!
* Get the currently set project filename.
* @note Valid only for both standalone version.
*/
CARLA_EXPORT const char* carla_get_current_project_filename(CarlaHostHandle handle);

/*!
* Clear the currently set project filename.
*/


+ 24
- 0
source/backend/CarlaStandalone.cpp View File

@@ -944,6 +944,30 @@ bool carla_save_project(CarlaHostHandle handle, const char* filename)
}

#ifndef BUILD_BRIDGE
const char* carla_get_current_project_folder(CarlaHostHandle handle)
{
CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, gNullCharPtr);

carla_debug("carla_get_current_project_folder(%p)", handle);

if (const char* const ret = handle->engine->getCurrentProjectFolder())
return ret;

return gNullCharPtr;
}

const char* carla_get_current_project_filename(CarlaHostHandle handle)
{
CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->isStandalone, gNullCharPtr);

carla_debug("carla_get_current_project_filename(%p)", handle);

if (const char* const ret = handle->engine->getCurrentProjectFilename())
return ret;

return gNullCharPtr;
}

void carla_clear_project_filename(CarlaHostHandle handle)
{
CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);


+ 41
- 3
source/backend/engine/CarlaEngine.cpp View File

@@ -1254,13 +1254,29 @@ bool CarlaEngine::loadProject(const char* const filename, const bool setAsCurren
carla_debug("CarlaEngine::loadProject(\"%s\")", filename);

const String jfilename = String(CharPointer_UTF8(filename));
File file(jfilename);
const File file(jfilename);
CARLA_SAFE_ASSERT_RETURN_ERR(file.existsAsFile(), "Requested file does not exist or is not a readable file");

if (setAsCurrentProject)
{
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
pData->currentProjectFilename = filename;
if (pData->currentProjectFilename != filename)
{
pData->currentProjectFilename = filename;

bool found;
const size_t r = pData->currentProjectFilename.rfind(CARLA_OS_SEP, &found);

if (found)
{
pData->currentProjectFolder = filename;
pData->currentProjectFolder[r] = '\0';
}
else
{
pData->currentProjectFolder.clear();
}
}
#endif
}

@@ -1282,7 +1298,23 @@ bool CarlaEngine::saveProject(const char* const filename, const bool setAsCurren
if (setAsCurrentProject)
{
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
pData->currentProjectFilename = filename;
if (pData->currentProjectFilename != filename)
{
pData->currentProjectFilename = filename;

bool found;
const size_t r = pData->currentProjectFilename.rfind(CARLA_OS_SEP, &found);

if (found)
{
pData->currentProjectFolder = filename;
pData->currentProjectFolder[r] = '\0';
}
else
{
pData->currentProjectFolder.clear();
}
}
#endif
}

@@ -1294,6 +1326,11 @@ bool CarlaEngine::saveProject(const char* const filename, const bool setAsCurren
}

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
const char* CarlaEngine::getCurrentProjectFolder() const noexcept
{
return pData->currentProjectFolder;
}

const char* CarlaEngine::getCurrentProjectFilename() const noexcept
{
return pData->currentProjectFilename;
@@ -1302,6 +1339,7 @@ const char* CarlaEngine::getCurrentProjectFilename() const noexcept
void CarlaEngine::clearCurrentProjectFilename() noexcept
{
pData->currentProjectFilename.clear();
pData->currentProjectFolder.clear();
}
#endif



+ 1
- 0
source/backend/engine/CarlaEngineInternal.cpp View File

@@ -386,6 +386,7 @@ CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine)
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
loadingProject(false),
currentProjectFilename(),
currentProjectFolder(),
#endif
bufferSize(0),
sampleRate(0.0),


+ 1
- 0
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -247,6 +247,7 @@ struct CarlaEngine::ProtectedData {
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
bool loadingProject;
CarlaString currentProjectFilename;
CarlaString currentProjectFolder;
#endif

uint32_t bufferSize;


+ 36
- 12
source/backend/engine/CarlaEngineNative.cpp View File

@@ -184,6 +184,7 @@ public:
fIsRunning(false),
fUiServer(this),
fLastScaleFactor(1.0f),
fLastProjectFolder(),
fOptionsForced(false)
{
carla_debug("CarlaEngineNative::CarlaEngineNative()");
@@ -319,6 +320,21 @@ public:
return "Plugin";
}

const char* getCurrentProjectFolder() const noexcept override
{
CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, nullptr);

static char filetype[] = "carla\0";

try {
return (const char*)(uintptr_t)pHost->dispatcher(pHost->handle,
NATIVE_HOST_OPCODE_GET_FILE_PATH,
0, 0,
(void*)filetype,
0.0f);
} CARLA_SAFE_EXCEPTION_RETURN("get_file_path", nullptr);
}

void callback(const bool sendHost, const bool sendOsc,
const EngineCallbackOpcode action, const uint pluginId,
const int value1, const int value2, const int value3,
@@ -420,7 +436,7 @@ protected:
{
const CarlaMutexLocker cml(fUiServer.getPipeLock());

if (fUiServer.writeAndFixMessage("buffer-size"))
if (fUiServer.writeMessage("buffer-size\n"))
{
char tmpBuf[STR_MAX+1];
carla_zeroChars(tmpBuf, STR_MAX+1);
@@ -444,7 +460,7 @@ protected:
{
const CarlaMutexLocker cml(fUiServer.getPipeLock());

if (fUiServer.writeAndFixMessage("sample-rate"))
if (fUiServer.writeMessage("sample-rate\n"))
{
char tmpBuf[STR_MAX+1];
carla_zeroChars(tmpBuf, STR_MAX+1);
@@ -485,8 +501,7 @@ protected:

if (const char* const filename = plugin->getFilename())
{
std::snprintf(tmpBuf, STR_MAX, "%s", filename);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(filename),);
}
else
{
@@ -495,8 +510,7 @@ protected:

if (const char* const name = plugin->getName())
{
std::snprintf(tmpBuf, STR_MAX, "%s", name);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(name),);
}
else
{
@@ -505,8 +519,7 @@ protected:

if (const char* const iconName = plugin->getIconName())
{
std::snprintf(tmpBuf, STR_MAX, "%s", iconName);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(iconName),);
}
else
{
@@ -680,8 +693,7 @@ protected:
std::snprintf(tmpBuf, STR_MAX, "%i:%i\n", mpData.bank, mpData.program);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);

std::snprintf(tmpBuf, STR_MAX, "%s", mpData.name);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(mpData.name),);
}

fUiServer.flushMessages();
@@ -1409,16 +1421,27 @@ protected:
// ------------------------------------------------------------------------------------------------------------
// send engine info

CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage("runtime-info"),);
std::snprintf(tmpBuf, STR_MAX, "%.12g:0\n", static_cast<double>(getDSPLoad()));
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("runtime-info\n"),);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);

fUiServer.flushMessages();

if (const char* const projFolder = getCurrentProjectFolder())
{
if (fLastProjectFolder != projFolder)
{
fLastProjectFolder = projFolder;
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("project-folder\n"),);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(projFolder),);
fUiServer.flushMessages();
}
}

// ------------------------------------------------------------------------------------------------------------
// send transport

CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage("transport"),);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("transport\n"),);
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(timeInfo.playing ? "true\n" : "false\n"),);

if (timeInfo.bbt.valid)
@@ -1676,6 +1699,7 @@ private:

float fParameters[kNumInParams+kNumOutParams];
float fLastScaleFactor;
CarlaString fLastProjectFolder;

bool fOptionsForced;



+ 33
- 14
source/backend/plugin/CarlaPluginJack.cpp View File

@@ -164,6 +164,11 @@ public:
return ret.releaseBufferPointer();
}

const CarlaString& getAppName() const noexcept
{
return fProject.appName;
}

protected:
#ifdef HAVE_LIBLO
static void _osc_error_handler(int num, const char* msg, const char* path)
@@ -184,7 +189,9 @@ protected:
if (fSetupLabel.length() <= 6)
return;

if (fProject.path.isNotEmpty() || fProject.init(kEngine->getCurrentProjectFilename(), &fSetupLabel[6]))
if (fProject.path.isNotEmpty() || fProject.init(kPlugin->getName(),
kEngine->getCurrentProjectFolder(),
&fSetupLabel[6]))
{
carla_stdout("Sending open signal %s %s %s",
fProject.path.buffer(), fProject.display.buffer(), fProject.clientName.buffer());
@@ -465,17 +472,23 @@ private:
display(),
clientName() {}

bool init(const char* const engineProjectFilename, const char* const uniqueCodeID)
bool init(const char* const pluginName,
const char* const engineProjectFolder,
const char* const uniqueCodeID)
{
CARLA_SAFE_ASSERT_RETURN(engineProjectFilename != nullptr && engineProjectFilename[0] != '\0', false);
CARLA_SAFE_ASSERT_RETURN(engineProjectFolder != nullptr && engineProjectFolder[0] != '\0', false);
CARLA_SAFE_ASSERT_RETURN(uniqueCodeID != nullptr && uniqueCodeID[0] != '\0', false);
CARLA_SAFE_ASSERT_RETURN(appName.isNotEmpty(), false);

const File file(File(engineProjectFilename).withFileExtension(uniqueCodeID));
String child(pluginName);
child += ".";
child += uniqueCodeID;

const File file(File(engineProjectFolder).getChildFile(child));

clientName = appName + "." + uniqueCodeID;
path = file.getFullPathName().toRawUTF8();
display = file.getFileNameWithoutExtension().toRawUTF8();
clientName = appName + "." + uniqueCodeID;

return true;
}
@@ -630,8 +643,6 @@ public:
#ifdef HAVE_LIBLO
if (fInfo.setupLabel.length() == 6)
setupUniqueProjectID();

fBridgeThread.nsmSave(fInfo.setupLabel);
#endif

{
@@ -640,6 +651,10 @@ public:
fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPrepareForSave);
fShmNonRtClientControl.commitWrite();
}

#ifdef HAVE_LIBLO
fBridgeThread.nsmSave(fInfo.setupLabel);
#endif
}

// -------------------------------------------------------------------
@@ -1776,19 +1791,20 @@ private:

void setupUniqueProjectID()
{
const char* const engineProjectFilename = pData->engine->getCurrentProjectFilename();
carla_stdout("setupUniqueProjectID %s", engineProjectFilename);
const char* const engineProjectFolder = pData->engine->getCurrentProjectFolder();
carla_stdout("setupUniqueProjectID %s", engineProjectFolder);

if (engineProjectFilename == nullptr || engineProjectFilename[0] == '\0')
if (engineProjectFolder == nullptr || engineProjectFolder[0] == '\0')
return;

const File file(engineProjectFilename);
CARLA_SAFE_ASSERT_RETURN(file.existsAsFile(),);
CARLA_SAFE_ASSERT_RETURN(file.getFileExtension().isNotEmpty(),);
const File file(engineProjectFolder);
CARLA_SAFE_ASSERT_RETURN(file.exists(),);

char code[6];
code[5] = '\0';

String child;

for (;;)
{
static const char* const kValidChars =
@@ -1804,7 +1820,10 @@ private:
code[3] = kValidChars[safe_rand(kValidCharsLen)];
code[4] = kValidChars[safe_rand(kValidCharsLen)];

const File newFile(file.withFileExtension(code));
child = pData->name;
child += ".";
child += code;
const File newFile(file.getChildFile(child));

if (newFile.existsAsFile())
continue;


+ 51
- 9
source/backend/plugin/CarlaPluginNative.cpp View File

@@ -256,6 +256,8 @@ public:
fNeedsIdle(false),
fInlineDisplayNeedsRedraw(false),
fInlineDisplayLastRedrawTime(0),
fLastProjectFilename(),
fLastProjectFolder(),
fAudioAndCvInBuffers(nullptr),
fAudioAndCvOutBuffers(nullptr),
fMidiEventInCount(0),
@@ -2690,70 +2692,107 @@ protected:
carla_debug("CarlaPluginNative::handleDispatcher(%i, %i, " P_INTPTR ", %p, %f)",
opcode, index, value, ptr, static_cast<double>(opt));

intptr_t ret = 0;

switch (opcode)
{
case NATIVE_HOST_OPCODE_NULL:
break;

case NATIVE_HOST_OPCODE_UPDATE_PARAMETER:
// TODO
pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, -1, 0, 0, 0.0f, nullptr);
break;

case NATIVE_HOST_OPCODE_UPDATE_MIDI_PROGRAM:
// TODO
pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, -1, 0, 0, 0.0f, nullptr);
break;

case NATIVE_HOST_OPCODE_RELOAD_PARAMETERS:
reloadParameters(nullptr, nullptr);
pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_ALL, pData->id, -1, 0, 0, 0.0f, nullptr);
break;

case NATIVE_HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
reloadPrograms(false);
pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, -1, 0, 0, 0.0f, nullptr);
break;

case NATIVE_HOST_OPCODE_RELOAD_ALL:
reload();
pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_ALL, pData->id, -1, 0, 0, 0.0f, nullptr);
break;

case NATIVE_HOST_OPCODE_UI_UNAVAILABLE:
pData->engine->callback(true, true, ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0, 0.0f, nullptr);
fIsUiAvailable = false;
break;

case NATIVE_HOST_OPCODE_HOST_IDLE:
pData->engine->callback(true, false, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr);
break;

case NATIVE_HOST_OPCODE_INTERNAL_PLUGIN:
ret = 1;
break;
return 1;
case NATIVE_HOST_OPCODE_QUEUE_INLINE_DISPLAY:
fInlineDisplayNeedsRedraw = true;
break;

case NATIVE_HOST_OPCODE_UI_TOUCH_PARAMETER:
CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);
pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), value != 0);
break;

case NATIVE_HOST_OPCODE_REQUEST_IDLE:
fNeedsIdle = true;
break;

case NATIVE_HOST_OPCODE_GET_FILE_PATH:
CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0);
{
const EngineOptions& opts(pData->engine->getOptions());
const char* const filetype = (const char*)ptr;
const char* ret = nullptr;

if (std::strcmp(filetype, "carla") == 0)
{
ret = pData->engine->getCurrentProjectFilename();

if (std::strcmp(filetype, "audio") == 0)
return static_cast<intptr_t>((uintptr_t)opts.pathAudio);
if (std::strcmp(filetype, "midi") == 0)
return static_cast<intptr_t>((uintptr_t)opts.pathMIDI);
if (fLastProjectFilename != ret)
{
fLastProjectFilename = ret;

bool found;
const size_t r = fLastProjectFilename.rfind(CARLA_OS_SEP, &found);
if (found)
{
fLastProjectFolder = ret;
fLastProjectFolder[r] = '\0';
}
else
{
fLastProjectFolder.clear();
}
}

ret = fLastProjectFolder.buffer();
}

else if (std::strcmp(filetype, "audio") == 0)
ret = opts.pathAudio;
else if (std::strcmp(filetype, "midi") == 0)
ret = opts.pathMIDI;

return static_cast<intptr_t>((uintptr_t)ret);
}
break;

case NATIVE_HOST_OPCODE_UI_RESIZE:
// unused here
break;
}

return ret;
return 0;

// unused for now
(void)opt;
@@ -2956,6 +2995,9 @@ private:
bool fInlineDisplayNeedsRedraw;
int64_t fInlineDisplayLastRedrawTime;

CarlaString fLastProjectFilename;
CarlaString fLastProjectFolder;

float** fAudioAndCvInBuffers;
float** fAudioAndCvOutBuffers;
uint32_t fMidiEventInCount;


+ 3
- 0
source/frontend/carla-plugin View File

@@ -174,6 +174,9 @@ class CarlaMiniW(ExternalUI, HostWindow):
xruns = int(values[1])
self.host._set_runtime_info(load, xruns)

elif msg == "project-folder":
self.fProjectFilename = self.readlineblock()

elif msg == "transport":
playing = self.readlineblock_bool()
frame, bar, beat, tick = [int(i) for i in self.readlineblock().split(":")]


Loading…
Cancel
Save