Browse Source

More work for LV2 state path, symlinks and move/copy when needed

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.2.0-RC1
falkTX 5 years ago
parent
commit
720c6fe104
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
3 changed files with 128 additions and 49 deletions
  1. +110
    -49
      source/backend/plugin/CarlaPluginLV2.cpp
  2. +10
    -0
      source/modules/water/files/File.cpp
  3. +8
    -0
      source/modules/water/files/File.h

+ 110
- 49
source/backend/plugin/CarlaPluginLV2.cpp View File

@@ -196,6 +196,7 @@ enum CarlaLv2StateFeatures {
kStateFeatureIdFreePath, kStateFeatureIdFreePath,
kStateFeatureIdMakePath, kStateFeatureIdMakePath,
kStateFeatureIdMapPath, kStateFeatureIdMapPath,
kStateFeatureIdWorker,
kStateFeatureCountAll kStateFeatureCountAll
}; };


@@ -702,6 +703,14 @@ public:
pData->active = false; pData->active = false;
} }


if (fExt.state != nullptr)
{
const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));

if (tmpDir.exists())
tmpDir.deleteRecursively();
}

if (fDescriptor != nullptr) if (fDescriptor != nullptr)
{ {
if (fDescriptor->cleanup != nullptr) if (fDescriptor->cleanup != nullptr)
@@ -1318,6 +1327,16 @@ public:


if (fExt.state != nullptr && fExt.state->save != nullptr) if (fExt.state != nullptr && fExt.state->save != nullptr)
{ {
const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));

if (tmpDir.exists())
{
const File stateDir(handleStateMapToAbsolutePath(true, false, false, "."));

if (stateDir.isNotNull())
tmpDir.moveFileTo(stateDir);
}

fExt.state->save(fHandle, carla_lv2_state_store, this, LV2_STATE_IS_POD, fStateFeatures); fExt.state->save(fHandle, carla_lv2_state_store, this, LV2_STATE_IS_POD, fStateFeatures);


if (fHandle2 != nullptr) if (fHandle2 != nullptr)
@@ -4823,9 +4842,14 @@ public:


void restoreLV2State() noexcept override void restoreLV2State() noexcept override
{ {
if (fExt.state == nullptr)
if (fExt.state == nullptr || fExt.state->restore == nullptr)
return; return;


const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));

if (tmpDir.exists())
tmpDir.deleteRecursively();

LV2_State_Status status = LV2_STATE_ERR_UNKNOWN; LV2_State_Status status = LV2_STATE_ERR_UNKNOWN;


{ {
@@ -5232,67 +5256,97 @@ public:


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


char* handleStateMapToAbstractPath(const bool tmp, const char* const absolutePath)
char* handleStateMapToAbstractPath(const bool temporary, const char* const absolutePath)
{ {
// may already be an abstract path // may already be an abstract path
if (! File::isAbsolutePath(absolutePath)) if (! File::isAbsolutePath(absolutePath))
return strdup(absolutePath); return strdup(absolutePath);


File target;
File projectDir, targetDir;


#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
if (const char* const projFolder = pData->engine->getCurrentProjectFolder()) if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
target = projFolder;
projectDir = projFolder;
else else
#endif #endif
target = File::getCurrentWorkingDirectory();
projectDir = File::getCurrentWorkingDirectory();


if (projectDir.isNull())
return nullptr;


water::String basedir(pData->engine->getName()); water::String basedir(pData->engine->getName());


if (tmp)
if (temporary)
basedir += ".tmp"; basedir += ".tmp";


target = target.getChildFile(basedir)
.getChildFile(getName());
targetDir = projectDir.getChildFile(basedir)
.getChildFile(getName());

if (! targetDir.exists())
targetDir.createDirectory();

// we may be saving to non-tmp path, let's check
if (! temporary)
{
const File tmpDir = projectDir.getChildFile(basedir + ".tmp")
.getChildFile(getName());

if (File(absolutePath).getFullPathName().startsWith(tmpDir.getFullPathName()))
targetDir = tmpDir;
}

carla_stdout("absolutePath is %s, targetDir is %s", absolutePath, targetDir.getFullPathName().toRawUTF8());


return strdup(File(absolutePath).getRelativePathFrom(target).toRawUTF8());
return strdup(File(absolutePath).getRelativePathFrom(targetDir).toRawUTF8());
} }


char* handleStateMapToAbsolutePath(const bool createDir, const bool tmp, const char* const abstractPath)
File handleStateMapToAbsolutePath(const bool createDirIfNeeded,
const bool symlinkIfNeeded,
const bool temporary,
const char* const abstractPath)
{ {
File target;
File targetDir, targetPath;


if (File::isAbsolutePath(abstractPath))
{
target = abstractPath;
}
else
{
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
target = projFolder;
else
if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
targetDir = projFolder;
else
#endif #endif
target = File::getCurrentWorkingDirectory();
targetDir = File::getCurrentWorkingDirectory();


water::String basedir(pData->engine->getName());
if (targetDir.isNull())
return File();


if (tmp)
basedir += ".tmp";
water::String basedir(pData->engine->getName());


target = target.getChildFile(basedir)
.getChildFile(getName())
.getChildFile(abstractPath);
}
if (temporary)
basedir += ".tmp";

targetDir = targetDir.getChildFile(basedir)
.getChildFile(getName());

if (createDirIfNeeded && ! targetDir.exists())
targetDir.createDirectory();

if (File::isAbsolutePath(abstractPath))
{
File wabstractPath(abstractPath);
targetPath = targetDir.getChildFile(wabstractPath.getFileName());


if (createDir)
if (symlinkIfNeeded)
wabstractPath.createSymbolicLink(targetPath, true);
}
else
{ {
File dir(target.getParentDirectory());
if (! dir.exists())
dir.createDirectory();
targetPath = targetDir.getChildFile(abstractPath);
targetDir = targetPath.getParentDirectory();

if (createDirIfNeeded && ! targetDir.exists())
targetDir.createDirectory();
} }


return strdup(target.getFullPathName().toRawUTF8());
return targetPath;
} }


LV2_State_Status handleStateStore(const uint32_t key, const void* const value, const size_t size, const uint32_t type, const uint32_t flags) LV2_State_Status handleStateStore(const uint32_t key, const void* const value, const size_t size, const uint32_t type, const uint32_t flags)
@@ -6050,8 +6104,8 @@ public:


LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path; LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path;
stateMapPathFt->handle = this; stateMapPathFt->handle = this;
stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path_tmp;
stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path_tmp;
stateMapPathFt->abstract_path = carla_lv2_state_map_to_abstract_path_tmp;
stateMapPathFt->absolute_path = carla_lv2_state_map_to_absolute_path_tmp;


LV2_Programs_Host* const programsFt = new LV2_Programs_Host; LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
programsFt->handle = this; programsFt->handle = this;
@@ -6177,8 +6231,8 @@ public:


LV2_State_Map_Path* const stateMapPathFt2 = new LV2_State_Map_Path; LV2_State_Map_Path* const stateMapPathFt2 = new LV2_State_Map_Path;
stateMapPathFt2->handle = this; stateMapPathFt2->handle = this;
stateMapPathFt2->abstract_path = carla_lv2_state_map_abstract_path_real;
stateMapPathFt2->absolute_path = carla_lv2_state_map_absolute_path_real;
stateMapPathFt2->abstract_path = carla_lv2_state_map_to_abstract_path_real;
stateMapPathFt2->absolute_path = carla_lv2_state_map_to_absolute_path_real;


for (uint32_t j=0; j < kStateFeatureCountAll; ++j) for (uint32_t j=0; j < kStateFeatureCountAll; ++j)
fStateFeatures[j] = new LV2_Feature; fStateFeatures[j] = new LV2_Feature;
@@ -6192,6 +6246,9 @@ public:
fStateFeatures[kStateFeatureIdMapPath]->URI = LV2_STATE__mapPath; fStateFeatures[kStateFeatureIdMapPath]->URI = LV2_STATE__mapPath;
fStateFeatures[kStateFeatureIdMapPath]->data = stateMapPathFt2; fStateFeatures[kStateFeatureIdMapPath]->data = stateMapPathFt2;


fStateFeatures[kStateFeatureIdWorker]->URI = LV2_WORKER__schedule;
fStateFeatures[kStateFeatureIdWorker]->data = workerFt;

// --------------------------------------------------------------- // ---------------------------------------------------------------
// initialize plugin // initialize plugin


@@ -7023,7 +7080,8 @@ private:
CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', nullptr);
carla_stdout("carla_lv2_state_make_path_real(%p, \"%s\")", handle, path); carla_stdout("carla_lv2_state_make_path_real(%p, \"%s\")", handle, path);


return ((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, path);
const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, false, path));
return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
} }


static char* carla_lv2_state_make_path_tmp(LV2_State_Make_Path_Handle handle, const char* const path) static char* carla_lv2_state_make_path_tmp(LV2_State_Make_Path_Handle handle, const char* const path)
@@ -7032,43 +7090,46 @@ private:
CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', nullptr);
carla_stdout("carla_lv2_state_make_path_tmp(%p, \"%s\")", handle, path); carla_stdout("carla_lv2_state_make_path_tmp(%p, \"%s\")", handle, path);


return ((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, path);
const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, true, path));
return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
} }


static char* carla_lv2_state_map_abstract_path_real(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
static char* carla_lv2_state_map_to_abstract_path_real(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
{ {
CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', nullptr);
carla_stdout("carla_lv2_state_map_abstract_path_real(%p, \"%s\")", handle, absolute_path);
carla_stdout("carla_lv2_state_map_to_abstract_path_real(%p, \"%s\")", handle, absolute_path);


return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(false, absolute_path); return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(false, absolute_path);
} }


static char* carla_lv2_state_map_abstract_path_tmp(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
static char* carla_lv2_state_map_to_abstract_path_tmp(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
{ {
CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', nullptr);
carla_stdout("carla_lv2_state_map_abstract_path_tmp(%p, \"%s\")", handle, absolute_path);
carla_stdout("carla_lv2_state_map_to_abstract_path_tmp(%p, \"%s\")", handle, absolute_path);


return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(true, absolute_path); return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(true, absolute_path);
} }


static char* carla_lv2_state_map_absolute_path_real(LV2_State_Map_Path_Handle handle, const char* const abstract_path)
static char* carla_lv2_state_map_to_absolute_path_real(LV2_State_Map_Path_Handle handle, const char* const abstract_path)
{ {
CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', nullptr);
carla_stdout("carla_lv2_state_map_absolute_path_real(%p, \"%s\")", handle, abstract_path);
carla_stdout("carla_lv2_state_map_to_absolute_path_real(%p, \"%s\")", handle, abstract_path);


return ((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(false, false, abstract_path);
const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, false, abstract_path));
return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
} }


static char* carla_lv2_state_map_absolute_path_tmp(LV2_State_Map_Path_Handle handle, const char* const abstract_path)
static char* carla_lv2_state_map_to_absolute_path_tmp(LV2_State_Map_Path_Handle handle, const char* const abstract_path)
{ {
CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', nullptr);
carla_stdout("carla_lv2_state_map_absolute_path_tmp(%p, \"%s\")", handle, abstract_path);
carla_stdout("carla_lv2_state_map_to_absolute_path_tmp(%p, \"%s\")", handle, abstract_path);


return ((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(false, true, abstract_path);
const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, true, abstract_path));
return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
} }


static LV2_State_Status carla_lv2_state_store(LV2_State_Handle handle, uint32_t key, const void* value, size_t size, uint32_t type, uint32_t flags) static LV2_State_Status carla_lv2_state_store(LV2_State_Handle handle, uint32_t key, const void* value, size_t size, uint32_t type, uint32_t flags)


+ 10
- 0
source/modules/water/files/File.cpp View File

@@ -99,6 +99,16 @@ File& File::operator= (File&& other) noexcept
} }
#endif #endif
bool File::isNull() const
{
return fullPath.isEmpty();
}
bool File::isNotNull() const
{
return fullPath.isNotEmpty();
}
//============================================================================== //==============================================================================
static String removeEllipsis (const String& path) static String removeEllipsis (const String& path)
{ {


+ 8
- 0
source/modules/water/files/File.h View File

@@ -118,6 +118,14 @@ public:
*/ */
bool isDirectory() const; bool isDirectory() const;
/** Checks whether the file is invalid (empty path).
*/
bool isNull() const;
/** Checks whether the file is valid (non-empty path).
*/
bool isNotNull() const;
/** Returns the size of the file in bytes. /** Returns the size of the file in bytes.
@returns the number of bytes in the file, or 0 if it doesn't exist. @returns the number of bytes in the file, or 0 if it doesn't exist.


Loading…
Cancel
Save