Browse Source

Convert from and to client name prefix as needed

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.2.0-RC1
falkTX 5 years ago
parent
commit
01c1aed761
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
4 changed files with 118 additions and 76 deletions
  1. +2
    -1
      source/backend/CarlaEngine.hpp
  2. +96
    -55
      source/backend/engine/CarlaEngine.cpp
  3. +7
    -5
      source/backend/engine/CarlaEngineGraph.cpp
  4. +13
    -15
      source/backend/engine/CarlaEngineJack.cpp

+ 2
- 1
source/backend/CarlaEngine.hpp View File

@@ -1368,7 +1368,8 @@ protected:
virtual const char* const* getPatchbayConnections(bool external) const; virtual const char* const* getPatchbayConnections(bool external) const;
virtual const PatchbayPosition* getPatchbayPositions(bool external, uint& count) const; virtual const PatchbayPosition* getPatchbayPositions(bool external, uint& count) const;
virtual void restorePatchbayConnection(bool external, const char* sourcePort, const char* targetPort); virtual void restorePatchbayConnection(bool external, const char* sourcePort, const char* targetPort);
virtual void restorePatchbayGroupPosition(bool external, const PatchbayPosition& ppos);
// returns true if plugin name mapping found, ppos.name updated to its converted name
virtual bool restorePatchbayGroupPosition(bool external, PatchbayPosition& ppos);


/*! /*!
* Virtual functions for handling external graph ports. * Virtual functions for handling external graph ports.


+ 96
- 55
source/backend/engine/CarlaEngine.cpp View File

@@ -44,6 +44,8 @@
#include "water/xml/XmlDocument.h" #include "water/xml/XmlDocument.h"
#include "water/xml/XmlElement.h" #include "water/xml/XmlElement.h"


#include <map>

// FIXME Remove on 2.1 release // FIXME Remove on 2.1 release
#include "lv2/atom.h" #include "lv2/atom.h"


@@ -2355,14 +2357,6 @@ void CarlaEngine::saveProjectInternal(water::MemoryOutputStream& outStream) cons
{ {
saveExternalConnections = false; saveExternalConnections = false;
} }
else if (std::getenv("LADISH_APP_NAME") != nullptr)
{
saveExternalConnections = false;
}
else if (std::getenv("NSM_URL") != nullptr)
{
saveExternalConnections = false;
}
else else
{ {
saveExternalConnections = true; saveExternalConnections = true;
@@ -2524,6 +2518,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
if (carla_isEqual(xmlElement->getDoubleAttribute("VERSION", 0.0), 2.0) || if (carla_isEqual(xmlElement->getDoubleAttribute("VERSION", 0.0), 2.0) ||
xmlElement->getBoolAttribute("IgnoreClientPrefix", false)) xmlElement->getBoolAttribute("IgnoreClientPrefix", false))
{ {
carla_stdout("Loading project in compatibility mode, will ignore client name prefix");
pData->ignoreClientPrefix = true; pData->ignoreClientPrefix = true;
setOption(ENGINE_OPTION_CLIENT_NAME_PREFIX, 0, ""); setOption(ENGINE_OPTION_CLIENT_NAME_PREFIX, 0, "");
} }
@@ -2952,40 +2947,45 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
return false; return false;
} }


bool hasInternalConnections = false;
// now we handle positions
std::map<water::String, water::String> mapGroupNamesInternal, mapGroupNamesExternal;


// and now we handle connections (internal)
if (XmlElement* const elem = xmlElement->getChildByName("Patchbay"))
if (XmlElement* const elemPatchbay = xmlElement->getChildByName("Patchbay"))
{ {
hasInternalConnections = true;

if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
if (XmlElement* const elemPositions = elemPatchbay->getChildByName("Positions"))
{ {
CarlaString sourcePort, targetPort;
String name;
PatchbayPosition ppos = { nullptr, -1, 0, 0, 0, 0, false };


for (XmlElement* patchElem = elem->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement())
for (XmlElement* patchElem = elemPositions->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement())
{ {
const String& patchTag(patchElem->getTagName()); const String& patchTag(patchElem->getTagName());


if (patchTag != "Connection")
if (patchTag != "Position")
continue; continue;


sourcePort.clear();
targetPort.clear();
XmlElement* const patchName = patchElem->getChildByName("Name");
CARLA_SAFE_ASSERT_CONTINUE(patchName != nullptr);


for (XmlElement* connElem = patchElem->getFirstChildElement(); connElem != nullptr; connElem = connElem->getNextElement())
const String nameText(patchName->getAllSubText().trim());
name = xmlSafeString(nameText, false);

ppos.name = name.toRawUTF8();
ppos.x1 = patchElem->getIntAttribute("x1");
ppos.y1 = patchElem->getIntAttribute("y1");
ppos.x2 = patchElem->getIntAttribute("x2");
ppos.y2 = patchElem->getIntAttribute("y2");
ppos.pluginId = patchElem->getIntAttribute("pluginId", -1);
ppos.dealloc = false;

if (name.isNotEmpty() && restorePatchbayGroupPosition(false, ppos))
{ {
const String& tag(connElem->getTagName());
const String text(connElem->getAllSubText().trim());
carla_stdout("Converted client name '%s' to '%s' for this session", name.toRawUTF8(), ppos.name);
mapGroupNamesInternal[name] = ppos.name;


/**/ if (tag == "Source")
sourcePort = xmlSafeString(text, false).toRawUTF8();
else if (tag == "Target")
targetPort = xmlSafeString(text, false).toRawUTF8();
if (ppos.dealloc)
std::free(const_cast<char*>(ppos.name));
} }

if (sourcePort.isNotEmpty() && targetPort.isNotEmpty())
restorePatchbayConnection(false, sourcePort, targetPort);
} }


callback(true, true, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr); callback(true, true, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr);
@@ -3001,8 +3001,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
} }
} }


// now we handle positions
if (XmlElement* const elemPatchbay = xmlElement->getChildByName("Patchbay"))
if (XmlElement* const elemPatchbay = xmlElement->getChildByName("ExternalPatchbay"))
{ {
if (XmlElement* const elemPositions = elemPatchbay->getChildByName("Positions")) if (XmlElement* const elemPositions = elemPatchbay->getChildByName("Positions"))
{ {
@@ -3028,9 +3027,16 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
ppos.x2 = patchElem->getIntAttribute("x2"); ppos.x2 = patchElem->getIntAttribute("x2");
ppos.y2 = patchElem->getIntAttribute("y2"); ppos.y2 = patchElem->getIntAttribute("y2");
ppos.pluginId = patchElem->getIntAttribute("pluginId", -1); ppos.pluginId = patchElem->getIntAttribute("pluginId", -1);
ppos.dealloc = false;

if (name.isNotEmpty() && restorePatchbayGroupPosition(true, ppos))
{
carla_stdout("Converted client name '%s' to '%s' for this session", name.toRawUTF8(), ppos.name);
mapGroupNamesExternal[name] = ppos.name;


if (name.isNotEmpty())
restorePatchbayGroupPosition(false, ppos);
if (ppos.dealloc)
std::free(const_cast<char*>(ppos.name));
}
} }


callback(true, true, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr); callback(true, true, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr);
@@ -3046,35 +3052,60 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
} }
} }


if (XmlElement* const elemPatchbay = xmlElement->getChildByName("ExternalPatchbay"))
bool hasInternalConnections = false;

// and now we handle connections (internal)
if (XmlElement* const elem = xmlElement->getChildByName("Patchbay"))
{ {
if (XmlElement* const elemPositions = elemPatchbay->getChildByName("Positions"))
hasInternalConnections = true;

if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
{ {
String name;
PatchbayPosition ppos = { nullptr, -1, 0, 0, 0, 0, false };
water::String sourcePort, targetPort;


for (XmlElement* patchElem = elemPositions->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement())
for (XmlElement* patchElem = elem->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement())
{ {
const String& patchTag(patchElem->getTagName()); const String& patchTag(patchElem->getTagName());


if (patchTag != "Position")
if (patchTag != "Connection")
continue; continue;


XmlElement* const patchName = patchElem->getChildByName("Name");
CARLA_SAFE_ASSERT_CONTINUE(patchName != nullptr);
sourcePort.clear();
targetPort.clear();


const String nameText(patchName->getAllSubText().trim());
name = xmlSafeString(nameText, false);
for (XmlElement* connElem = patchElem->getFirstChildElement(); connElem != nullptr; connElem = connElem->getNextElement())
{
const String& tag(connElem->getTagName());
const String text(connElem->getAllSubText().trim());


ppos.name = name.toRawUTF8();
ppos.x1 = patchElem->getIntAttribute("x1");
ppos.y1 = patchElem->getIntAttribute("y1");
ppos.x2 = patchElem->getIntAttribute("x2");
ppos.y2 = patchElem->getIntAttribute("y2");
ppos.pluginId = patchElem->getIntAttribute("pluginId", -1);
/**/ if (tag == "Source")
sourcePort = xmlSafeString(text, false);
else if (tag == "Target")
targetPort = xmlSafeString(text, false);
}


if (name.isNotEmpty())
restorePatchbayGroupPosition(true, ppos);
if (sourcePort.isNotEmpty() && targetPort.isNotEmpty())
{
std::map<water::String, water::String>& map(mapGroupNamesInternal);
std::map<water::String, water::String>::iterator it;
if ((it = map.find(sourcePort.upToFirstOccurrenceOf(":", false, false))) != map.end())
sourcePort = it->second + sourcePort.fromFirstOccurrenceOf(":", true, false);
if ((it = map.find(targetPort.upToFirstOccurrenceOf(":", false, false))) != map.end())
targetPort = it->second + targetPort.fromFirstOccurrenceOf(":", true, false);

restorePatchbayConnection(false, sourcePort.toRawUTF8(), targetPort.toRawUTF8());
}
}

callback(true, true, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr);

if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
} }
} }
} }
@@ -3127,7 +3158,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
continue; continue;
} }


CarlaString sourcePort, targetPort;
water::String sourcePort, targetPort;


for (XmlElement* patchElem = elem->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement()) for (XmlElement* patchElem = elem->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement())
{ {
@@ -3145,13 +3176,23 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
const String text(connElem->getAllSubText().trim()); const String text(connElem->getAllSubText().trim());


/**/ if (tag == "Source") /**/ if (tag == "Source")
sourcePort = xmlSafeString(text, false).toRawUTF8();
sourcePort = xmlSafeString(text, false);
else if (tag == "Target") else if (tag == "Target")
targetPort = xmlSafeString(text, false).toRawUTF8();
targetPort = xmlSafeString(text, false);
} }


if (sourcePort.isNotEmpty() && targetPort.isNotEmpty()) if (sourcePort.isNotEmpty() && targetPort.isNotEmpty())
restorePatchbayConnection(loadingAsExternal, sourcePort, targetPort);
{
std::map<water::String, water::String>& map(loadingAsExternal ? mapGroupNamesExternal
: mapGroupNamesInternal);
std::map<water::String, water::String>::iterator it;
if ((it = map.find(sourcePort.upToFirstOccurrenceOf(":", false, false))) != map.end())
sourcePort = it->second + sourcePort.fromFirstOccurrenceOf(":", true, false);
if ((it = map.find(targetPort.upToFirstOccurrenceOf(":", false, false))) != map.end())
targetPort = it->second + targetPort.fromFirstOccurrenceOf(":", true, false);

restorePatchbayConnection(loadingAsExternal, sourcePort.toRawUTF8(), targetPort.toRawUTF8());
}
} }
break; break;
} }


+ 7
- 5
source/backend/engine/CarlaEngineGraph.cpp View File

@@ -2958,21 +2958,23 @@ void CarlaEngine::restorePatchbayConnection(const bool external,
} }
} }


void CarlaEngine::restorePatchbayGroupPosition(const bool external, const PatchbayPosition& ppos)
bool CarlaEngine::restorePatchbayGroupPosition(const bool external, PatchbayPosition& ppos)
{ {
CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(),);
CARLA_SAFE_ASSERT_RETURN(ppos.name != nullptr && ppos.name[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(), false);
CARLA_SAFE_ASSERT_RETURN(ppos.name != nullptr && ppos.name[0] != '\0', false);


if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
{ {
PatchbayGraph* const graph = pData->graph.getPatchbayGraph(); PatchbayGraph* const graph = pData->graph.getPatchbayGraph();
CARLA_SAFE_ASSERT_RETURN(graph != nullptr,);
CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false);


uint groupId; uint groupId;
CARLA_SAFE_ASSERT_RETURN(graph->getGroupFromName(external, ppos.name, groupId),);
CARLA_SAFE_ASSERT_RETURN(graph->getGroupFromName(external, ppos.name, groupId), false);


graph->setGroupPos(true, true, external, groupId, ppos.x1, ppos.y1, ppos.x2, ppos.y2); graph->setGroupPos(true, true, external, groupId, ppos.x1, ppos.y1, ppos.x2, ppos.y2);
} }

return false;
} }


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


+ 13
- 15
source/backend/engine/CarlaEngineJack.cpp View File

@@ -2681,18 +2681,17 @@ public:
} }
} }


void restorePatchbayGroupPosition(const bool external, const PatchbayPosition& ppos) override
bool restorePatchbayGroupPosition(const bool external, PatchbayPosition& ppos) override
{ {
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr,);
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false);
carla_debug("CarlaEngineJack::restorePatchbayGroupPosition(%s, ...)", bool2str(external)); carla_debug("CarlaEngineJack::restorePatchbayGroupPosition(%s, ...)", bool2str(external));


if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! external) if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! external)
return CarlaEngine::restorePatchbayGroupPosition(external, ppos); return CarlaEngine::restorePatchbayGroupPosition(external, ppos);


bool reallocd = false;
bool hasGroups = true; bool hasGroups = true;
uint groupId = 0; uint groupId = 0;
const char* rname = ppos.name;
const char* const orig_name = ppos.name;


/* NOTE: When loading a project, it might take a bit to receive plugins' jack client registration callbacks. /* NOTE: When loading a project, it might take a bit to receive plugins' jack client registration callbacks.
* We try to wait a little for it, but not too much. * We try to wait a little for it, but not too much.
@@ -2700,18 +2699,18 @@ public:
if (ppos.pluginId >= 0) if (ppos.pluginId >= 0)
{ {
// strip client name prefix if already in place // strip client name prefix if already in place
if (const char* const rname2 = std::strstr(rname, "."))
if (const char* const rname2 = std::strstr(ppos.name, "."))
if (const char* const rname3 = std::strstr(rname2, "/")) if (const char* const rname3 = std::strstr(rname2, "/"))
rname = rname3 + 1;
ppos.name = rname3 + 1;


if (fClientNamePrefix.isNotEmpty()) if (fClientNamePrefix.isNotEmpty())
{ {
char* nname = (char*)std::malloc(fClientNamePrefix.length() + std::strlen(rname) + 1);
char* nname = (char*)std::malloc(fClientNamePrefix.length() + std::strlen(ppos.name) + 1);
std::strcpy(nname, fClientNamePrefix.buffer()); std::strcpy(nname, fClientNamePrefix.buffer());
std::strcat(nname, rname);
std::strcat(nname, ppos.name);


reallocd = true;
rname = nname;
ppos.name = nname;
ppos.dealloc = true;
} }


for (int i=10; --i >=0;) for (int i=10; --i >=0;)
@@ -2725,7 +2724,7 @@ public:
break; break;
} }


groupId = fUsedGroups.getGroupId(rname);
groupId = fUsedGroups.getGroupId(ppos.name);
} }


if (groupId != 0) if (groupId != 0)
@@ -2740,7 +2739,7 @@ public:
const CarlaMutexLocker cml(fUsedGroups.mutex); const CarlaMutexLocker cml(fUsedGroups.mutex);


if (fUsedGroups.list.count() != 0) if (fUsedGroups.list.count() != 0)
groupId = fUsedGroups.getGroupId(rname);
groupId = fUsedGroups.getGroupId(ppos.name);
else else
hasGroups = false; hasGroups = false;
} }
@@ -2755,7 +2754,7 @@ public:


jack_uuid_t uuid; jack_uuid_t uuid;
{ {
char* const uuidstr = jackbridge_get_uuid_for_client_name(fClient, rname);
char* const uuidstr = jackbridge_get_uuid_for_client_name(fClient, ppos.name);
CARLA_SAFE_ASSERT_BREAK(uuidstr != nullptr && uuidstr[0] != '\0'); CARLA_SAFE_ASSERT_BREAK(uuidstr != nullptr && uuidstr[0] != '\0');


const bool parsed = jackbridge_uuid_parse(uuidstr, &uuid); const bool parsed = jackbridge_uuid_parse(uuidstr, &uuid);
@@ -2784,8 +2783,7 @@ public:
} }
# endif # endif


if (reallocd)
std::free(const_cast<char*>(rname));
return ppos.name != orig_name;
} }
#endif #endif




Loading…
Cancel
Save