{controlGroup.name}
@@ -566,7 +565,7 @@ const PluginControlView =
} else {
result.push((
-
+
{node as ReactNode}
));
@@ -584,7 +583,7 @@ const PluginControlView =
render(): ReactNode {
- this.controlKeyIndex = 0;
+ this.controlKeyIndex = 0;
let classes = this.props.classes;
let pedalboardItem: PedalboardItem;
let pedalboard = this.model.pedalboard.get();
@@ -650,29 +649,33 @@ const PluginControlView =
)
}
-
{
- this.setState({ showFileDialog: false });
- }}
- onOk={(fileProperty, selectedFile) => {
+ {this.state.showFileDialog && (
- this.model.setPatchProperty(
- this.props.instanceId,
- fileProperty.patchProperty,
- JsonAtom.Path(selectedFile)
- )
- .then(() => {
+ {
+ this.setState({ showFileDialog: false });
+ }}
+ onOk={(fileProperty, selectedFile) => {
+
+ this.model.setPatchProperty(
+ this.props.instanceId,
+ fileProperty.patchProperty,
+ JsonAtom.Path(selectedFile)
+ )
+ .then(() => {
+
+ })
+ .catch((error) => {
+ this.model.showAlert("Unable to complete the operation. Audio is not running." + error);
+ });
+ this.setState({ showFileDialog: false });
+ }
+ }
+ />
+ )}
- })
- .catch((error) => {
- this.model.showAlert("Unable to complete the operation. Audio is not running." + error);
- });
- this.setState({ showFileDialog: false });
- }
- }
- />
this.onImeValueChange(key, value)}
diff --git a/src/FileEntry.cpp b/src/FileEntry.cpp
index 2a6da62..3c77073 100644
--- a/src/FileEntry.cpp
+++ b/src/FileEntry.cpp
@@ -38,4 +38,5 @@ JSON_MAP_BEGIN(FileRequestResult)
JSON_MAP_REFERENCE(FileRequestResult,files)
JSON_MAP_REFERENCE(FileRequestResult,isProtected)
JSON_MAP_REFERENCE(FileRequestResult,breadcrumbs)
+ JSON_MAP_REFERENCE(FileRequestResult,currentDirectory)
JSON_MAP_END()
diff --git a/src/FileEntry.hpp b/src/FileEntry.hpp
index f1dc3ff..c040955 100644
--- a/src/FileEntry.hpp
+++ b/src/FileEntry.hpp
@@ -52,6 +52,7 @@ namespace pipedal {
std::vector files_;
bool isProtected_ = false;
std::vector breadcrumbs_;
+ std::string currentDirectory_;
DECLARE_JSON_MAP(FileRequestResult);
};
diff --git a/src/Lv2Effect.cpp b/src/Lv2Effect.cpp
index 9df333e..3f4863d 100644
--- a/src/Lv2Effect.cpp
+++ b/src/Lv2Effect.cpp
@@ -43,9 +43,21 @@
#include "RingBufferReader.hpp"
using namespace pipedal;
+namespace fs = std::filesystem;
const float BYPASS_TIME_S = 0.1f;
+
+static fs::path makeAbsolutePath(const std::filesystem::path &path, const std::filesystem::path &parentPath)
+{
+ if (path.is_absolute())
+ {
+ return path;
+ }
+ return parentPath / path;
+}
+
+
Lv2Effect::Lv2Effect(
IHost *pHost_,
const std::shared_ptr &info_,
@@ -69,7 +81,6 @@ Lv2Effect::Lv2Effect(
this->pathProperties.push_back(filePropertyUrid);
this->pathPropertyWriters.push_back(PatchPropertyWriter(instanceId, filePropertyUrid));
- std::vector pathPropertyWriters;
}
}
for (auto &pathProperty: pedalboardItem.pathProperties_)
@@ -84,8 +95,10 @@ Lv2Effect::Lv2Effect(
const LilvPlugins *plugins = lilv_world_get_all_plugins(pWorld);
+ // xxx: could we not stash the pPlugin in the plugin info?
auto uriNode = lilv_new_uri(pWorld, pedalboardItem.uri().c_str());
const LilvPlugin *pPlugin = lilv_plugins_get_by_uri(plugins, uriNode);
+
lilv_node_free(uriNode);
{
AutoLilvNode bundleUri = lilv_plugin_get_bundle_uri(pPlugin);
@@ -98,6 +111,25 @@ Lv2Effect::Lv2Effect(
logFeature.GetLog(),
bundleUriString,
storagePath);
+
+
+ mapPathFeature.Prepare(&(pHost_->GetMapFeature()));
+ mapPathFeature.SetPluginStoragePath(pHost_->GetPluginStoragePath());
+ if (info->piPedalUI())
+ {
+ const auto &fileProperties = info_->piPedalUI()->fileProperties();
+ for (const auto &fileProperty : fileProperties)
+ {
+ if (!fileProperty->resourceDirectory().empty())
+ {
+ mapPathFeature.AddResourceFileMapping({
+ makeAbsolutePath(fileProperty->resourceDirectory(),bundleUriString),
+ makeAbsolutePath(fileProperty->directory(),pHost_->GetPluginStoragePath())
+ });
+ }
+ }
+ }
+
lilv_free(bundleUriString);
}
@@ -109,6 +141,10 @@ Lv2Effect::Lv2Effect(
{
this->features.push_back(*p);
}
+ this->features.push_back(mapPathFeature.GetMapPathFeature());
+ this->features.push_back(mapPathFeature.GetMakePathFeature());
+ this->features.push_back(mapPathFeature.GetFreePathFeature());
+
this->features.push_back(this->fileBrowserFilesFeature.GetFeature());
diff --git a/src/Lv2Effect.hpp b/src/Lv2Effect.hpp
index a85e5ae..a6d5417 100644
--- a/src/Lv2Effect.hpp
+++ b/src/Lv2Effect.hpp
@@ -27,6 +27,7 @@
#include "FileBrowserFilesFeature.hpp"
#include "PatchPropertyWriter.hpp"
#include
+#include "MapPathFeature.hpp"
#include "IEffect.hpp"
#include "Worker.hpp"
@@ -90,7 +91,7 @@ namespace pipedal
std::vector outputAtomBuffers;
std::vector features;
LV2_Feature *work_schedule_feature = nullptr;
-
+ MapPathFeature mapPathFeature;
uint64_t maxInputControlPort = 0;
std::vector isInputControlPort;
diff --git a/src/MapPathFeature.cpp b/src/MapPathFeature.cpp
index 85040cd..aedd4e7 100644
--- a/src/MapPathFeature.cpp
+++ b/src/MapPathFeature.cpp
@@ -26,8 +26,7 @@
using namespace pipedal;
-MapPathFeature::MapPathFeature(const std::filesystem::path &storagePath)
-:storagePath(storagePath)
+MapPathFeature::MapPathFeature()
{
lv2_state_map_path.handle = (LV2_State_Map_Path_Handle *)this;
lv2_state_map_path.absolute_path = FnAbsolutePath;
diff --git a/src/MapPathFeature.hpp b/src/MapPathFeature.hpp
index ab227a4..655c42f 100644
--- a/src/MapPathFeature.hpp
+++ b/src/MapPathFeature.hpp
@@ -24,12 +24,23 @@
namespace pipedal
{
+ struct ResourceFileMapping {
+ std::string resourcePath; // absolute path of the resource directory.
+ std::string storagePath; // absolute path of where resource directory files get placed.
+ };
class MapPathFeature
{
public:
- MapPathFeature(const std::filesystem::path &storagePath);
+ MapPathFeature();
void Prepare(MapFeature* map);
void SetPluginStoragePath(const std::string&path) { storagePath = path;}
+
+ void AddResourceFileMapping(const ResourceFileMapping &resourceFileMapping)
+ {
+ this->resourceFileMappings.push_back(resourceFileMapping);
+ }
+
+ const std::vector &GetResourceFileMappings() const { return resourceFileMappings; }
const std::string&GetPluginStoragePath() const { return storagePath; }
const LV2_Feature*GetMapPathFeature() { return &mapPathFeature;}
const LV2_Feature*GetMakePathFeature() { return &makePathFeature;}
@@ -60,5 +71,6 @@ namespace pipedal
private:
std::string storagePath;
+ std::vector resourceFileMappings;
};
}
\ No newline at end of file
diff --git a/src/PluginHost.cpp b/src/PluginHost.cpp
index d987f67..1d0ae47 100644
--- a/src/PluginHost.cpp
+++ b/src/PluginHost.cpp
@@ -243,16 +243,15 @@ static float nodeAsFloat(const LilvNode *node, float default_ = 0)
void PluginHost::SetPluginStoragePath(const std::filesystem::path &path)
{
- mapPathFeature.SetPluginStoragePath(path);
+ pluginStoragePath = path;
}
std::string PluginHost::GetPluginStoragePath() const
{
- return mapPathFeature.GetPluginStoragePath();
+ return pluginStoragePath;
}
PluginHost::PluginHost()
- : mapPathFeature("")
{
pWorld = nullptr;
@@ -260,13 +259,9 @@ PluginHost::PluginHost()
lv2Features.push_back(mapFeature.GetUnmapFeature());
optionsFeature.Prepare(mapFeature, 44100, this->GetMaxAudioBufferSize(), this->GetAtomBufferSize());
-
- mapPathFeature.Prepare(&mapFeature);
- lv2Features.push_back(mapPathFeature.GetMapPathFeature());
- lv2Features.push_back(mapPathFeature.GetMakePathFeature());
- lv2Features.push_back(mapPathFeature.GetFreePathFeature());
lv2Features.push_back(optionsFeature.GetFeature());
+
lv2Features.push_back(nullptr);
this->urids = new Urids(mapFeature);
diff --git a/src/PluginHost.hpp b/src/PluginHost.hpp
index 2638207..5fa685d 100644
--- a/src/PluginHost.hpp
+++ b/src/PluginHost.hpp
@@ -757,7 +757,7 @@ namespace pipedal
std::vector lv2Features;
MapFeature mapFeature;
OptionsFeature optionsFeature;
- MapPathFeature mapPathFeature;
+ std::string pluginStoragePath;
static void fn_LilvSetPortValueFunc(const char *port_symbol,
void *user_data,
diff --git a/src/Storage.cpp b/src/Storage.cpp
index a25e4d7..f60201f 100644
--- a/src/Storage.cpp
+++ b/src/Storage.cpp
@@ -1770,6 +1770,7 @@ FileRequestResult Storage::GetModFileList2(const std::string &relativePath, cons
FileEntry(uploadsDirectory / fileProperty.directory(), fs::path(fileProperty.directory()).filename().string(), true, true));
}
result.breadcrumbs_.push_back({"", "Home"});
+ result.currentDirectory_ = relativePath;
return result;
}
fs::path modDirectoryPath;
@@ -1824,9 +1825,23 @@ FileRequestResult Storage::GetModFileList2(const std::string &relativePath, cons
}
AddFilesToResult(result, fileProperty, relativePath);
+ result.currentDirectory_ = relativePath;
return result;
}
+static bool IsChildDirectory(const fs::path& child, const fs::path&parent) {
+ auto iChild = child.begin();
+ for (auto i = parent.begin(); i != parent.end(); ++i)
+ {
+ if (iChild == child.end() || (*i) != *iChild)
+ {
+ return false;
+ }
+ ++iChild;
+ }
+ return true;
+}
+
FileRequestResult Storage::GetFileList2(const std::string &relativePath_, const UiFileProperty &fileProperty)
{
std::string absolutePath = relativePath_;
@@ -1843,15 +1858,35 @@ FileRequestResult Storage::GetFileList2(const std::string &relativePath_, const
if (fileProperty.directory().empty())
{
+
throw std::runtime_error("fileProperty.directory() not specified.");
}
std::filesystem::path pluginRootDirectory = this->GetPluginUploadDirectory() / fileProperty.directory();
- if (absolutePath == "")
+ if (absolutePath.empty())
{
absolutePath = pluginRootDirectory.string();
}
+ // handle resource directories.
+ if (!fileProperty.resourceDirectory().empty())
{
+ if (fileProperty.resourceDirectory() == absolutePath)
+ {
+ absolutePath = pluginRootDirectory;
+ }
+ }
+
+ if (!IsChildDirectory(absolutePath,pluginRootDirectory))
+ {
+ absolutePath = pluginRootDirectory;
+ }
+
+
+ result.currentDirectory_ = absolutePath;
+
+
+ {
+ // watch out for resource files!!!
result.breadcrumbs_.push_back({"", "Home"});
fs::path fsAbsolutePath{absolutePath};
auto iAbsolutePath = fsAbsolutePath.begin();
diff --git a/src/main.cpp b/src/main.cpp
index 2f22fb9..c1d4e97 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -398,6 +398,11 @@ int main(int argc, char *argv[])
}
Lv2Log::info("Shutdown complete.");
+ if (systemd)
+ {
+ sd_notify(0, "STOPPING=1");
+ }
+
if (g_restart)
return EXIT_FAILURE; // indicate to systemd that we want a restart.
}