Skip to content

Commit

Permalink
- include external script files (+ GLSL files + SNEX files + Faust DS…
Browse files Browse the repository at this point in the history
…P files) into snippet with special "embedded snippet resource mode" !
  • Loading branch information
christoph-hart committed Mar 21, 2024
1 parent 98a7a75 commit 1093e0c
Show file tree
Hide file tree
Showing 17 changed files with 449 additions and 88 deletions.
64 changes: 61 additions & 3 deletions hi_backend/backend/BackendApplicationCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ void BackendCommandTarget::getAllCommands(Array<CommandID>& commands)
MenuFileSettingCheckSanity,
MenuFileSettingsCleanBuildDirectory,
MenuFileCreateThirdPartyNode,
MenuFileExtractEmbeddeSnippetFiles,
MenuReplaceWithClipboardContent,
MenuExportFileAsPlugin,
MenuExportFileAsEffectPlugin,
Expand Down Expand Up @@ -195,6 +196,22 @@ void BackendCommandTarget::getAllCommands(Array<CommandID>& commands)
commands.addArray(id, numElementsInArray(id));
}

void BackendCommandTarget::setCopyPasteTarget(CopyPasteTarget* newTarget)
{
if (currentCopyPasteTarget.get() != nullptr)
{
currentCopyPasteTarget->deselect();
}
else
{
mainCommandManager->setFirstCommandTarget(this);
}

currentCopyPasteTarget = newTarget;

updateCommands();
}

void BackendCommandTarget::createMenuBarNames()
{
menuNames.clear();
Expand Down Expand Up @@ -296,6 +313,10 @@ void BackendCommandTarget::getCommandInfo(CommandID commandID, ApplicationComman
setCommandTarget(result, "Archive Project", GET_PROJECT_HANDLER(bpe->getMainSynthChain()).isActive(), false, 'X', false);
result.categoryName = "File";
break;
case MenuFileExtractEmbeddeSnippetFiles:
setCommandTarget(result, "Extract embedded files from HISE snippet", GET_PROJECT_HANDLER(bpe->getMainSynthChain()).isActive(), false, 'X', false);
result.categoryName = "File";
break;
case MenuFileDownloadNewProject:
setCommandTarget(result, "Download archived Project", true, false, 'X', false);
result.categoryName = "File";
Expand Down Expand Up @@ -733,6 +754,7 @@ bool BackendCommandTarget::perform(const InvocationInfo &info)
case MenuFileSettingsCleanBuildDirectory: Actions::cleanBuildDirectory(bpe); return true;
case MenuFileCreateThirdPartyNode: Actions::createThirdPartyNode(bpe); return true;
case MenuReplaceWithClipboardContent: Actions::replaceWithClipboardContent(bpe); return true;
case MenuFileExtractEmbeddeSnippetFiles: Actions::extractEmbeddedFilesFromSnippet(bpe); return true;
case MenuFileQuit: if (PresetHandler::showYesNoWindow("Quit Application", "Do you want to quit?"))
JUCEApplicationBase::quit(); return true;
case MenuEditUndo: bpe->owner->getControlUndoManager()->undo(); updateCommands(); return true;
Expand Down Expand Up @@ -940,6 +962,7 @@ PopupMenu BackendCommandTarget::getMenuForIndex(int topLevelMenuIndex, const Str


ADD_ALL_PLATFORMS(MenuReplaceWithClipboardContent);
ADD_ALL_PLATFORMS(MenuFileExtractEmbeddeSnippetFiles);
ADD_ALL_PLATFORMS(MenuFileCreateRecoveryXml);


Expand Down Expand Up @@ -1289,6 +1312,7 @@ void BackendCommandTarget::Actions::replaceWithClipboardContent(BackendRootWindo
if (v.isValid())
{
bpe->loadNewContainer(v);

return;
}
}
Expand Down Expand Up @@ -1736,13 +1760,27 @@ void BackendCommandTarget::Actions::exportFileAsSnippet(BackendProcessor* bp)
MainController::ScopedEmbedAllResources sd(bp);

ValueTree v = bp->getMainSynthChain()->exportAsValueTree();

auto scriptRootFolder = bp->getCurrentFileHandler().getSubDirectory(FileHandlerBase::Scripts);
auto snexRootFolder = BackendDllManager::getSubFolder(bp, BackendDllManager::FolderSubType::CodeLibrary);

auto embeddedScripts = bp->collectIncludedScriptFilesForSnippet("embeddedScripts", scriptRootFolder);
auto embeddedSnexFiles = bp->collectIncludedScriptFilesForSnippet("embeddedSnexFiles", snexRootFolder);

MemoryOutputStream mos;

v.writeToStream(mos);
if(embeddedScripts.getNumChildren() > 0 || embeddedSnexFiles.getNumChildren() > 0)
{
ValueTree nv("extended_snippet");
nv.addChild(v, -1, nullptr);
nv.addChild(embeddedScripts, -1, nullptr);
nv.addChild(embeddedSnexFiles, -1, nullptr);
nv.writeToStream(mos);
}
else
v.writeToStream(mos);

MemoryOutputStream mos2;

GZIPCompressorOutputStream zipper(&mos2, 9);

zipper.write(mos.getData(), mos.getDataSize());
Expand All @@ -1756,7 +1794,6 @@ void BackendCommandTarget::Actions::exportFileAsSnippet(BackendProcessor* bp)
{
PresetHandler::showMessageWindow("Preset copied as compressed snippet", "You can paste the clipboard content to share this preset", PresetHandler::IconType::Info);
}

}

void BackendCommandTarget::Actions::createRnboTemplate(BackendRootWindow* bpe)
Expand Down Expand Up @@ -3111,6 +3148,27 @@ void BackendCommandTarget::Actions::restoreToDefault(BackendRootWindow * bpe)
debugToConsole(mp, message);
}

void BackendCommandTarget::Actions::extractEmbeddedFilesFromSnippet(BackendRootWindow* bpe)
{
auto gp = dynamic_cast<GlobalScriptCompileBroadcaster*>(bpe->getBackendProcessor());

int numWritten = 0;

auto chain = bpe->getBackendProcessor()->getMainSynthChain();

for(int i = 0; i < gp->getNumExternalScriptFiles(); i++)
{
if(gp->getExternalScriptFile(i)->extractEmbedded())
{
debugToConsole(chain, "Extracted " + gp->getExternalScriptFile(i)->getFile().getFullPathName());
numWritten++;
}
}

debugToConsole(chain, "Extracted " + String(numWritten) + " files from currently loaded HISE snippet");

}

#undef REPLACE_WILDCARD
#undef REPLACE_WILDCARD_WITH_STRING

Expand Down
19 changes: 4 additions & 15 deletions hi_backend/backend/BackendApplicationCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class BackendCommandTarget: public ApplicationCommandTarget,
MenuCloseProject,
MenuFileArchiveProject,
MenuFileImportProjectFromHXI,
MenuFileExtractEmbeddeSnippetFiles,
MenuFileDownloadNewProject,
MenuFileCreateRecoveryXml,
MenuProjectShowInFinder,
Expand Down Expand Up @@ -276,21 +277,7 @@ class BackendCommandTarget: public ApplicationCommandTarget,
menuItemsChanged();
}

void setCopyPasteTarget(CopyPasteTarget *newTarget)
{
if (currentCopyPasteTarget.get() != nullptr)
{
currentCopyPasteTarget->deselect();
}
else
{
mainCommandManager->setFirstCommandTarget(this);
}

currentCopyPasteTarget = newTarget;

updateCommands();
}
void setCopyPasteTarget(CopyPasteTarget *newTarget);

void createMenuBarNames();

Expand Down Expand Up @@ -404,6 +391,8 @@ class BackendCommandTarget: public ApplicationCommandTarget,

static void createThirdPartyNode(BackendRootWindow* bpe);
static void restoreToDefault(BackendRootWindow * bpe);

static void extractEmbeddedFilesFromSnippet(BackendRootWindow* bpe);
};

private:
Expand Down
59 changes: 56 additions & 3 deletions hi_core/hi_core/GlobalScriptCompileBroadcaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,57 @@ void GlobalScriptCompileBroadcaster::clearIncludedFiles()
includedFiles.clear();
}

void GlobalScriptCompileBroadcaster::restoreIncludedScriptFilesFromSnippet(const ValueTree& snippetTree)
{
#if USE_BACKEND
auto mc = dynamic_cast<MainController*>(this);
auto scriptRootFolder = mc->getActiveFileHandler()->getSubDirectory(FileHandlerBase::Scripts);
auto snexRootFolder = BackendDllManager::getSubFolder(mc, BackendDllManager::FolderSubType::CodeLibrary);

auto restoreFromChild = [&](const Identifier& id, const File& rootDirectory)
{
auto v = snippetTree.getChildWithName(id);
jassert(v.isValid());

auto chain = dynamic_cast<const MainController*>(this)->getMainSynthChain();

for(auto c: v)
{
debugToConsole(const_cast<ModulatorSynthChain*>(chain), "loaded embedded file " + c["filename"].toString() + " from HISE snippet");
auto n = new ExternalScriptFile(rootDirectory, c);
includedFiles.add(n);
}
};

restoreFromChild("embeddedScripts", scriptRootFolder);
restoreFromChild("embeddedSnexFiles", snexRootFolder);
#endif
}

ValueTree GlobalScriptCompileBroadcaster::collectIncludedScriptFilesForSnippet(const Identifier& id, const File& root) const
{
#if USE_BACKEND
ValueTree d(id);

auto chain = dynamic_cast<const MainController*>(this)->getMainSynthChain();

for(auto f: includedFiles)
{
if(!f->getFile().isAChildOf(root))
continue;

auto c = f->toEmbeddableValueTree(root);
debugToConsole(const_cast<ModulatorSynthChain*>(chain), "embedded " + c["filename"].toString() + " into HISE snippet");
d.addChild(c, -1, nullptr);
}

return d;
#else
jassertfalse;
return {};
#endif
}

ScriptComponentEditBroadcaster* GlobalScriptCompileBroadcaster::getScriptComponentEditBroadcaster()
{
return globalEditBroadcaster;
Expand Down Expand Up @@ -234,17 +285,18 @@ String GlobalScriptCompileBroadcaster::getExternalScriptFromCollection(const Str
return String();
}

ExternalScriptFile::Ptr GlobalScriptCompileBroadcaster::getExternalScriptFile(const File& fileToInclude)
ExternalScriptFile::Ptr GlobalScriptCompileBroadcaster::getExternalScriptFile(const File& fileToInclude, bool createIfNotFound)
{
for (int i = 0; i < includedFiles.size(); i++)
{
if (includedFiles[i]->getFile() == fileToInclude)
return includedFiles[i];
}

includedFiles.add(new ExternalScriptFile(fileToInclude));
if(createIfNotFound)
return includedFiles.add(new ExternalScriptFile(fileToInclude));

return includedFiles.getLast();
return nullptr;
}

juce::ValueTree GlobalScriptCompileBroadcaster::exportWebViewResources()
Expand Down Expand Up @@ -400,6 +452,7 @@ ExternalScriptFile::RuntimeError::RuntimeError() = default;

ExternalScriptFile::ExternalScriptFile(const File& file):
file(file),
resourceType(ResourceType::FileBased),
currentResult(Result::ok())
{
#if USE_BACKEND
Expand Down
60 changes: 59 additions & 1 deletion hi_core/hi_core/GlobalScriptCompileBroadcaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ class ExternalScriptFile : public ReferenceCountedObject
{
public:

enum class ResourceType
{
EmbeddedInSnippet,
FileBased,
numResourceTypes
};

struct RuntimeError
{
using Broadcaster = LambdaBroadcaster<Array<RuntimeError>*>;
Expand Down Expand Up @@ -102,6 +109,19 @@ class ExternalScriptFile : public ReferenceCountedObject

ExternalScriptFile(const File&file);

ExternalScriptFile(const File& rootDirectory, const ValueTree& v):
resourceType(ResourceType::EmbeddedInSnippet),
file(rootDirectory.getChildFile(v["filename"].toString())),
currentResult(Result::ok())
{

#if USE_BACKEND
content.replaceAllContent(v["content"]);
content.setSavePoint();
content.clearUndoHistory();
#endif
}

~ExternalScriptFile();

void setResult(Result r);
Expand All @@ -112,14 +132,48 @@ class ExternalScriptFile : public ReferenceCountedObject

File getFile() const;

ValueTree toEmbeddableValueTree(const File& rootDirectory) const
{
auto fn = getFile();
auto name = fn.getRelativePathFrom(rootDirectory);

ValueTree c("file");
c.setProperty("filename", name.replaceCharacter('\\', '/'), nullptr);
c.setProperty("content", content.getAllContent(), nullptr);
return c;
}

typedef ReferenceCountedObjectPtr<ExternalScriptFile> Ptr;

void setRuntimeErrors(const Result& r);

RuntimeError::Broadcaster& getRuntimeErrorBroadcaster();

ResourceType getResourceType() const
{
return resourceType;
}

bool extractEmbedded()
{
if(resourceType == ResourceType::EmbeddedInSnippet)
{
if(!file.existsAsFile() || PresetHandler::showYesNoWindow("Overwrite local file", "The file " + getFile().getFileName() + " from the snippet already exists. Do you want to overwrite your local file?"))
{
file.getParentDirectory().createDirectory();
file.replaceWithText(content.getAllContent());
resourceType = ResourceType::FileBased;
return true;
}
}

return false;
}

private:

ResourceType resourceType;

RuntimeError::Broadcaster runtimeErrorBroadcaster;

Array<RuntimeError> runtimeErrors;
Expand Down Expand Up @@ -179,12 +233,16 @@ class GlobalScriptCompileBroadcaster

int getNumExternalScriptFiles() const;

ExternalScriptFile::Ptr getExternalScriptFile(const File& fileToInclude);
ExternalScriptFile::Ptr getExternalScriptFile(const File& fileToInclude, bool createIfNotFound);

ExternalScriptFile::Ptr getExternalScriptFile(int index) const;

void clearIncludedFiles();

void restoreIncludedScriptFilesFromSnippet(const ValueTree& snippetTree);

ValueTree collectIncludedScriptFilesForSnippet(const Identifier& id, const File& root) const;

ScriptComponentEditBroadcaster* getScriptComponentEditBroadcaster();

const ScriptComponentEditBroadcaster* getScriptComponentEditBroadcaster() const;
Expand Down
Loading

0 comments on commit 1093e0c

Please sign in to comment.