Tweak wasm build, add persistent storage

Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
falkTX 2023-05-21 04:39:27 +02:00
parent 9aba0e034a
commit e6a799cd4c
No known key found for this signature in database
GPG key ID: CDBAA37ABC74FBA0
10 changed files with 150 additions and 40 deletions

2
dpf

@ -1 +1 @@
Subproject commit b4460beb094502c868dda5991e356623b13ce658
Subproject commit 802e4460844b75b4c2a96c5a9f9baa791209f74e

View file

@ -892,8 +892,8 @@ struct AidaWidget : ModuleWidgetWithSideScrews<23> {
heightPedal,
cornerRadius,
cornerRadius,
nvgRGBA(0,0,0,1.f),
nvgRGBA(0,0,0,0.f)));
nvgRGBAf(0,0,0,1.f),
nvgRGBAf(0,0,0,0.f)));
nvgFill(args.vg);
// .rt-neural .grid
@ -916,7 +916,7 @@ struct AidaWidget : ModuleWidgetWithSideScrews<23> {
nvgFill(args.vg);
// extra
nvgStrokeColor(args.vg, nvgRGBA(150, 150, 150, 0.25f));
nvgStrokeColor(args.vg, nvgRGBA(150, 150, 150, 60));
nvgStroke(args.vg);
drawOutputJacksArea(args.vg);

View file

@ -471,10 +471,10 @@ struct AudioFileListWidget : ImGuiWidget {
selectedFile = (size_t)-1;
static constexpr const char* const supportedExtensions[] = {
#ifdef HAVE_SNDFILE
#ifdef HAVE_SNDFILE
".aif",".aifc",".aiff",".au",".bwf",".flac",".htk",".iff",".mat4",".mat5",".oga",".ogg",".opus",
".paf",".pvf",".pvf5",".sd2",".sf",".snd",".svx",".vcc",".w64",".wav",".xi",
#endif
#endif
".mp3"
};

View file

@ -89,9 +89,9 @@
#ifdef DISTRHO_OS_WASM
# if CARDINAL_VARIANT_MINI
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini.vcv"
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini"
# else
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm.vcv"
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm"
# endif
#endif
@ -374,6 +374,17 @@ static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv,
}
#endif
// -----------------------------------------------------------------------------------------------------------
#ifdef DISTRHO_OS_WASM
static void WebBrowserDataLoaded(void* const data)
{
static_cast<Initializer*>(data)->loadSettings(true);
}
#endif
// -----------------------------------------------------------------------------------------------------------
Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalBaseUI* const ui)
{
using namespace rack;
@ -490,7 +501,17 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB
#endif
if (isRealInstance)
{
#ifdef DISTRHO_OS_WASM
EM_ASM({
Module.FS.mkdir('/userfiles');
Module.FS.mount(Module.IDBFS, {}, '/userfiles');
Module.FS.syncfs(true, function(err) { if (!err) { dynCall('vi', $0, [$1]) } });
}, WebBrowserDataLoaded, this);
#else
system::createDirectory(asset::userDir);
#endif
}
}
#ifndef CARDINAL_COMMON_DSP_ONLY
@ -513,13 +534,11 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB
if (settings::settingsPath.empty())
settings::settingsPath = asset::config(CARDINAL_VARIANT_NAME ".json");
const std::string patchesPath = asset::patchesPath();
#ifdef DISTRHO_OS_WASM
templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME ".vcv");
factoryTemplatePath = system::join(patchesPath, "templates/" CARDINAL_VARIANT_NAME ".vcv");
#else
templatePath = asset::user("templates/" CARDINAL_VARIANT_NAME ".vcv");
factoryTemplatePath = system::join(patchesPath, "templates/" CARDINAL_VARIANT_NAME ".vcv");
#ifdef DISTRHO_OS_WASM
factoryTemplatePath = system::join(asset::patchesPath(), CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME ".vcv");
#else
factoryTemplatePath = system::join(asset::patchesPath(), "templates/" CARDINAL_VARIANT_NAME ".vcv");
#endif
// Log environment
@ -672,7 +691,8 @@ bool isMini()
bool isStandalone()
{
return std::strstr(getPluginFormatName(), "Standalone") != nullptr;
static const bool standalone = std::strstr(getPluginFormatName(), "Standalone") != nullptr;
return standalone;
}
#ifdef ARCH_WIN
@ -712,6 +732,15 @@ std::string getSpecialPath(const SpecialPath type)
char* patchFromURL = nullptr;
char* patchRemoteURL = nullptr;
char* patchStorageSlug = nullptr;
void syncfs()
{
settings::save();
EM_ASM({
Module.FS.syncfs(false, function(){} );
});
}
#endif
std::string homeDir()
@ -783,6 +812,10 @@ void loadPathDialog(const std::string& path, const bool asTemplate)
APP->history->setSaved();
}
#ifdef DISTRHO_OS_WASM
syncfs();
#endif
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote())
if (remoteDetails->autoDeploy)
remoteUtils::sendFullPatchToRemote(remoteDetails);
@ -812,6 +845,10 @@ void loadSelectionDialog()
std::free(pathC);
#ifdef DISTRHO_OS_WASM
syncfs();
#endif
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote())
if (remoteDetails->autoDeploy)
remoteUtils::sendFullPatchToRemote(remoteDetails);
@ -839,6 +876,10 @@ void loadTemplate(const bool factory)
APP->patch->path.clear();
APP->history->setSaved();
#ifdef DISTRHO_OS_WASM
syncfs();
#endif
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote())
if (remoteDetails->autoDeploy)
remoteUtils::sendFullPatchToRemote(remoteDetails);
@ -862,6 +903,10 @@ void revertDialog()
promptClear("Revert patch to the last saved state?", []{
APP->patch->loadAction(APP->patch->path);
#ifdef DISTRHO_OS_WASM
syncfs();
#endif
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote())
if (remoteDetails->autoDeploy)
remoteUtils::sendFullPatchToRemote(remoteDetails);
@ -886,6 +931,14 @@ void saveDialog(const std::string& path)
asyncDialog::create(string::f("Could not save patch: %s", e.what()).c_str());
return;
}
APP->patch->pushRecentPath(path);
#ifdef DISTRHO_OS_WASM
syncfs();
#else
rack::settings::save();
#endif
#endif
}
@ -944,7 +997,11 @@ void saveTemplateDialog()
catch (Exception& e) {
asyncDialog::create(string::f("Could not save template patch: %s", e.what()).c_str());
return;
}
}
#ifdef DISTRHO_OS_WASM
syncfs();
#endif
});
}

View file

@ -53,6 +53,7 @@ std::string getSpecialPath(SpecialPath type);
extern char* patchFromURL;
extern char* patchRemoteURL;
extern char* patchStorageSlug;
void syncfs();
#endif
std::string homeDir();

View file

@ -66,6 +66,11 @@ namespace app {
rack::widget::Widget* createMenuBar() { return new rack::widget::Widget; }
}
#endif
#ifdef DISTRHO_OS_WASM
namespace asset {
std::string patchesPath();
}
#endif
namespace engine {
void Engine_setAboutToClose(Engine*);
}
@ -312,6 +317,15 @@ public:
context->scene->rackScroll->reset();
}
#ifdef DISTRHO_OS_WASM
// switch factory template to regular one after first load
#if CARDINAL_VARIANT_MINI
context->patch->factoryTemplatePath = rack::system::join(rack::asset::patchesPath(), "templates/mini.vcv");
#else
context->patch->factoryTemplatePath = rack::system::join(rack::asset::patchesPath(), "templates/main.vcv");
#endif
#endif
#ifdef CARDINAL_INIT_OSC_THREAD
fInitializer->remotePluginInstance = this;
#endif

View file

@ -62,6 +62,11 @@
#endif
namespace rack {
#ifdef DISTRHO_OS_WASM
namespace asset {
std::string patchesPath();
}
#endif
namespace engine {
void Engine_setAboutToClose(Engine*);
void Engine_setRemoteDetails(Engine*, remoteUtils::RemoteDetails*);
@ -246,7 +251,7 @@ static void downloadRemotePatchFailed(const char* const filename)
}
using namespace rack;
context->patch->templatePath = system::join(asset::systemDir, "init/wasm.vcv"); // FIXME
context->patch->templatePath = rack::system::join(asset::patchesPath(), "templates/main.vcv");
context->patch->loadTemplate();
context->scene->rackScroll->reset();
}
@ -1228,7 +1233,11 @@ protected:
context->patch->pushRecentPath(sfilename);
context->history->setSaved();
#ifdef DISTRHO_OS_WASM
rack::syncfs();
#else
rack::settings::save();
#endif
}
#if 0

View file

@ -283,6 +283,7 @@ LINK_FLAGS += -O3
LINK_FLAGS += -sALLOW_MEMORY_GROWTH
LINK_FLAGS += -sINITIAL_MEMORY=64Mb
LINK_FLAGS += -sLZ4=1
LINK_FLAGS += -lidbfs.js
ifeq ($(CARDINAL_VARIANT),mini)
LINK_FLAGS += --preload-file=../../bin/CardinalMini.lv2/resources@/resources

View file

@ -56,6 +56,11 @@
#include "DistrhoPlugin.hpp"
#include "DistrhoStandaloneUtils.hpp"
#ifdef DISTRHO_OS_WASM
# include <emscripten/emscripten.h>
# undef HAVE_LIBLO
#endif
#ifdef HAVE_LIBLO
# include <lo/lo.h>
#endif
@ -98,6 +103,28 @@ struct FileButton : MenuButton {
const bool isStandalone;
std::vector<std::string> demoPatches;
#ifdef DISTRHO_OS_WASM
static void WebBrowserDataSaved(const int err)
{
err ? async_dialog_message("Error, could not save web browser data!")
: async_dialog_message("Web browser data saved!");
}
static void wasmSaveAs()
{
async_dialog_text_input("Filename", nullptr, [](char* const filename) {
if (filename == nullptr)
return;
APP->patch->path = "/userfiles/";
APP->patch->path += filename;
if (rack::system::getExtension(filename) != ".vcv")
APP->patch->path += ".vcv";
patchUtils::saveDialog(APP->patch->path);
std::free(filename);
});
}
#endif
FileButton(const bool standalone)
: MenuButton(), isStandalone(standalone)
{
@ -131,7 +158,6 @@ struct FileButton : MenuButton {
}));
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
#ifndef DISTRHO_OS_WASM
menu->addChild(createMenuItem("New (factory template)", "", []() {
patchUtils::loadTemplateDialog(true);
}));
@ -149,6 +175,11 @@ struct FileButton : MenuButton {
}
}, settings::recentPatchPaths.empty()));
menu->addChild(createMenuItem("Import selection...", "", [=]() {
patchUtils::loadSelectionDialog();
}, false, true));
#ifndef DISTRHO_OS_WASM
menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() {
// NOTE: will do nothing if path is empty, intentionally
patchUtils::saveDialog(APP->patch->path);
@ -158,13 +189,16 @@ struct FileButton : MenuButton {
patchUtils::saveAsDialog();
}));
#else
menu->addChild(createMenuItem("Import patch...", RACK_MOD_CTRL_NAME "+O", []() {
patchUtils::loadDialog();
menu->addChild(createMenuItem("Save", "", []() {
if (APP->patch->path.empty())
wasmSaveAs();
else
patchUtils::saveDialog(APP->patch->path);
}));
menu->addChild(createMenuItem("Import selection...", "", [=]() {
patchUtils::loadSelectionDialog();
}, false, true));
menu->addChild(createMenuItem("Save as", "", []() {
wasmSaveAs();
}));
menu->addChild(createMenuItem("Save and download compressed", RACK_MOD_CTRL_NAME "+Shift+S", []() {
patchUtils::saveAsDialog();
@ -184,6 +218,17 @@ struct FileButton : MenuButton {
patchUtils::saveTemplateDialog();
}));
#ifdef DISTRHO_OS_WASM
menu->addChild(new ui::MenuSeparator);
menu->addChild(createMenuItem("Save persistent browser data", "", []() {
settings::save();
EM_ASM({
Module.FS.syncfs(false, function(err){ dynCall('vi', $0, [!!err]) });
}, WebBrowserDataSaved);
}));
#endif
#if defined(HAVE_LIBLO) || ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
#ifdef __MOD_DEVICES__
#define REMOTE_NAME "MOD"
@ -213,21 +258,6 @@ struct FileButton : MenuButton {
}
#endif
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
#ifndef DISTRHO_OS_WASM
menu->addChild(new ui::MenuSeparator);
// Load selection
menu->addChild(createMenuItem("Import selection...", "", [=]() {
patchUtils::loadSelectionDialog();
}, false, true));
menu->addChild(createMenuItem("Export uncompressed json...", "", []() {
patchUtils::saveAsDialogUncompressed();
}));
#endif
#endif
if (!demoPatches.empty())
{
menu->addChild(new ui::MenuSeparator);

View file

@ -276,13 +276,11 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
patchUtils::revertDialog();
e.consume(this);
}
#ifndef DISTRHO_OS_WASM
if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
// NOTE: will do nothing if path is empty, intentionally
patchUtils::saveDialog(APP->patch->path);
e.consume(this);
}
#endif
if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
patchUtils::saveAsDialog();
e.consume(this);