From f777036acb07adb0cc0a8e7076f9c0777e86e0cd Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez <aacuelo@teleco.upv.es> Date: Thu, 19 Nov 2015 19:54:47 +0100 Subject: [PATCH] Make possible to save and load processor signal chains --- .../GenericProcessor/GenericProcessor.h | 6 +- .../PlaceholderProcessor.cpp | 6 +- .../PlaceholderProcessor.h | 2 +- .../PlaceholderProcessorEditor.cpp | 8 +- .../Processors/PluginManager/PluginClass.cpp | 88 +++++++++++++++++++ Source/Processors/PluginManager/PluginClass.h | 9 ++ .../PluginManager/PluginManager.cpp | 34 +++++-- .../Processors/PluginManager/PluginManager.h | 5 +- .../ProcessorGraph/ProcessorGraph.cpp | 34 +++++-- .../ProcessorManager/ProcessorManager.cpp | 79 +++++++++++++++-- .../ProcessorManager/ProcessorManager.h | 1 + Source/UI/EditorViewport.cpp | 22 ++++- Source/UI/ProcessorList.cpp | 2 + 13 files changed, 261 insertions(+), 35 deletions(-) diff --git a/Source/Processors/GenericProcessor/GenericProcessor.h b/Source/Processors/GenericProcessor/GenericProcessor.h index 320c568b6..d9aa51173 100755 --- a/Source/Processors/GenericProcessor/GenericProcessor.h +++ b/Source/Processors/GenericProcessor/GenericProcessor.h @@ -36,7 +36,7 @@ enum ChannelType {HEADSTAGE_CHANNEL = 0, AUX_CHANNEL = 1, ADC_CHANNEL = 2, EVENT #include "../Parameter/Parameter.h" #include "../Channel/Channel.h" #include "../../CoreServices.h" -#include "../PluginManager/OpenEphysPlugin.h" +#include "../PluginManager/PluginClass.h" #include <time.h> #include <stdio.h> @@ -66,7 +66,7 @@ class Channel; */ -class PLUGIN_API GenericProcessor : public AudioProcessor +class PLUGIN_API GenericProcessor : public AudioProcessor, public PluginClass { public: @@ -101,7 +101,7 @@ public: virtual AudioProcessorEditor* createEditor(); /** The default is to have no editor.*/ - bool hasEditor() const; + virtual bool hasEditor() const; /** JUCE method. Not used.*/ void reset(); diff --git a/Source/Processors/PlaceholderProcessor/PlaceholderProcessor.cpp b/Source/Processors/PlaceholderProcessor/PlaceholderProcessor.cpp index 88ebc3934..3208a816b 100644 --- a/Source/Processors/PlaceholderProcessor/PlaceholderProcessor.cpp +++ b/Source/Processors/PlaceholderProcessor/PlaceholderProcessor.cpp @@ -43,7 +43,8 @@ bool PlaceholderProcessor::hasEditor() const AudioProcessorEditor* PlaceholderProcessor::createEditor() { - return new PlaceholderProcessorEditor(this, processorName, libName, libVersion); + editor = new PlaceholderProcessorEditor(this, processorName, libName, libVersion); + return editor; } void PlaceholderProcessor::process(AudioSampleBuffer& continuousBuffer, MidiBuffer& eventBuffer) @@ -60,7 +61,8 @@ bool PlaceholderProcessor::isSink() return processorSink; } -bool PlaceholderProcessor::enable() +bool PlaceholderProcessor::isReady() { + CoreServices::sendStatusMessage("Cannot acquire with placeholder nodes"); return false; //This processor never allows processing } \ No newline at end of file diff --git a/Source/Processors/PlaceholderProcessor/PlaceholderProcessor.h b/Source/Processors/PlaceholderProcessor/PlaceholderProcessor.h index 5da989288..ae89b3a71 100644 --- a/Source/Processors/PlaceholderProcessor/PlaceholderProcessor.h +++ b/Source/Processors/PlaceholderProcessor/PlaceholderProcessor.h @@ -39,7 +39,7 @@ public: MidiBuffer& eventBuffer) override; bool isSource() override; bool isSink() override; - bool enable() override; + bool isReady() override; private: const String processorName; const String libName; diff --git a/Source/Processors/PlaceholderProcessor/PlaceholderProcessorEditor.cpp b/Source/Processors/PlaceholderProcessor/PlaceholderProcessorEditor.cpp index 43df12bf1..7cf012f17 100644 --- a/Source/Processors/PlaceholderProcessor/PlaceholderProcessorEditor.cpp +++ b/Source/Processors/PlaceholderProcessor/PlaceholderProcessorEditor.cpp @@ -27,18 +27,18 @@ PlaceholderProcessorEditor::PlaceholderProcessorEditor(GenericProcessor* parentN : GenericEditor(parentNode, true), processorName(pName), libName(lName), libVersion(lVer) { notfoundLabel = new Label("Not found", "Plugin not found"); - notfoundLabel->setBounds(30, 30, 100, 20); + notfoundLabel->setBounds(10, 25, 100, 20); addAndMakeVisible(notfoundLabel); libLabel = new Label("Plugin", libName + " ver. " + String(libVersion)); - libLabel->setBounds(30, 70, 100, 20); + libLabel->setBounds(10, 40, 160, 40); addAndMakeVisible(libLabel); nameLabel = new Label("Processor", "Missing processor: " + processorName); - libLabel->setBounds(30, 110, 100, 20); + nameLabel->setBounds(10, 75, 160, 40); addAndMakeVisible(nameLabel); - desiredWidth = 150; + desiredWidth = 180; setEnabledState(false); } diff --git a/Source/Processors/PluginManager/PluginClass.cpp b/Source/Processors/PluginManager/PluginClass.cpp index f40c0f2e5..1ad338aee 100644 --- a/Source/Processors/PluginManager/PluginClass.cpp +++ b/Source/Processors/PluginManager/PluginClass.cpp @@ -22,3 +22,91 @@ */ #include "PluginClass.h" +#include "PluginManager.h" +#include "../../AccessClass.h" +#include "../ProcessorManager/ProcessorManager.h" + +PluginClass::PluginClass() +{ + libName = String::empty; + pluginName = String::empty; + libVersion = -1; + pluginType = Plugin::NotAPlugin; +} + +PluginClass::~PluginClass() +{ + +} + +void PluginClass::setPluginData(Plugin::PluginType type, int index) +{ + PluginManager* pm = AccessClass::getPluginManager(); + String name; + pluginType = type; + pluginIndex = index; + switch (type) + { + case Plugin::ProcessorPlugin: + { + Plugin::ProcessorInfo i = pm->getProcessorInfo(index); + name = i.name; + } + break; + case Plugin::RecordEnginePlugin: + { + Plugin::RecordEngineInfo i = pm->getRecordEngineInfo(index); + name = i.name; + } + break; + case Plugin::DatathreadPlugin: + { + Plugin::DataThreadInfo i = pm->getDataThreadInfo(index); + name = i.name; + } + break; + case Plugin::FileSourcePlugin: + { + Plugin::FileSourceInfo i = pm->getFileSourceInfo(index); + name = i.name; + } + break; + case Plugin::NotAPlugin: + { + String pName; + int pType; + ProcessorManager::getProcessorNameAndType(BuiltInProcessor, index, pName, pType); + name = pName; + } + default: + return; + } + pluginName = name; + libName = pm->getLibraryName(pm->getLibraryIndexFromPlugin(type, index)); + libVersion = pm->getLibraryVersion(pm->getLibraryIndexFromPlugin(type, index)); +} + +String PluginClass::getLibName() const +{ + return libName; +} + +String PluginClass::getPluginName() const +{ + return pluginName; +} + +int PluginClass::getLibVersion() const +{ + return libVersion; +} + +Plugin::PluginType PluginClass::getPluginType() const +{ + return pluginType; +} + +int PluginClass::getIndex() const +{ + return pluginIndex; +} \ No newline at end of file diff --git a/Source/Processors/PluginManager/PluginClass.h b/Source/Processors/PluginManager/PluginClass.h index 0fb7f84d1..d72bc54de 100644 --- a/Source/Processors/PluginManager/PluginClass.h +++ b/Source/Processors/PluginManager/PluginClass.h @@ -28,11 +28,20 @@ class PluginClass { public: + PluginClass(); + ~PluginClass(); void setPluginData(Plugin::PluginType type, int index); + String getLibName() const; + String getPluginName() const; + int getLibVersion() const; + Plugin::PluginType getPluginType() const; + int getIndex() const; private: String libName; String pluginName; + Plugin::PluginType pluginType; int libVersion; + int pluginIndex; }; diff --git a/Source/Processors/PluginManager/PluginManager.cpp b/Source/Processors/PluginManager/PluginManager.cpp index 2e80659e7..f02d7a029 100644 --- a/Source/Processors/PluginManager/PluginManager.cpp +++ b/Source/Processors/PluginManager/PluginManager.cpp @@ -179,6 +179,7 @@ int PluginManager::loadPlugin(const String& pluginLoc) { LoadedLibInfo lib; lib.apiVersion = libInfo.apiVersion; lib.name = libInfo.name; + lib.libVersion = libInfo.libVersion; lib.numPlugins = libInfo.numPlugins; lib.handle = handle; @@ -197,7 +198,7 @@ int PluginManager::loadPlugin(const String& pluginLoc) { info.creator = pInfo.processor.creator; info.name = pInfo.processor.name; info.type = pInfo.processor.type; - info.libIndex = libArray.size(); + info.libIndex = libArray.size()-1; processorPlugins.add(info); break; } @@ -314,14 +315,37 @@ Plugin::FileSourceInfo PluginManager::getFileSourceInfo(String name, String libN return i; } -String PluginManager::getPluginName(int index) const +String PluginManager::getLibraryName(int index) const +{ + if (index < 0 || index >= libArray.size()) + return String::empty; + else + return libArray[index].name; +} + +int PluginManager::getLibraryVersion(int index) const { - return libArray[index].name; + if (index < 0 || index >= libArray.size()) + return -1; + else + return libArray[index].libVersion; } -int PluginManager::getPluginVersion(int index) const +int PluginManager::getLibraryIndexFromPlugin(Plugin::PluginType type, int index) { - return libArray[index].libVersion; + switch (type) + { + case Plugin::ProcessorPlugin: + return processorPlugins[index].libIndex; + case Plugin::RecordEnginePlugin: + return recordEnginePlugins[index].libIndex; + case Plugin::DatathreadPlugin: + return dataThreadPlugins[index].libIndex; + case Plugin::FileSourcePlugin: + return fileSourcePlugins[index].libIndex; + default: + return -1; + } } Plugin::ProcessorInfo PluginManager::getEmptyProcessorInfo() diff --git a/Source/Processors/PluginManager/PluginManager.h b/Source/Processors/PluginManager/PluginManager.h index fac06d638..ccc50462b 100644 --- a/Source/Processors/PluginManager/PluginManager.h +++ b/Source/Processors/PluginManager/PluginManager.h @@ -74,8 +74,9 @@ public: Plugin::RecordEngineInfo getRecordEngineInfo(String name, String libName = String::empty) const; Plugin::FileSourceInfo getFileSourceInfo(int index) const; Plugin::FileSourceInfo getFileSourceInfo(String name, String libName = String::empty) const; - String getPluginName(int index) const; - int getPluginVersion(int index) const; + String getLibraryName(int index) const; + int getLibraryVersion(int index) const; + int getLibraryIndexFromPlugin(Plugin::PluginType type, int index); private: Array<LoadedLibInfo> libArray; diff --git a/Source/Processors/ProcessorGraph/ProcessorGraph.cpp b/Source/Processors/ProcessorGraph/ProcessorGraph.cpp index b2a27b133..68111e777 100644 --- a/Source/Processors/ProcessorGraph/ProcessorGraph.cpp +++ b/Source/Processors/ProcessorGraph/ProcessorGraph.cpp @@ -470,16 +470,34 @@ void ProcessorGraph::connectProcessorToAudioAndRecordNodes(GenericProcessor* sou GenericProcessor* ProcessorGraph::createProcessorFromDescription(Array<var>& description) { - String processorName = description[0]; - int processorType = description[1]; - int processorIndex = description[2]; - String processorCategory = description[3]; + GenericProcessor* processor = nullptr; - std::cout << "Creating from description..." << std::endl; - std::cout << processorCategory << "::" << processorName << " (" << processorType << "-" << processorIndex << ")" << std::endl; + bool fromProcessorList = description[0]; + String processorName = description[1]; + int processorType = description[2]; + int processorIndex = description[3]; - GenericProcessor* processor = nullptr; - processor = ProcessorManager::createProcessor((ProcessorClasses)processorType, processorIndex); + if (fromProcessorList) + { + String processorCategory = description[4]; + + std::cout << "Creating from description..." << std::endl; + std::cout << processorCategory << "::" << processorName << " (" << processorType << "-" << processorIndex << ")" << std::endl; + + processor = ProcessorManager::createProcessor((ProcessorClasses)processorType, processorIndex); + } + else + { + String libName = description[4]; + int libVersion = description[5]; + bool isSource = description[6]; + bool isSink = description[7]; + + std::cout << "Creating from plugin info..." << std::endl; + std::cout << libName << "(" << libVersion << ")::" << processorName << std::endl; + + processor = ProcessorManager::createProcessorFromPluginInfo((Plugin::PluginType)processorType, processorIndex, processorName, libName, libVersion, isSource, isSink); + } String msg = "New " + processorName + " created"; CoreServices::sendStatusMessage(msg); diff --git a/Source/Processors/ProcessorManager/ProcessorManager.cpp b/Source/Processors/ProcessorManager/ProcessorManager.cpp index d83479477..9ec180260 100644 --- a/Source/Processors/ProcessorManager/ProcessorManager.cpp +++ b/Source/Processors/ProcessorManager/ProcessorManager.cpp @@ -33,6 +33,8 @@ #include "../Splitter/Splitter.h" #include "../DataThreads/RhythmNode/RHD2000Thread.h" +#include "../PlaceholderProcessor/PlaceholderProcessor.h" + /** Total number of builtin processors **/ #define BUILTIN_PROCESSORS 4 @@ -44,6 +46,10 @@ namespace ProcessorManager { switch (index) { + case -1: + name = "Placeholder processor"; + type = UtilityProcessor; + break; case 0: name = "Rhythm FPGA"; type = SourceProcessor; @@ -70,24 +76,29 @@ namespace ProcessorManager /** Built-in constructors **/ GenericProcessor* createBuiltInProcessor(int index) { + GenericProcessor* proc; switch (index) { + case -1: + proc = new PlaceholderProcessor("Empty placeholder", "Undefined", 0, false, false); + break; case 0: - return new SourceNode("Rhythm FPGA", &RHD2000Thread::createDataThread); + proc = new SourceNode("Rhythm FPGA", &RHD2000Thread::createDataThread); break; case 1: - return new Merger(); + proc = new Merger(); break; case 2: - return new Splitter(); + proc = new Splitter(); break; case 3: - return new FileReader(); + proc = new FileReader(); break; default: return nullptr; - break; } + proc->setPluginData(Plugin::NotAPlugin, index); + return proc; } int getNumProcessors(ProcessorClasses pClass) @@ -146,13 +157,17 @@ namespace ProcessorManager case PluginProcessor: { Plugin::ProcessorInfo info = AccessClass::getPluginManager()->getProcessorInfo(index); - return info.creator(); + GenericProcessor* proc = info.creator(); + proc->setPluginData(Plugin::ProcessorPlugin, index); + return proc; break; } case DataThreadProcessor: { Plugin::DataThreadInfo info = AccessClass::getPluginManager()->getDataThreadInfo(index); - return new SourceNode(info.name, info.creator); + GenericProcessor* proc = new SourceNode(info.name, info.creator); + proc->setPluginData(Plugin::DatathreadPlugin, index); + return proc; break; } @@ -160,4 +175,54 @@ namespace ProcessorManager return nullptr; } } + + GenericProcessor* createProcessorFromPluginInfo(Plugin::PluginType type, int index, String procName, String libName, int libVersion, bool source, bool sink) + { + PluginManager* pm = AccessClass::getPluginManager(); + GenericProcessor* proc = nullptr; + if (index > -1) + { + if (type == Plugin::NotAPlugin) + { + return createBuiltInProcessor(index); + } + else if (type == Plugin::ProcessorPlugin) + { + for (int i = 0; i < pm->getNumProcessors(); i++) + { + Plugin::ProcessorInfo info = pm->getProcessorInfo(i); + if (procName.equalsIgnoreCase(info.name)) + { + int libIndex = pm->getLibraryIndexFromPlugin(Plugin::ProcessorPlugin, i); + if (libName.equalsIgnoreCase(pm->getLibraryName(libIndex)) && libVersion == pm->getLibraryVersion(libIndex)) + { + proc = info.creator(); + proc->setPluginData(Plugin::ProcessorPlugin, i); + return proc; + } + } + } + } + else if (type == Plugin::DatathreadPlugin) + { + for (int i = 0; i < pm->getNumDataThreads(); i++) + { + Plugin::DataThreadInfo info = pm->getDataThreadInfo(i); + if (procName.equalsIgnoreCase(info.name)) + { + int libIndex = pm->getLibraryIndexFromPlugin(Plugin::DatathreadPlugin, i); + if (libName.equalsIgnoreCase(pm->getLibraryName(libIndex)) && libVersion == pm->getLibraryVersion(libIndex)) + { + proc = new SourceNode(info.name, info.creator); + proc->setPluginData(Plugin::DatathreadPlugin, i); + return proc; + } + } + } + } + } + proc = new PlaceholderProcessor(procName, libName, libVersion, source, sink); + proc->setPluginData(Plugin::NotAPlugin, -1); + return proc; + } }; \ No newline at end of file diff --git a/Source/Processors/ProcessorManager/ProcessorManager.h b/Source/Processors/ProcessorManager/ProcessorManager.h index 9f1c1bcba..d643bdbf7 100644 --- a/Source/Processors/ProcessorManager/ProcessorManager.h +++ b/Source/Processors/ProcessorManager/ProcessorManager.h @@ -38,6 +38,7 @@ namespace ProcessorManager int getNumProcessors(ProcessorClasses pClass); void getProcessorNameAndType(ProcessorClasses pClass, int index, String& name, int& type); GenericProcessor* createProcessor(ProcessorClasses pClass, int index); + GenericProcessor* createProcessorFromPluginInfo(Plugin::PluginType type, int index, String procName, String libName, int libVersion, bool source = false, bool sink = false); }; diff --git a/Source/UI/EditorViewport.cpp b/Source/UI/EditorViewport.cpp index fc837d4d5..1f69f9ec9 100755 --- a/Source/UI/EditorViewport.cpp +++ b/Source/UI/EditorViewport.cpp @@ -239,7 +239,7 @@ void EditorViewport::itemDropped(const SourceDetails& dragSourceDetails) if (canEdit) { - message = "last filter dropped: " + (*description)[0].toString(); + message = "last filter dropped: " + (*description)[1].toString(); std::cout << "Item dropped at insertion point " << insertionPoint << std::endl; @@ -1195,6 +1195,13 @@ XmlElement* EditorViewport::createNodeXml(GenericEditor* editor, e->setAttribute("name", name); e->setAttribute("insertionPoint", insertionPt); + e->setAttribute("pluginName", source->getPluginName()); + e->setAttribute("pluginType", (int)(source->getPluginType())); + e->setAttribute("pluginIndex", source->getIndex()); + e->setAttribute("libraryName", source->getLibName()); + e->setAttribute("libraryVersion", source->getLibVersion()); + e->setAttribute("isSource", source->isSource()); + e->setAttribute("isSink", source->isSink()); /**Saves individual processor parameters to XML */ std::cout << "Create subnodes with parameters" << std::endl; @@ -1510,8 +1517,17 @@ const String EditorViewport::loadState(File fileToLoad) insertionPoint = 0; } - //Point<int> pt = - SourceDetails sd = SourceDetails(processor->getStringAttribute("name"), + //See ProcessorGraph::createProcessorFromDescription for description info + Array<var> procDesc; + procDesc.add(false); + procDesc.add(processor->getStringAttribute("pluginName")); + procDesc.add(processor->getIntAttribute("pluginType")); + procDesc.add(processor->getIntAttribute("pluginIndex")); + procDesc.add(processor->getStringAttribute("libraryName")); + procDesc.add(processor->getIntAttribute("libraryVersion")); + procDesc.add(processor->getBoolAttribute("isSource")); + procDesc.add(processor->getBoolAttribute("isSink")); + SourceDetails sd = SourceDetails(procDesc, 0, Point<int>(0,0)); diff --git a/Source/UI/ProcessorList.cpp b/Source/UI/ProcessorList.cpp index 6df56c58d..f0089cfeb 100755 --- a/Source/UI/ProcessorList.cpp +++ b/Source/UI/ProcessorList.cpp @@ -490,7 +490,9 @@ void ProcessorList::mouseDrag(const MouseEvent& e) Point<int> imageOffset(20,10); + //See ProcessorGraph::createProcesorFromDescription for description info Array<var> dragData; + dragData.add(true); dragData.add(dragDescription); dragData.add(listItem->processorType); dragData.add(listItem->processorId); -- GitLab